From d39d0b9e724bc057c6842b53c6cab70f86ec18d2 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 22 May 2024 15:47:48 +0300 Subject: [PATCH 1/6] Add ability to return exactUsdValue and _id for movements --- workers/loc.api/sync/movements/index.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/workers/loc.api/sync/movements/index.js b/workers/loc.api/sync/movements/index.js index 1576d5b11..52b575a03 100644 --- a/workers/loc.api/sync/movements/index.js +++ b/workers/loc.api/sync/movements/index.js @@ -97,7 +97,8 @@ class Movements { end, sort: ledgersOrder, isWithdrawals, - isDeposits + isDeposits, + isExcludePrivate }) const [ @@ -182,7 +183,9 @@ class Movements { currency, amount, amountUsd, - subUserId + subUserId, + _id, + exactUsdValue } = ledger return { @@ -199,7 +202,9 @@ class Movements { transactionId: '', note: '', subUserId, - _isFromLedgers: true + isLedgers: true, + _id, + exactUsdValue } }) } From 4a06bed13f50cee67cf263f7f0a096f73a36585d Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 22 May 2024 16:27:11 +0300 Subject: [PATCH 2/6] Add helper to remap movements --- .../helpers/remap-movements.js | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js diff --git a/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js b/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js new file mode 100644 index 000000000..65ad54cc8 --- /dev/null +++ b/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js @@ -0,0 +1,66 @@ +'use strict' + +const { + isForexSymb +} = require('../../helpers') + +module.exports = (movements, params) => { + const { + remappedTrxs, + remappedTrxsForConvToUsd + } = params + + for (const movement of movements) { + if ( + !movement?.currency || + isForexSymb(movement.currency) || + !Number.isFinite(movement?.amount) || + movement.amount === 0 || + !Number.isFinite(movement?.mtsUpdated) + ) { + continue + } + + const firstSymb = movement.currency + const lastSymb = 'USD' + const symbSeparator = firstSymb.length > 3 + ? ':' + : '' + + const remappedMovement = { + // NOTE: it means entries are not taken form trades table + isAdditionalTrxMovements: true, + // NOTE: movements can have sub-account transfer entries from ledgers table + isMovements: !movement.isLedgers, + symbol: `t${firstSymb}${symbSeparator}${lastSymb}`, + mtsCreate: movement.mtsUpdated, + firstSymb, + lastSymb, + firstSymbPrice: null, + lastSymbPrice: 1, + execAmount: movement.amount, + // NOTE: execPrice = firstSymbPrice and should be set when converting currencies + execPrice: 0, + // NOTE: exactUsdValue can be null on the first launch, for warm-up it's filling from pub-trades + exactUsdValue: movement.exactUsdValue + } + + remappedTrxs.push(remappedMovement) + + if ( + Number.isFinite(movement.exactUsdValue) && + movement.exactUsdValue > 0 + ) { + const price = movement.exactUsdValue / movement.amount + + remappedMovement.firstSymbPrice = price + remappedMovement.execPrice = price + + continue + } + + remappedTrxsForConvToUsd.push(remappedMovement) + } + + return params +} From 3ee7a6dc4efae7fa91ee68c62c16a545953879b7 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 22 May 2024 16:27:33 +0300 Subject: [PATCH 3/6] Add helper to remap trades --- .../helpers/remap-trades.js | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js diff --git a/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js b/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js new file mode 100644 index 000000000..bb5a5098e --- /dev/null +++ b/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js @@ -0,0 +1,53 @@ +'use strict' + +const splitSymbolPairs = require( + 'bfx-report/workers/loc.api/helpers/split-symbol-pairs' +) + +module.exports = (trades, params) => { + const { + remappedTrxs, + remappedTrxsForConvToUsd + } = params + + for (const trade of trades) { + if ( + !trade?.symbol || + !Number.isFinite(trade?.execAmount) || + trade.execAmount === 0 || + !Number.isFinite(trade?.execPrice) || + trade.execPrice === 0 || + !Number.isFinite(trade?.mtsCreate) + ) { + continue + } + + const [firstSymb, lastSymb] = splitSymbolPairs(trade.symbol) + trade.firstSymb = firstSymb + trade.lastSymb = lastSymb + trade.firstSymbPrice = null + trade.lastSymbPrice = null + + remappedTrxs.push(trade) + + if (lastSymb === 'USD') { + trade.firstSymbPrice = trade.execPrice + trade.lastSymbPrice = 1 + + continue + } + if ( + Number.isFinite(trade.exactUsdValue) && + trade.exactUsdValue > 0 + ) { + trade.firstSymbPrice = trade.exactUsdValue / trade.execAmount + trade.lastSymbPrice = trade.exactUsdValue / trade.execPrice + + continue + } + + remappedTrxsForConvToUsd.push(trade) + } + + return params +} From ce8942228967342f92a512360f948bd515bf5086 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 22 May 2024 16:28:34 +0300 Subject: [PATCH 4/6] Add ability to fetch transactions --- .../transaction.tax.report/helpers/index.js | 6 +- .../sync/transaction.tax.report/index.js | 117 +++++++++++++++++- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/workers/loc.api/sync/transaction.tax.report/helpers/index.js b/workers/loc.api/sync/transaction.tax.report/helpers/index.js index 71c804c7b..7761b3c11 100644 --- a/workers/loc.api/sync/transaction.tax.report/helpers/index.js +++ b/workers/loc.api/sync/transaction.tax.report/helpers/index.js @@ -1,7 +1,11 @@ 'use strict' const TRX_TAX_STRATEGIES = require('./trx.tax.strategies') +const remapTrades = require('./remap-trades') +const remapMovements = require('./remap-movements') module.exports = { - TRX_TAX_STRATEGIES + TRX_TAX_STRATEGIES, + remapTrades, + remapMovements } diff --git a/workers/loc.api/sync/transaction.tax.report/index.js b/workers/loc.api/sync/transaction.tax.report/index.js index 497472f93..93ddde252 100644 --- a/workers/loc.api/sync/transaction.tax.report/index.js +++ b/workers/loc.api/sync/transaction.tax.report/index.js @@ -1,7 +1,9 @@ 'use strict' const { - TRX_TAX_STRATEGIES + TRX_TAX_STRATEGIES, + remapTrades, + remapMovements } = require('./helpers') const { decorateInjectable } = require('../../di/utils') @@ -74,9 +76,122 @@ class TransactionTaxReport { const isFIFO = strategy === TRX_TAX_STRATEGIES.FIFO const isLIFO = strategy === TRX_TAX_STRATEGIES.LIFO + const { + trxs: trxsForCurrPeriod, + trxsForConvToUsd + } = await this.#getTrxs({ + user, + start, + end + }) + + if ( + !Array.isArray(trxsForCurrPeriod) || + trxsForCurrPeriod.length === 0 + ) { + return [] + } + + const { + trxs: trxsForPrevPeriod + } = start > 0 + ? await this.#getTrxs({ + user, + start: 0, + end: start - 1 + }) + : { trxs: [] } + // TODO: return [] } + + async #getTrxs (params) { + const { + user, + start, + end + } = params ?? {} + + const tradesPromise = this.#getTrades(params) + const withdrawalsPromise = this.movements.getMovements({ + auth: user, + start, + end, + isWithdrawals: true, + isExcludePrivate: false + }) + const depositsPromise = this.movements.getMovements({ + auth: user, + start, + end, + isDeposits: true, + isExcludePrivate: false + }) + + const [ + trades, + withdrawals, + deposits + ] = await Promise.all([ + tradesPromise, + withdrawalsPromise, + depositsPromise + ]) + + const movements = [...withdrawals, ...deposits] + const remappedTrxs = [] + const remappedTrxsForConvToUsd = [] + + remapTrades( + trades, + { remappedTrxs, remappedTrxsForConvToUsd } + ) + remapMovements( + movements, + { remappedTrxs, remappedTrxsForConvToUsd } + ) + + const trxs = remappedTrxs + .sort((a, b) => b?.mtsCreate - a?.mtsCreate) + const trxsForConvToUsd = remappedTrxsForConvToUsd + .sort((a, b) => b?.mtsCreate - a?.mtsCreate) + + return { + trxs, + trxsForConvToUsd + } + } + + async #getTrades ({ + user, + start, + end, + symbol + }) { + const symbFilter = ( + Array.isArray(symbol) && + symbol.length !== 0 + ) + ? { $in: { symbol } } + : {} + + return this.dao.getElemsInCollBy( + this.ALLOWED_COLLS.TRADES, + { + filter: { + user_id: user._id, + $lte: { mtsCreate: end }, + $gte: { mtsCreate: start }, + ...symbFilter + }, + sort: [['mtsCreate', -1]], + projection: this.tradesModel, + exclude: ['user_id'], + isExcludePrivate: false + } + ) + } } decorateInjectable(TransactionTaxReport, depsTypes) From 2a30f18cb88a56517b1d0fea00dccc45a7179034 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Thu, 23 May 2024 12:40:31 +0300 Subject: [PATCH 5/6] Add collection flags to trx entries --- .../sync/transaction.tax.report/helpers/remap-movements.js | 3 +++ .../sync/transaction.tax.report/helpers/remap-trades.js | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js b/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js index 65ad54cc8..7f01a31a3 100644 --- a/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js +++ b/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js @@ -28,10 +28,13 @@ module.exports = (movements, params) => { : '' const remappedMovement = { + _id: movement._id, // NOTE: it means entries are not taken form trades table isAdditionalTrxMovements: true, // NOTE: movements can have sub-account transfer entries from ledgers table isMovements: !movement.isLedgers, + isLedgers: !!movement.isLedgers, + isTrades: false, symbol: `t${firstSymb}${symbSeparator}${lastSymb}`, mtsCreate: movement.mtsUpdated, firstSymb, diff --git a/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js b/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js index bb5a5098e..6a15b74cd 100644 --- a/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js +++ b/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js @@ -27,6 +27,10 @@ module.exports = (trades, params) => { trade.lastSymb = lastSymb trade.firstSymbPrice = null trade.lastSymbPrice = null + trade.isAdditionalTrxMovements = false + trade.isMovements = false + trade.isLedgers = false + trade.isTrades = true remappedTrxs.push(trade) From 3753a31a691a6160a8c0653649b2a95bdbe2bfbe Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Fri, 24 May 2024 11:24:14 +0300 Subject: [PATCH 6/6] Improve pair price naming in usd --- .../helpers/remap-movements.js | 8 ++++---- .../transaction.tax.report/helpers/remap-trades.js | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js b/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js index 7f01a31a3..f22393f28 100644 --- a/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js +++ b/workers/loc.api/sync/transaction.tax.report/helpers/remap-movements.js @@ -39,10 +39,10 @@ module.exports = (movements, params) => { mtsCreate: movement.mtsUpdated, firstSymb, lastSymb, - firstSymbPrice: null, - lastSymbPrice: 1, + firstSymbPriceUsd: null, + lastSymbPriceUsd: 1, execAmount: movement.amount, - // NOTE: execPrice = firstSymbPrice and should be set when converting currencies + // NOTE: execPrice = firstSymbPriceUsd and should be set when converting currencies execPrice: 0, // NOTE: exactUsdValue can be null on the first launch, for warm-up it's filling from pub-trades exactUsdValue: movement.exactUsdValue @@ -56,7 +56,7 @@ module.exports = (movements, params) => { ) { const price = movement.exactUsdValue / movement.amount - remappedMovement.firstSymbPrice = price + remappedMovement.firstSymbPriceUsd = price remappedMovement.execPrice = price continue diff --git a/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js b/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js index 6a15b74cd..722290295 100644 --- a/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js +++ b/workers/loc.api/sync/transaction.tax.report/helpers/remap-trades.js @@ -25,8 +25,8 @@ module.exports = (trades, params) => { const [firstSymb, lastSymb] = splitSymbolPairs(trade.symbol) trade.firstSymb = firstSymb trade.lastSymb = lastSymb - trade.firstSymbPrice = null - trade.lastSymbPrice = null + trade.firstSymbPriceUsd = null + trade.lastSymbPriceUsd = null trade.isAdditionalTrxMovements = false trade.isMovements = false trade.isLedgers = false @@ -35,8 +35,8 @@ module.exports = (trades, params) => { remappedTrxs.push(trade) if (lastSymb === 'USD') { - trade.firstSymbPrice = trade.execPrice - trade.lastSymbPrice = 1 + trade.firstSymbPriceUsd = trade.execPrice + trade.lastSymbPriceUsd = 1 continue } @@ -44,8 +44,8 @@ module.exports = (trades, params) => { Number.isFinite(trade.exactUsdValue) && trade.exactUsdValue > 0 ) { - trade.firstSymbPrice = trade.exactUsdValue / trade.execAmount - trade.lastSymbPrice = trade.exactUsdValue / trade.execPrice + trade.firstSymbPriceUsd = trade.exactUsdValue / trade.execAmount + trade.lastSymbPriceUsd = trade.exactUsdValue / trade.execPrice continue }