From d8a5b50b07eb3b9ca9f7f2024eff221e7ca9d1e3 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 12:34:26 +0300 Subject: [PATCH 01/10] Add TransactionTaxReport service type --- workers/loc.api/di/types.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workers/loc.api/di/types.js b/workers/loc.api/di/types.js index ab72b5cd5..0f1286839 100644 --- a/workers/loc.api/di/types.js +++ b/workers/loc.api/di/types.js @@ -69,5 +69,6 @@ module.exports = { SyncUserStepData: Symbol.for('SyncUserStepData'), SyncUserStepDataFactory: Symbol.for('SyncUserStepDataFactory'), HTTPRequest: Symbol.for('HTTPRequest'), - SummaryByAsset: Symbol.for('SummaryByAsset') + SummaryByAsset: Symbol.for('SummaryByAsset'), + TransactionTaxReport: Symbol.for('TransactionTaxReport') } From a97d30a6f35de3d432b187bcdf58cac275853c84 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 13:06:25 +0300 Subject: [PATCH 02/10] Add TransactionTaxReport service --- .../transaction.tax.report/helpers/index.js | 7 ++ .../helpers/trx.tax.strategies.js | 8 ++ .../sync/transaction.tax.report/index.js | 84 +++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 workers/loc.api/sync/transaction.tax.report/helpers/index.js create mode 100644 workers/loc.api/sync/transaction.tax.report/helpers/trx.tax.strategies.js create mode 100644 workers/loc.api/sync/transaction.tax.report/index.js diff --git a/workers/loc.api/sync/transaction.tax.report/helpers/index.js b/workers/loc.api/sync/transaction.tax.report/helpers/index.js new file mode 100644 index 000000000..71c804c7b --- /dev/null +++ b/workers/loc.api/sync/transaction.tax.report/helpers/index.js @@ -0,0 +1,7 @@ +'use strict' + +const TRX_TAX_STRATEGIES = require('./trx.tax.strategies') + +module.exports = { + TRX_TAX_STRATEGIES +} diff --git a/workers/loc.api/sync/transaction.tax.report/helpers/trx.tax.strategies.js b/workers/loc.api/sync/transaction.tax.report/helpers/trx.tax.strategies.js new file mode 100644 index 000000000..087b2bbf7 --- /dev/null +++ b/workers/loc.api/sync/transaction.tax.report/helpers/trx.tax.strategies.js @@ -0,0 +1,8 @@ +'use strict' + +const TRX_TAX_STRATEGIES = { + FIFO: 'FIFO', + LIFO: 'LIFO' +} + +module.exports = TRX_TAX_STRATEGIES diff --git a/workers/loc.api/sync/transaction.tax.report/index.js b/workers/loc.api/sync/transaction.tax.report/index.js new file mode 100644 index 000000000..497472f93 --- /dev/null +++ b/workers/loc.api/sync/transaction.tax.report/index.js @@ -0,0 +1,84 @@ +'use strict' + +const { + TRX_TAX_STRATEGIES +} = require('./helpers') + +const { decorateInjectable } = require('../../di/utils') + +const depsTypes = (TYPES) => [ + TYPES.DAO, + TYPES.Authenticator, + TYPES.SyncSchema, + TYPES.ALLOWED_COLLS, + TYPES.SYNC_API_METHODS, + TYPES.Movements, + TYPES.RService, + TYPES.GetDataFromApi, + TYPES.WSEventEmitterFactory, + TYPES.Logger +] +class TransactionTaxReport { + constructor ( + dao, + authenticator, + syncSchema, + ALLOWED_COLLS, + SYNC_API_METHODS, + movements, + rService, + getDataFromApi, + wsEventEmitterFactory, + logger + ) { + this.dao = dao + this.authenticator = authenticator + this.syncSchema = syncSchema + this.ALLOWED_COLLS = ALLOWED_COLLS + this.SYNC_API_METHODS = SYNC_API_METHODS + this.movements = movements + this.rService = rService + this.getDataFromApi = getDataFromApi + this.wsEventEmitterFactory = wsEventEmitterFactory + this.logger = logger + + this.tradesModel = this.syncSchema.getModelsMap() + .get(this.ALLOWED_COLLS.TRADES) + } + + async makeTrxTaxReportInBackground (args = {}) { + const { auth, params } = args ?? {} + const user = await this.authenticator + .verifyRequestUser({ auth }) + const _args = { auth: user, params } + + this.wsEventEmitterFactory() + .emitTrxTaxReportGenerationInBackgroundToOne(() => { + return this.getTransactionTaxReport(_args) + }, user) + .then(() => {}, (err) => { + this.logger.error(`TRX_TAX_REPORT_GEN_FAILED: ${err.stack || err}`) + }) + + return true + } + + async getTransactionTaxReport (args = {}) { + const { auth, params } = args ?? {} + const start = params.start ?? 0 + const end = params.end ?? Date.now() + const strategy = params.strategy ?? TRX_TAX_STRATEGIES.LIFO + const user = await this.authenticator + .verifyRequestUser({ auth }) + + const isFIFO = strategy === TRX_TAX_STRATEGIES.FIFO + const isLIFO = strategy === TRX_TAX_STRATEGIES.LIFO + + // TODO: + return [] + } +} + +decorateInjectable(TransactionTaxReport, depsTypes) + +module.exports = TransactionTaxReport From c30573804a50ebdb479018bd4e2cda3d2278b0fd Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 13:06:55 +0300 Subject: [PATCH 03/10] Add TransactionTaxReport service into di --- workers/loc.api/di/app.deps.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/workers/loc.api/di/app.deps.js b/workers/loc.api/di/app.deps.js index db53474f0..84a4f57bf 100644 --- a/workers/loc.api/di/app.deps.js +++ b/workers/loc.api/di/app.deps.js @@ -97,6 +97,7 @@ const { fullTaxReportCsvWriter } = require('../generate-report-file/csv-writer') const FullTaxReport = require('../sync/full.tax.report') +const TransactionTaxReport = require('../sync/transaction.tax.report') const WeightedAveragesReport = require('../sync/weighted.averages.report') const SqliteDbMigrator = require( '../sync/dao/db-migrations/sqlite.db.migrator' @@ -151,6 +152,7 @@ module.exports = ({ ['_positionsSnapshot', TYPES.PositionsSnapshot], ['_fullSnapshotReport', TYPES.FullSnapshotReport], ['_fullTaxReport', TYPES.FullTaxReport], + ['_transactionTaxReport', TYPES.TransactionTaxReport], ['_tradedVolume', TYPES.TradedVolume], ['_totalFeesReport', TYPES.TotalFeesReport], ['_performingLoan', TYPES.PerformingLoan], @@ -393,6 +395,9 @@ module.exports = ({ ) bind(TYPES.FullTaxReport) .to(FullTaxReport) + bind(TYPES.TransactionTaxReport) + .to(TransactionTaxReport) + .inSingletonScope() rebind(TYPES.WeightedAveragesReport) .to(WeightedAveragesReport) rebind(TYPES.ReportFileJobData) From c9e5984e887b93d9c60a6cf2da789c03f74201fa Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 13:07:56 +0300 Subject: [PATCH 04/10] Add data consistency checker for TransactionTaxReport --- .../sync/data.consistency.checker/checker.names.js | 1 + .../sync/data.consistency.checker/checkers.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/workers/loc.api/sync/data.consistency.checker/checker.names.js b/workers/loc.api/sync/data.consistency.checker/checker.names.js index db644c065..f4dff2943 100644 --- a/workers/loc.api/sync/data.consistency.checker/checker.names.js +++ b/workers/loc.api/sync/data.consistency.checker/checker.names.js @@ -7,6 +7,7 @@ module.exports = { POSITIONS_SNAPSHOT: 'getPositionsSnapshot', FULL_SNAPSHOT_REPORT: 'getFullSnapshotReport', FULL_TAX_REPORT: 'getFullTaxReport', + TRANSACTION_TAX_REPORT: 'getTransactionTaxReport', TRADED_VOLUME: 'getTradedVolume', TOTAL_FEES_REPORT: 'getTotalFeesReport', PERFORMING_LOAN: 'getPerformingLoan', diff --git a/workers/loc.api/sync/data.consistency.checker/checkers.js b/workers/loc.api/sync/data.consistency.checker/checkers.js index 041ed2cbf..ff5b666e4 100644 --- a/workers/loc.api/sync/data.consistency.checker/checkers.js +++ b/workers/loc.api/sync/data.consistency.checker/checkers.js @@ -103,6 +103,20 @@ class Checkers { }) } + [CHECKER_NAMES.TRANSACTION_TAX_REPORT] (auth) { + return this.syncCollsManager + .haveCollsBeenSyncedUpToDate({ + auth, + params: { + schema: [ + this.SYNC_API_METHODS.TRADES, + this.SYNC_API_METHODS.LEDGERS, + this.SYNC_API_METHODS.MOVEMENTS + ] + } + }) + } + [CHECKER_NAMES.TRADED_VOLUME] (auth) { return this.syncCollsManager .haveCollsBeenSyncedUpToDate({ From bffe5447584a4ea992e64a9aff5058469bdbef69 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 13:09:49 +0300 Subject: [PATCH 05/10] Add params schema for TransactionTaxReport --- workers/loc.api/helpers/schema.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/workers/loc.api/helpers/schema.js b/workers/loc.api/helpers/schema.js index db81e9197..0059fd710 100644 --- a/workers/loc.api/helpers/schema.js +++ b/workers/loc.api/helpers/schema.js @@ -214,6 +214,25 @@ const paramsSchemaForFullTaxReportApi = { } } +const paramsSchemaForTransactionTaxReportApi = { + type: 'object', + properties: { + end: { + type: 'integer' + }, + start: { + type: 'integer' + }, + strategy: { + type: 'string', + enum: [ + 'FIFO', + 'LIFO' + ] + } + } +} + const paramsSchemaForWinLossApi = { type: 'object', properties: { @@ -412,6 +431,15 @@ const paramsSchemaForFullTaxReportFile = { } } +const paramsSchemaForTransactionTaxReportFile = { + type: 'object', + properties: { + ...cloneDeep(paramsSchemaForTransactionTaxReportApi.properties), + timezone, + dateFormat + } +} + const paramsSchemaForTradedVolumeFile = { type: 'object', properties: { @@ -460,6 +488,7 @@ module.exports = { paramsSchemaForPositionsSnapshotApi, paramsSchemaForFullSnapshotReportApi, paramsSchemaForFullTaxReportApi, + paramsSchemaForTransactionTaxReportApi, paramsSchemaForTradedVolumeApi, paramsSchemaForTotalFeesReportApi, paramsSchemaForPerformingLoanApi, @@ -471,6 +500,7 @@ module.exports = { paramsSchemaForPositionsSnapshotFile, paramsSchemaForFullSnapshotReportFile, paramsSchemaForFullTaxReportFile, + paramsSchemaForTransactionTaxReportFile, paramsSchemaForTradedVolumeFile, paramsSchemaForTotalFeesReportFile, paramsSchemaForPerformingLoanFile, From 140b0d12cd8fff7e9bb640acbf42b4268d5734e7 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 13:11:18 +0300 Subject: [PATCH 06/10] Add getTransactionTaxReport entrypoint to main service --- workers/loc.api/service.report.framework.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/workers/loc.api/service.report.framework.js b/workers/loc.api/service.report.framework.js index 057c195a8..b1bd3c017 100644 --- a/workers/loc.api/service.report.framework.js +++ b/workers/loc.api/service.report.framework.js @@ -1409,6 +1409,17 @@ class FrameworkReportService extends ReportService { }, 'getFullTaxReport', args, cb) } + getTransactionTaxReport (space, args, cb) { + return this._privResponder(async () => { + await this._dataConsistencyChecker + .check(this._CHECKER_NAMES.TRANSACTION_TAX_REPORT, args) + + checkParams(args, 'paramsSchemaForTransactionTaxReportApi') + + return this._transactionTaxReport.getTransactionTaxReport(args) + }, 'getTransactionTaxReport', args, cb) + } + getTradedVolume (space, args, cb) { return this._privResponder(async () => { await this._dataConsistencyChecker From e61213381835b590e748b069f82c7c3e6e625f6e Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 13:12:29 +0300 Subject: [PATCH 07/10] Add makeTrxTaxReportInBackground entrypoint to main service --- workers/loc.api/service.report.framework.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/workers/loc.api/service.report.framework.js b/workers/loc.api/service.report.framework.js index b1bd3c017..3c18bc1bb 100644 --- a/workers/loc.api/service.report.framework.js +++ b/workers/loc.api/service.report.framework.js @@ -1420,6 +1420,17 @@ class FrameworkReportService extends ReportService { }, 'getTransactionTaxReport', args, cb) } + makeTrxTaxReportInBackground (space, args, cb) { + return this._privResponder(async () => { + await this._dataConsistencyChecker + .check(this._CHECKER_NAMES.TRANSACTION_TAX_REPORT, args) + + checkParams(args, 'paramsSchemaForTransactionTaxReportApi') + + return this._transactionTaxReport.makeTrxTaxReportInBackground(args) + }, 'makeTrxTaxReportInBackground', args, cb) + } + getTradedVolume (space, args, cb) { return this._privResponder(async () => { await this._dataConsistencyChecker From 112a5807d4bb16023b6de94fc276d0bcfd002666 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 13:12:59 +0300 Subject: [PATCH 08/10] Add getTransactionTaxReportFile entrypoint to main service --- workers/loc.api/service.report.framework.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/workers/loc.api/service.report.framework.js b/workers/loc.api/service.report.framework.js index 3c18bc1bb..2e0ea6bf7 100644 --- a/workers/loc.api/service.report.framework.js +++ b/workers/loc.api/service.report.framework.js @@ -1575,6 +1575,20 @@ class FrameworkReportService extends ReportService { }, 'getFullTaxReportFile', args, cb) } + /** + * @deprecated + */ + getTransactionTaxReportCsv (...args) { return this.getTransactionTaxReportFile(...args) } + + getTransactionTaxReportFile (space, args, cb) { + return this._responder(() => { + return this._generateReportFile( + 'getTransactionTaxReportFileJobData', + args + ) + }, 'getTransactionTaxReportFile', args, cb) + } + /** * @deprecated */ From 3f25cb9af9359e3224a0f8f4caad75679fd6b887 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 13:13:38 +0300 Subject: [PATCH 09/10] Add report file job data for TransactionTaxReport --- .../report.file.job.data.js | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/workers/loc.api/generate-report-file/report.file.job.data.js b/workers/loc.api/generate-report-file/report.file.job.data.js index 430725f1c..ad545f3a3 100644 --- a/workers/loc.api/generate-report-file/report.file.job.data.js +++ b/workers/loc.api/generate-report-file/report.file.job.data.js @@ -528,6 +528,50 @@ class ReportFileJobData extends BaseReportFileJobData { return jobData } + async getTransactionTaxReportFileJobData ( + args, + uId, + uInfo + ) { + checkParams(args, 'paramsSchemaForTransactionTaxReportFile') + + const { + userId, + userInfo + } = await checkJobAndGetUserData( + this.rService, + uId, + uInfo + ) + + const reportFileArgs = getReportFileArgs(args) + + const jobData = { + userInfo, + userId, + name: 'getTransactionTaxReport', + fileNamesMap: [['getTransactionTaxReport', 'transaction-tax-report']], + args: reportFileArgs, + propNameForPagination: null, + columnsCsv: { + asset: 'DESCRIPTION OF PROPERTY', + amount: 'AMOUNT', + mtsAcquired: 'DATE ACQUIRED', + mtsSold: 'DATE SOLD', + proceeds: 'PROCEEDS', + cost: 'COST', + gainOrLoss: 'GAIN OR LOSS' + }, + formatSettings: { + asset: 'symbol', + mtsAcquired: 'date', + mtsSold: 'date' + } + } + + return jobData + } + async getTradedVolumeFileJobData ( args, uId, From 5e285ba407d661599ba7c922da78b9a382eec53d Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 21 May 2024 13:15:16 +0300 Subject: [PATCH 10/10] Add ability to send ws event when trx tax report generated --- workers/loc.api/ws-transport/ws.event.emitter.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/workers/loc.api/ws-transport/ws.event.emitter.js b/workers/loc.api/ws-transport/ws.event.emitter.js index c1ea2481a..4d0f2350c 100644 --- a/workers/loc.api/ws-transport/ws.event.emitter.js +++ b/workers/loc.api/ws-transport/ws.event.emitter.js @@ -138,6 +138,21 @@ class WSEventEmitter extends AbstractWSEventEmitter { }, 'emitBfxUnamePwdAuthRequired') } + emitTrxTaxReportGenerationInBackgroundToOne ( + handler = () => {}, + auth = {} + ) { + return this.emit(async (user, ...args) => { + if (this.isNotTargetUser(auth, user)) { + return { isNotEmitted: true } + } + + return typeof handler === 'function' + ? await handler(user, ...args) + : handler + }, 'emitTrxTaxReportGenerationInBackgroundToOne') + } + async emitRedirectingRequestsStatusToApi ( handler = () => {} ) {