diff --git a/src/models/Categories.model.ts b/src/models/Categories.model.ts index 058406d2..c6a51ede 100644 --- a/src/models/Categories.model.ts +++ b/src/models/Categories.model.ts @@ -1,4 +1,3 @@ -import { Transaction } from 'sequelize/types'; import { CATEGORY_TYPES } from 'shared-types'; import { Table, Column, Model, ForeignKey, DataType, BelongsToMany } from 'sequelize-typescript'; import Users from './Users.model'; @@ -102,10 +101,7 @@ export interface EditCategoryPayload { color?: string; } -export const editCategory = async ( - { userId, categoryId, ...params }: EditCategoryPayload, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const editCategory = async ({ userId, categoryId, ...params }: EditCategoryPayload) => { const existingCategory = await Categories.findByPk(categoryId); if (!existingCategory) { throw new NotFoundError({ message: 'Category with provided id does not exist!' }); @@ -116,7 +112,6 @@ export const editCategory = async ( userId, }, returning: true, - transaction, }); return categories; @@ -127,13 +122,9 @@ export interface DeleteCategoryPayload { categoryId: number; } -export const deleteCategory = async ( - { userId, categoryId }: DeleteCategoryPayload, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const deleteCategory = async ({ userId, categoryId }: DeleteCategoryPayload) => { return Categories.destroy({ where: { userId, id: categoryId }, - transaction, }); }; diff --git a/src/models/Currencies.model.ts b/src/models/Currencies.model.ts index 0d270d8d..df558a3a 100644 --- a/src/models/Currencies.model.ts +++ b/src/models/Currencies.model.ts @@ -1,5 +1,4 @@ import cc from 'currency-codes'; -import { Transaction } from 'sequelize/types'; import { Op } from 'sequelize'; import { Table, @@ -85,20 +84,17 @@ export async function getCurrency({ }); } -export async function getCurrencies( - { - ids, - currencies, - numbers, - codes, - }: { - ids?: number[]; - numbers?: number[]; - currencies?: string[]; - codes?: string[]; - }, - { transaction }: { transaction?: Transaction } = {}, -) { +export async function getCurrencies({ + ids, + currencies, + numbers, + codes, +}: { + ids?: number[]; + numbers?: number[]; + currencies?: string[]; + codes?: string[]; +}) { if ( ids === undefined && currencies === undefined && @@ -118,7 +114,7 @@ export async function getCurrencies( if (codes) where.code = { [Op.in]: codes }; if (numbers) where.number = { [Op.in]: numbers }; - return Currencies.findAll({ where, transaction }); + return Currencies.findAll({ where }); } export const createCurrency = async ({ code }) => { diff --git a/src/models/RefundTransactions.model.ts b/src/models/RefundTransactions.model.ts index 676c95f9..9f8195be 100644 --- a/src/models/RefundTransactions.model.ts +++ b/src/models/RefundTransactions.model.ts @@ -1,4 +1,3 @@ -import { Transaction } from 'sequelize/types'; import { Table, Column, Model, ForeignKey, BelongsTo, DataType } from 'sequelize-typescript'; import Transactions from './Transactions.model'; import Users from './Users.model'; @@ -60,42 +59,42 @@ export default class RefundTransactions extends Model { refundTransaction: Transactions; } -export const createRefundTransaction = async ( - { - userId, - originalTxId, - refundTxId, - }: { userId: number; originalTxId: number | null; refundTxId: number }, - { transaction }: { transaction?: Transaction } = {}, -) => { - return RefundTransactions.create({ userId, originalTxId, refundTxId }, { transaction }); +export const createRefundTransaction = async ({ + userId, + originalTxId, + refundTxId, +}: { + userId: number; + originalTxId: number | null; + refundTxId: number; +}) => { + return RefundTransactions.create({ userId, originalTxId, refundTxId }); }; -export const getRefundsForTransaction = async ( - { originalTxId, userId }: { originalTxId: number; userId: number }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const getRefundsForTransaction = async ({ + originalTxId, + userId, +}: { + originalTxId: number; + userId: number; +}) => { return RefundTransactions.findAll({ where: { originalTxId: originalTxId, userId }, include: [{ model: Transactions, as: 'refundTransaction' }], - transaction, }); }; export const bulkCreateRefundTransactions = ( { data }: { data: Array<{ userId: number; originalTxId: number | null; refundTxId: number }> }, { - transaction, validate = true, returning = false, }: { - transaction: Transaction; validate?: boolean; returning?: boolean; }, ) => { return RefundTransactions.bulkCreate(data, { - transaction, validate, returning, }); diff --git a/src/models/Transactions.model.ts b/src/models/Transactions.model.ts index b2c94617..1a7cba1d 100644 --- a/src/models/Transactions.model.ts +++ b/src/models/Transactions.model.ts @@ -7,7 +7,6 @@ import { TransactionModel, } from 'shared-types'; import { Op } from 'sequelize'; -import { Transaction } from 'sequelize/types'; import { Table, BeforeCreate, @@ -330,42 +329,39 @@ export default class Transactions extends Model { } } -export const getTransactions = async ( - { - from = 0, - limit = 20, - accountType, - accountId, - userId, - sortDirection = SORT_DIRECTIONS.desc, - includeUser, - includeAccount, - transactionType, - includeCategory, - includeAll, - nestedInclude, - isRaw = false, - excludeTransfer, - excludeRefunds, - }: { - from: number; - limit: number; - accountType: ACCOUNT_TYPES; - transactionType: string; - accountId: number; - userId: number; - sortDirection: SORT_DIRECTIONS; - includeUser: boolean; - includeAccount: boolean; - includeCategory: boolean; - includeAll: boolean; - nestedInclude: boolean; - isRaw: boolean; - excludeTransfer?: boolean; - excludeRefunds?: boolean; - }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const getTransactions = async ({ + from = 0, + limit = 20, + accountType, + accountId, + userId, + sortDirection = SORT_DIRECTIONS.desc, + includeUser, + includeAccount, + transactionType, + includeCategory, + includeAll, + nestedInclude, + isRaw = false, + excludeTransfer, + excludeRefunds, +}: { + from: number; + limit: number; + accountType: ACCOUNT_TYPES; + transactionType: string; + accountId: number; + userId: number; + sortDirection: SORT_DIRECTIONS; + includeUser: boolean; + includeAccount: boolean; + includeCategory: boolean; + includeAll: boolean; + nestedInclude: boolean; + isRaw: boolean; + excludeTransfer?: boolean; + excludeRefunds?: boolean; +}) => { const include = prepareTXInclude({ includeUser, includeAccount, @@ -386,7 +382,6 @@ export const getTransactions = async ( refundLinked: excludeRefunds ? false : undefined, }), }, - transaction, offset: from, limit: limit, order: [['time', sortDirection]], @@ -416,26 +411,23 @@ export const getTransactionBySomeId = ({ }); }; -export const getTransactionById = ( - { - id, - userId, - includeUser, - includeAccount, - includeCategory, - includeAll, - nestedInclude, - }: { - id: number; - userId: number; - includeUser?: boolean; - includeAccount?: boolean; - includeCategory?: boolean; - includeAll?: boolean; - nestedInclude?: boolean; - }, - { transaction }: { transaction?: Transaction } = {}, -): Promise => { +export const getTransactionById = ({ + id, + userId, + includeUser, + includeAccount, + includeCategory, + includeAll, + nestedInclude, +}: { + id: number; + userId: number; + includeUser?: boolean; + includeAccount?: boolean; + includeCategory?: boolean; + includeAll?: boolean; + nestedInclude?: boolean; +}): Promise => { const include = prepareTXInclude({ includeUser, includeAccount, @@ -447,30 +439,26 @@ export const getTransactionById = ( return Transactions.findOne({ where: { id, userId }, include, - transaction, }); }; -export const getTransactionsByTransferId = ( - { - transferId, - userId, - includeUser, - includeAccount, - includeCategory, - includeAll, - nestedInclude, - }: { - transferId: number; - userId: number; - includeUser?: boolean; - includeAccount?: boolean; - includeCategory?: boolean; - includeAll?: boolean; - nestedInclude?: boolean; - }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const getTransactionsByTransferId = ({ + transferId, + userId, + includeUser, + includeAccount, + includeCategory, + includeAll, + nestedInclude, +}: { + transferId: number; + userId: number; + includeUser?: boolean; + includeAccount?: boolean; + includeCategory?: boolean; + includeAll?: boolean; + nestedInclude?: boolean; +}) => { const include = prepareTXInclude({ includeUser, includeAccount, @@ -482,32 +470,28 @@ export const getTransactionsByTransferId = ( return Transactions.findAll({ where: { transferId, userId }, include, - transaction, }); }; -export const getTransactionsByArrayOfField = async ( - { - fieldValues, - fieldName, - userId, - includeUser, - includeAccount, - includeCategory, - includeAll, - nestedInclude, - }: { - fieldValues: TransactionModel[T][]; - fieldName: T; - userId: number; - includeUser?: boolean; - includeAccount?: boolean; - includeCategory?: boolean; - includeAll?: boolean; - nestedInclude?: boolean; - }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const getTransactionsByArrayOfField = async ({ + fieldValues, + fieldName, + userId, + includeUser, + includeAccount, + includeCategory, + includeAll, + nestedInclude, +}: { + fieldValues: TransactionModel[T][]; + fieldName: T; + userId: number; + includeUser?: boolean; + includeAccount?: boolean; + includeCategory?: boolean; + includeAll?: boolean; + nestedInclude?: boolean; +}) => { const include = prepareTXInclude({ includeUser, includeAccount, @@ -524,7 +508,6 @@ export const getTransactionsByArrayOfField = async { - const response = await Transactions.create({ userId, ...rest }, { transaction }); +export const createTransaction = async ({ userId, ...rest }: CreateTransactionPayload) => { + const response = await Transactions.create({ userId, ...rest }); - return getTransactionById( - { - id: response.get('id'), - userId, - }, - { transaction }, - ); + return getTransactionById({ + id: response.get('id'), + userId, + }); }; export interface UpdateTransactionByIdParams { @@ -598,21 +575,19 @@ export interface UpdateTransactionByIdParams { export const updateTransactionById = async ( { id, userId, ...payload }: UpdateTransactionByIdParams, { - transaction, // For refunds we need to have an option to disable them. Otherwise there will be some kind of // deadlock - request stucks forever with no error message. TODO: consider removing this logic at all individualHooks = true, - }: { transaction?: Transaction; individualHooks?: boolean } = {}, + }: { individualHooks?: boolean } = {}, ) => { const where = { id, userId }; await Transactions.update(removeUndefinedKeys(payload), { where, - transaction, individualHooks, }); - return getTransactionById({ id, userId }, { transaction }); + return getTransactionById({ id, userId }); }; export const updateTransactions = ( @@ -631,24 +606,19 @@ export const updateTransactions = ( }, where: Record & { userId: number }, { - transaction, // For refunds we need to have an option to disable them. Otherwise there will be some kind of // deadlock - request stucks forever with no error message. TODO: consider removing this logic at all individualHooks = true, - }: { transaction?: Transaction; individualHooks?: boolean } = {}, + }: { individualHooks?: boolean } = {}, ) => { return Transactions.update(removeUndefinedKeys(payload), { where, - transaction, individualHooks, }); }; -export const deleteTransactionById = async ( - { id, userId }: { id: number; userId: number }, - { transaction }: { transaction?: Transaction } = {}, -) => { - const tx = await getTransactionById({ id, userId }, { transaction }); +export const deleteTransactionById = async ({ id, userId }: { id: number; userId: number }) => { + const tx = await getTransactionById({ id, userId }); if (tx.accountType !== ACCOUNT_TYPES.system) { throw new ValidationError({ @@ -658,7 +628,6 @@ export const deleteTransactionById = async ( return Transactions.destroy({ where: { id, userId }, - transaction, // So that BeforeDestroy will be triggered individualHooks: true, }); diff --git a/src/models/UsersCurrencies.model.ts b/src/models/UsersCurrencies.model.ts index 67ad1f78..4b680eae 100644 --- a/src/models/UsersCurrencies.model.ts +++ b/src/models/UsersCurrencies.model.ts @@ -1,4 +1,3 @@ -import { Transaction } from 'sequelize/types'; import { Op } from 'sequelize'; import { Table, Column, Model, ForeignKey, BelongsTo } from 'sequelize-typescript'; import { UserCurrencyModel } from 'shared-types'; @@ -56,27 +55,19 @@ export default class UsersCurrencies extends Model { isDefaultCurrency: boolean; } -export const getCurrencies = ( - { userId }: { userId: number }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const getCurrencies = ({ userId }: { userId: number }) => { return UsersCurrencies.findAll({ where: { userId }, include: { model: Currencies, }, - transaction, }); }; -export const getBaseCurrency = async ( - { userId }: { userId: number }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const getBaseCurrency = async ({ userId }: { userId: number }) => { const data = (await UsersCurrencies.findOne({ where: { userId, isDefaultCurrency: true }, include: { model: Currencies }, - transaction, })) as UsersCurrencies & { currency: Currencies }; return data; @@ -115,22 +106,19 @@ export const getCurrency: getCurrencyOverload = ({ }) as Promise; }; -export const addCurrency = ( - { - userId, - currencyId, - exchangeRate, - liveRateUpdate, - isDefaultCurrency, - }: { - userId: number; - currencyId: number; - exchangeRate?: number; - liveRateUpdate?: boolean; - isDefaultCurrency?: boolean; - }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const addCurrency = ({ + userId, + currencyId, + exchangeRate, + liveRateUpdate, + isDefaultCurrency, +}: { + userId: number; + currencyId: number; + exchangeRate?: number; + liveRateUpdate?: boolean; + isDefaultCurrency?: boolean; +}) => { return UsersCurrencies.create( { userId, @@ -141,27 +129,23 @@ export const addCurrency = ( }, { returning: true, - transaction, }, ); }; -export const updateCurrency = async ( - { - userId, - currencyId, - exchangeRate, - liveRateUpdate, - isDefaultCurrency, - }: { - userId: number; - currencyId: number; - exchangeRate?: number; - liveRateUpdate?: boolean; - isDefaultCurrency?: boolean; - }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const updateCurrency = async ({ + userId, + currencyId, + exchangeRate, + liveRateUpdate, + isDefaultCurrency, +}: { + userId: number; + currencyId: number; + exchangeRate?: number; + liveRateUpdate?: boolean; + isDefaultCurrency?: boolean; +}) => { const where = { userId, currencyId }; await UsersCurrencies.update( @@ -172,7 +156,6 @@ export const updateCurrency = async ( }, { where, - transaction, }, ); @@ -181,40 +164,33 @@ export const updateCurrency = async ( return currency; }; -export const deleteCurrency = async ( - { - userId, - currencyId, - }: { - userId: number; - currencyId: number; - }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const deleteCurrency = async ({ + userId, + currencyId, +}: { + userId: number; + currencyId: number; +}) => { const where = { userId, currencyId }; return UsersCurrencies.destroy({ where, - transaction, }); }; -export const updateCurrencies = async ( - { - userId, - currencyIds, - exchangeRate, - liveRateUpdate, - isDefaultCurrency, - }: { - userId: number; - currencyIds?: number[]; - exchangeRate?: number; - liveRateUpdate?: boolean; - isDefaultCurrency?: boolean; - }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const updateCurrencies = async ({ + userId, + currencyIds, + exchangeRate, + liveRateUpdate, + isDefaultCurrency, +}: { + userId: number; + currencyIds?: number[]; + exchangeRate?: number; + liveRateUpdate?: boolean; + isDefaultCurrency?: boolean; +}) => { const where: { userId: number; currencyId?: { [Op.in]: number[] }; @@ -234,12 +210,10 @@ export const updateCurrencies = async ( }, { where, - transaction, }, ); return UsersCurrencies.findAll({ where, - transaction, }); }; diff --git a/src/services/accounts.service.ts b/src/services/accounts.service.ts index 022b7e75..dd19626d 100644 --- a/src/services/accounts.service.ts +++ b/src/services/accounts.service.ts @@ -268,7 +268,6 @@ const defineCorrectAmountFromTxType = (amount: number, transactionType: TRANSACT // refAmount, // currencyId, // }: updateAccountBalanceRequiredFields & { amount: number; refAmount: number }, -// { transaction }: { transaction?: Transaction }, // ): Promise; // /** For **DELETED** transactions. When only (prevAmount + prefRefAmount) passed */ diff --git a/src/services/transactions/create-transaction.ts b/src/services/transactions/create-transaction.ts index edff8f76..8f0af477 100644 --- a/src/services/transactions/create-transaction.ts +++ b/src/services/transactions/create-transaction.ts @@ -1,7 +1,6 @@ import { ACCOUNT_TYPES, TRANSACTION_TYPES, TRANSACTION_TRANSFER_NATURE } from 'shared-types'; import { v4 as uuidv4 } from 'uuid'; -import { Transaction } from 'sequelize/types'; import { logger } from '@js/utils/logger'; import { UnwrapPromise } from '@common/types'; import { ValidationError } from '@js/errors'; @@ -37,24 +36,21 @@ type CreateOppositeTransactionParams = [ * touch source tx, and calculate refAmount for opposite tx * */ -export const calcTransferTransactionRefAmount = async ( - { - userId, - baseTransaction, - destinationAmount, - oppositeTxCurrencyCode, - baseCurrency, - }: { - userId: number; - baseTransaction: Transactions.default; - destinationAmount: number; - oppositeTxCurrencyCode: string; - baseCurrency?: UnwrapPromise>; - }, - { transaction }: { transaction?: Transaction } = {}, -) => { +export const calcTransferTransactionRefAmount = async ({ + userId, + baseTransaction, + destinationAmount, + oppositeTxCurrencyCode, + baseCurrency, +}: { + userId: number; + baseTransaction: Transactions.default; + destinationAmount: number; + oppositeTxCurrencyCode: string; + baseCurrency?: UnwrapPromise>; +}) => { if (!baseCurrency) { - baseCurrency = await UsersCurrencies.getBaseCurrency({ userId }, { transaction }); + baseCurrency = await UsersCurrencies.getBaseCurrency({ userId }); } const isSourceRef = baseTransaction.currencyCode === baseCurrency.currency.code; @@ -65,14 +61,11 @@ export const calcTransferTransactionRefAmount = async ( if (isSourceRef && !isOppositeRef) { oppositeRefAmount = baseTransaction.refAmount; } else if (!isSourceRef && isOppositeRef) { - baseTransaction = await Transactions.updateTransactionById( - { - id: baseTransaction.id, - userId, - refAmount: destinationAmount, - }, - { transaction }, - ); + baseTransaction = await Transactions.updateTransactionById({ + id: baseTransaction.id, + userId, + refAmount: destinationAmount, + }); oppositeRefAmount = destinationAmount; } else if (isSourceRef && isOppositeRef) { oppositeRefAmount = baseTransaction.refAmount; diff --git a/src/services/user-exchange-rate/get-user-exchange-rates.service.ts b/src/services/user-exchange-rate/get-user-exchange-rates.service.ts index 4d4c6c3b..b0dec914 100644 --- a/src/services/user-exchange-rate/get-user-exchange-rates.service.ts +++ b/src/services/user-exchange-rate/get-user-exchange-rates.service.ts @@ -1,9 +1,7 @@ -import { Transaction } from 'sequelize/types'; -import { connection } from '@models/index'; - import * as UsersCurrencies from '@models/UsersCurrencies.model'; import { getExchangeRate } from './get-exchange-rate.service'; +import { withTransaction } from '../common'; /** * By default we just return system exchange rates from ExchangeRates table. @@ -12,38 +10,19 @@ import { getExchangeRate } from './get-exchange-rate.service'; * back, we need to remove his custom record from UserExchangeRates table */ -export async function getUserExchangeRates( - { userId }: { userId: number }, - { transaction }: { transaction?: Transaction } = {}, -) { - const isTxPassedFromAbove = transaction !== undefined; - - transaction = transaction ?? (await connection.sequelize.transaction()); - - try { - const userBaseCurrency = await UsersCurrencies.getBaseCurrency({ userId }, { transaction }); - const userCurrencies = await UsersCurrencies.getCurrencies({ userId }, { transaction }); - - const exchangeRates = await Promise.all( - userCurrencies.map((item) => - getExchangeRate({ - userId, - baseId: item.currencyId, - quoteId: userBaseCurrency.currencyId, - }), - ), - ); - - if (!isTxPassedFromAbove) { - await transaction.commit(); - } - - return exchangeRates; - } catch (err) { - if (!isTxPassedFromAbove) { - await transaction.rollback(); - } - - throw new err(); - } -} +export const getUserExchangeRates = withTransaction(async ({ userId }: { userId: number }) => { + const userBaseCurrency = await UsersCurrencies.getBaseCurrency({ userId }); + const userCurrencies = await UsersCurrencies.getCurrencies({ userId }); + + const exchangeRates = await Promise.all( + userCurrencies.map((item) => + getExchangeRate({ + userId, + baseId: item.currencyId, + quoteId: userBaseCurrency.currencyId, + }), + ), + ); + + return exchangeRates; +});