From c216ab1d7665fe9f59444387c5368b11c68712e1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 5 Mar 2022 11:07:27 +0100 Subject: [PATCH] Eliminate data source from order model (#730) * Eliminate currency, data source and symbol from order model * Remove prefix for symbols with data source GHOSTFOLIO * Update changelog --- CHANGELOG.md | 9 +++ apps/api/src/app/export/export.service.ts | 5 +- apps/api/src/app/import/import-data.dto.ts | 3 +- apps/api/src/app/import/import.service.ts | 17 +++-- apps/api/src/app/order/order.controller.ts | 9 +++ apps/api/src/app/order/order.service.ts | 71 ++++++++++++------- .../app/portfolio/portfolio.service-new.ts | 29 ++++---- .../src/app/portfolio/portfolio.service.ts | 29 ++++---- ...orm-data-source-in-response.interceptor.ts | 8 --- .../src/services/data-gathering.service.ts | 27 ++++--- .../ghostfolio-scraper-api.service.ts | 8 +-- .../services/exchange-rate-data.service.ts | 7 +- ...-or-update-transaction-dialog.component.ts | 14 ++-- libs/common/src/lib/helper.ts | 4 -- .../activities-table.component.html | 4 +- .../migration.sql | 2 + .../migration.sql | 2 + .../migration.sql | 2 + .../migration.sql | 5 ++ prisma/schema.prisma | 5 +- prisma/seed.js | 40 +++-------- 21 files changed, 148 insertions(+), 152 deletions(-) create mode 100644 prisma/migrations/20220302184222_removed_data_source_from_order/migration.sql create mode 100644 prisma/migrations/20220302191841_removed_currency_from_order/migration.sql create mode 100644 prisma/migrations/20220302193633_removed_symbol_from_order/migration.sql create mode 100644 prisma/migrations/20220302200727_changed_currency_to_required_in_symbol_profile/migration.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index 043680fff..555060133 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,10 +11,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Included data provider errors in API response +### Changed + +- Removed the redundant attributes (`currency`, `dataSource`, `symbol`) of the activity model +- Removed the prefix for symbols with the data source `GHOSTFOLIO` + ### Fixed - Improved the account calculations +### Todo + +- Apply data migration (`yarn database:migrate`) + ## 1.122.0 - 01.03.2022 ### Added diff --git a/apps/api/src/app/export/export.service.ts b/apps/api/src/app/export/export.service.ts index b540fe363..124fe6325 100644 --- a/apps/api/src/app/export/export.service.ts +++ b/apps/api/src/app/export/export.service.ts @@ -18,8 +18,6 @@ export class ExportService { orderBy: { date: 'desc' }, select: { accountId: true, - currency: true, - dataSource: true, date: true, fee: true, id: true, @@ -42,7 +40,6 @@ export class ExportService { orders: orders.map( ({ accountId, - currency, date, fee, quantity, @@ -52,12 +49,12 @@ export class ExportService { }) => { return { accountId, - currency, date, fee, quantity, type, unitPrice, + currency: SymbolProfile.currency, dataSource: SymbolProfile.dataSource, symbol: type === 'ITEM' ? SymbolProfile.name : SymbolProfile.symbol }; diff --git a/apps/api/src/app/import/import-data.dto.ts b/apps/api/src/app/import/import-data.dto.ts index fa1b3aa99..488ac786f 100644 --- a/apps/api/src/app/import/import-data.dto.ts +++ b/apps/api/src/app/import/import-data.dto.ts @@ -1,5 +1,4 @@ import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto'; -import { Order } from '@prisma/client'; import { Type } from 'class-transformer'; import { IsArray, ValidateNested } from 'class-validator'; @@ -7,5 +6,5 @@ export class ImportDataDto { @IsArray() @Type(() => CreateOrderDto) @ValidateNested({ each: true }) - orders: Order[]; + orders: CreateOrderDto[]; } diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 7d0f152b2..d68e60bac 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -3,8 +3,8 @@ import { OrderService } from '@ghostfolio/api/app/order/order.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { Injectable } from '@nestjs/common'; -import { Order } from '@prisma/client'; import { isSameDay, parseISO } from 'date-fns'; +import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto'; @Injectable() export class ImportService { @@ -19,7 +19,7 @@ export class ImportService { orders, userId }: { - orders: Partial[]; + orders: Partial[]; userId: string; }): Promise { for (const order of orders) { @@ -52,11 +52,8 @@ export class ImportService { unitPrice } of orders) { await this.orderService.createOrder({ - currency, - dataSource, fee, quantity, - symbol, type, unitPrice, userId, @@ -65,6 +62,7 @@ export class ImportService { SymbolProfile: { connectOrCreate: { create: { + currency, dataSource, symbol }, @@ -85,7 +83,7 @@ export class ImportService { orders, userId }: { - orders: Partial[]; + orders: Partial[]; userId: string; }) { if ( @@ -99,6 +97,7 @@ export class ImportService { } const existingOrders = await this.orderService.orders({ + include: { SymbolProfile: true }, orderBy: { date: 'desc' }, where: { userId } }); @@ -109,12 +108,12 @@ export class ImportService { ] of orders.entries()) { const duplicateOrder = existingOrders.find((order) => { return ( - order.currency === currency && - order.dataSource === dataSource && + order.SymbolProfile.currency === currency && + order.SymbolProfile.dataSource === dataSource && isSameDay(order.date, parseISO((date))) && order.fee === fee && order.quantity === quantity && - order.symbol === symbol && + order.SymbolProfile.symbol === symbol && order.type === type && order.unitPrice === unitPrice ); diff --git a/apps/api/src/app/order/order.controller.ts b/apps/api/src/app/order/order.controller.ts index 58a043b82..740676950 100644 --- a/apps/api/src/app/order/order.controller.ts +++ b/apps/api/src/app/order/order.controller.ts @@ -114,6 +114,7 @@ export class OrderController { SymbolProfile: { connectOrCreate: { create: { + currency: data.currency, dataSource: data.dataSource, symbol: data.symbol }, @@ -171,6 +172,14 @@ export class OrderController { id_userId: { id: accountId, userId: this.request.user.id } } }, + SymbolProfile: { + connect: { + dataSource_symbol: { + dataSource: data.dataSource, + symbol: data.symbol + } + } + }, User: { connect: { id: this.request.user.id } } }, where: { diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index 2613c2c13..ee01b3092 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -53,7 +53,13 @@ export class OrderService { } public async createOrder( - data: Prisma.OrderCreateInput & { accountId?: string; userId: string } + data: Prisma.OrderCreateInput & { + accountId?: string; + currency?: string; + dataSource?: DataSource; + symbol?: string; + userId: string; + } ): Promise { const defaultAccount = ( await this.accountService.getAccounts(data.userId) @@ -71,15 +77,13 @@ export class OrderService { }; if (data.type === 'ITEM') { - const currency = data.currency; + const currency = data.SymbolProfile.connectOrCreate.create.currency; const dataSource: DataSource = 'MANUAL'; const id = uuidv4(); const name = data.SymbolProfile.connectOrCreate.create.symbol; Account = undefined; - data.dataSource = dataSource; data.id = id; - data.symbol = null; data.SymbolProfile.connectOrCreate.create.currency = currency; data.SymbolProfile.connectOrCreate.create.dataSource = dataSource; data.SymbolProfile.connectOrCreate.create.name = name; @@ -95,7 +99,7 @@ export class OrderService { await this.dataGatheringService.gatherProfileData([ { - dataSource: data.dataSource, + dataSource: data.SymbolProfile.connectOrCreate.create.dataSource, symbol: data.SymbolProfile.connectOrCreate.create.symbol } ]); @@ -106,7 +110,7 @@ export class OrderService { // Gather symbol data of order in the background, if not draft this.dataGatheringService.gatherSymbols([ { - dataSource: data.dataSource, + dataSource: data.SymbolProfile.connectOrCreate.create.dataSource, date: data.date, symbol: data.SymbolProfile.connectOrCreate.create.symbol } @@ -116,6 +120,9 @@ export class OrderService { await this.cacheService.flush(); delete data.accountId; + delete data.currency; + delete data.dataSource; + delete data.symbol; delete data.userId; const orderData: Prisma.OrderCreateInput = data; @@ -193,50 +200,60 @@ export class OrderService { value, feeInBaseCurrency: this.exchangeRateDataService.toCurrency( order.fee, - order.currency, + order.SymbolProfile.currency, userCurrency ), valueInBaseCurrency: this.exchangeRateDataService.toCurrency( value, - order.currency, + order.SymbolProfile.currency, userCurrency ) }; }); } - public async updateOrder(params: { + public async updateOrder({ + data, + where + }: { + data: Prisma.OrderUpdateInput & { + currency?: string; + dataSource?: DataSource; + symbol?: string; + }; where: Prisma.OrderWhereUniqueInput; - data: Prisma.OrderUpdateInput; }): Promise { - const { data, where } = params; - if (data.Account.connect.id_userId.id === null) { delete data.Account; } + let isDraft = false; + if (data.type === 'ITEM') { - const name = data.symbol; + const name = data.SymbolProfile.connect.dataSource_symbol.symbol; - data.symbol = null; data.SymbolProfile = { update: { name } }; - } - - const isDraft = isAfter(data.date as Date, endOfToday()); - - if (!isDraft) { - // Gather symbol data of order in the background, if not draft - this.dataGatheringService.gatherSymbols([ - { - dataSource: data.dataSource, - date: data.date, - symbol: data.symbol - } - ]); + } else { + isDraft = isAfter(data.date as Date, endOfToday()); + + if (!isDraft) { + // Gather symbol data of order in the background, if not draft + this.dataGatheringService.gatherSymbols([ + { + dataSource: data.SymbolProfile.connect.dataSource_symbol.dataSource, + date: data.date, + symbol: data.SymbolProfile.connect.dataSource_symbol.symbol + } + ]); + } } await this.cacheService.flush(); + delete data.currency; + delete data.dataSource; + delete data.symbol; + return this.prismaService.order.update({ data: { ...data, diff --git a/apps/api/src/app/portfolio/portfolio.service-new.ts b/apps/api/src/app/portfolio/portfolio.service-new.ts index e078c5410..b34a9206f 100644 --- a/apps/api/src/app/portfolio/portfolio.service-new.ts +++ b/apps/api/src/app/portfolio/portfolio.service-new.ts @@ -450,7 +450,7 @@ export class PortfolioServiceNew { }; } - const positionCurrency = orders[0].currency; + const positionCurrency = orders[0].SymbolProfile.currency; const [SymbolProfile] = await this.symbolProfileService.getSymbolProfiles([ aSymbol ]); @@ -460,13 +460,13 @@ export class PortfolioServiceNew { return order.type === 'BUY' || order.type === 'SELL'; }) .map((order) => ({ - currency: order.currency, - dataSource: order.SymbolProfile?.dataSource ?? order.dataSource, + currency: order.SymbolProfile.currency, + dataSource: order.SymbolProfile.dataSource, date: format(order.date, DATE_FORMAT), fee: new Big(order.fee), name: order.SymbolProfile?.name, quantity: new Big(order.quantity), - symbol: order.symbol, + symbol: order.SymbolProfile.symbol, type: order.type, unitPrice: new Big(order.unitPrice) })); @@ -1023,7 +1023,7 @@ export class PortfolioServiceNew { .map((order) => { return this.exchangeRateDataService.toCurrency( new Big(order.quantity).mul(order.unitPrice).toNumber(), - order.currency, + order.SymbolProfile.currency, this.request.user.Settings.currency ); }) @@ -1042,7 +1042,7 @@ export class PortfolioServiceNew { .map((order) => { return this.exchangeRateDataService.toCurrency( order.fee, - order.currency, + order.SymbolProfile.currency, this.request.user.Settings.currency ); }) @@ -1064,7 +1064,7 @@ export class PortfolioServiceNew { .map((order) => { return this.exchangeRateDataService.toCurrency( new Big(order.quantity).mul(order.unitPrice).toNumber(), - order.currency, + order.SymbolProfile.currency, this.request.user.Settings.currency ); }) @@ -1117,24 +1117,24 @@ export class PortfolioServiceNew { } const portfolioOrders: PortfolioOrder[] = orders.map((order) => ({ - currency: order.currency, - dataSource: order.SymbolProfile?.dataSource ?? order.dataSource, + currency: order.SymbolProfile.currency, + dataSource: order.SymbolProfile.dataSource, date: format(order.date, DATE_FORMAT), fee: new Big( this.exchangeRateDataService.toCurrency( order.fee, - order.currency, + order.SymbolProfile.currency, userCurrency ) ), name: order.SymbolProfile?.name, quantity: new Big(order.quantity), - symbol: order.symbol, + symbol: order.SymbolProfile.symbol, type: order.type, unitPrice: new Big( this.exchangeRateDataService.toCurrency( order.unitPrice, - order.currency, + order.SymbolProfile.currency, userCurrency ) ) @@ -1180,7 +1180,8 @@ export class PortfolioServiceNew { for (const order of ordersByAccount) { let currentValueOfSymbol = - order.quantity * portfolioItemsNow[order.symbol].marketPrice; + order.quantity * + portfolioItemsNow[order.SymbolProfile.symbol].marketPrice; let originalValueOfSymbol = order.quantity * order.unitPrice; if (order.type === 'SELL') { @@ -1230,7 +1231,7 @@ export class PortfolioServiceNew { .map((order) => { return this.exchangeRateDataService.toCurrency( order.quantity * order.unitPrice, - order.currency, + order.SymbolProfile.currency, currency ); }) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 108c55d27..f3df18c30 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -438,7 +438,7 @@ export class PortfolioService { }; } - const positionCurrency = orders[0].currency; + const positionCurrency = orders[0].SymbolProfile.currency; const [SymbolProfile] = await this.symbolProfileService.getSymbolProfiles([ aSymbol ]); @@ -448,13 +448,13 @@ export class PortfolioService { return order.type === 'BUY' || order.type === 'SELL'; }) .map((order) => ({ - currency: order.currency, - dataSource: order.SymbolProfile?.dataSource ?? order.dataSource, + currency: order.SymbolProfile.currency, + dataSource: order.SymbolProfile.dataSource, date: format(order.date, DATE_FORMAT), fee: new Big(order.fee), name: order.SymbolProfile?.name, quantity: new Big(order.quantity), - symbol: order.symbol, + symbol: order.SymbolProfile.symbol, type: order.type, unitPrice: new Big(order.unitPrice) })); @@ -987,7 +987,7 @@ export class PortfolioService { .map((order) => { return this.exchangeRateDataService.toCurrency( new Big(order.quantity).mul(order.unitPrice).toNumber(), - order.currency, + order.SymbolProfile.currency, this.request.user.Settings.currency ); }) @@ -1006,7 +1006,7 @@ export class PortfolioService { .map((order) => { return this.exchangeRateDataService.toCurrency( order.fee, - order.currency, + order.SymbolProfile.currency, this.request.user.Settings.currency ); }) @@ -1028,7 +1028,7 @@ export class PortfolioService { .map((order) => { return this.exchangeRateDataService.toCurrency( new Big(order.quantity).mul(order.unitPrice).toNumber(), - order.currency, + order.SymbolProfile.currency, this.request.user.Settings.currency ); }) @@ -1080,24 +1080,24 @@ export class PortfolioService { } const portfolioOrders: PortfolioOrder[] = orders.map((order) => ({ - currency: order.currency, - dataSource: order.SymbolProfile?.dataSource ?? order.dataSource, + currency: order.SymbolProfile.currency, + dataSource: order.SymbolProfile.dataSource, date: format(order.date, DATE_FORMAT), fee: new Big( this.exchangeRateDataService.toCurrency( order.fee, - order.currency, + order.SymbolProfile.currency, userCurrency ) ), name: order.SymbolProfile?.name, quantity: new Big(order.quantity), - symbol: order.symbol, + symbol: order.SymbolProfile.symbol, type: order.type, unitPrice: new Big( this.exchangeRateDataService.toCurrency( order.unitPrice, - order.currency, + order.SymbolProfile.currency, userCurrency ) ) @@ -1139,7 +1139,8 @@ export class PortfolioService { for (const order of ordersByAccount) { let currentValueOfSymbol = - order.quantity * portfolioItemsNow[order.symbol].marketPrice; + order.quantity * + portfolioItemsNow[order.SymbolProfile.symbol].marketPrice; let originalValueOfSymbol = order.quantity * order.unitPrice; if (order.type === 'SELL') { @@ -1189,7 +1190,7 @@ export class PortfolioService { .map((order) => { return this.exchangeRateDataService.toCurrency( order.quantity * order.unitPrice, - order.currency, + order.SymbolProfile.currency, currency ); }) diff --git a/apps/api/src/interceptors/transform-data-source-in-response.interceptor.ts b/apps/api/src/interceptors/transform-data-source-in-response.interceptor.ts index 2aeb895fe..6c96b3965 100644 --- a/apps/api/src/interceptors/transform-data-source-in-response.interceptor.ts +++ b/apps/api/src/interceptors/transform-data-source-in-response.interceptor.ts @@ -32,7 +32,6 @@ export class TransformDataSourceInResponseInterceptor activity.SymbolProfile.dataSource = encodeDataSource( activity.SymbolProfile.dataSource ); - activity.dataSource = encodeDataSource(activity.dataSource); return activity; }); } @@ -66,13 +65,6 @@ export class TransformDataSourceInResponseInterceptor }); } - if (data.orders) { - data.orders.map((order) => { - order.dataSource = encodeDataSource(order.dataSource); - return order; - }); - } - if (data.positions) { data.positions.map((position) => { position.dataSource = encodeDataSource(position.dataSource); diff --git a/apps/api/src/services/data-gathering.service.ts b/apps/api/src/services/data-gathering.service.ts index 9292709c3..ea70d7be8 100644 --- a/apps/api/src/services/data-gathering.service.ts +++ b/apps/api/src/services/data-gathering.service.ts @@ -549,19 +549,24 @@ export class DataGatheringService { } private async getSymbolsProfileData(): Promise { - const distinctOrders = await this.prismaService.order.findMany({ - distinct: ['symbol'], - orderBy: [{ symbol: 'asc' }], - select: { dataSource: true, symbol: true } + const symbolProfiles = await this.prismaService.symbolProfile.findMany({ + orderBy: [{ symbol: 'asc' }] }); - return distinctOrders.filter((distinctOrder) => { - return ( - distinctOrder.dataSource !== DataSource.GHOSTFOLIO && - distinctOrder.dataSource !== DataSource.MANUAL && - distinctOrder.dataSource !== DataSource.RAKUTEN - ); - }); + return symbolProfiles + .filter((symbolProfile) => { + return ( + symbolProfile.dataSource !== DataSource.GHOSTFOLIO && + symbolProfile.dataSource !== DataSource.MANUAL && + symbolProfile.dataSource !== DataSource.RAKUTEN + ); + }) + .map((symbolProfile) => { + return { + dataSource: symbolProfile.dataSource, + symbol: symbolProfile.symbol + }; + }); } private async isDataGatheringNeeded() { diff --git a/apps/api/src/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service.ts b/apps/api/src/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service.ts index dbc7dc97c..837dc2af3 100644 --- a/apps/api/src/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service.ts +++ b/apps/api/src/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service.ts @@ -7,11 +7,7 @@ import { } from '@ghostfolio/api/services/interfaces/interfaces'; import { PrismaService } from '@ghostfolio/api/services/prisma.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service'; -import { - DATE_FORMAT, - getYesterday, - isGhostfolioScraperApiSymbol -} from '@ghostfolio/common/helper'; +import { DATE_FORMAT, getYesterday } from '@ghostfolio/common/helper'; import { Granularity } from '@ghostfolio/common/types'; import { Injectable, Logger } from '@nestjs/common'; import { DataSource, SymbolProfile } from '@prisma/client'; @@ -29,7 +25,7 @@ export class GhostfolioScraperApiService implements DataProviderInterface { ) {} public canHandle(symbol: string) { - return isGhostfolioScraperApiSymbol(symbol); + return true; } public async getAssetProfile( diff --git a/apps/api/src/services/exchange-rate-data.service.ts b/apps/api/src/services/exchange-rate-data.service.ts index 8e639e7c0..53a6f0f6e 100644 --- a/apps/api/src/services/exchange-rate-data.service.ts +++ b/apps/api/src/services/exchange-rate-data.service.ts @@ -191,12 +191,7 @@ export class ExchangeRateDataService { await this.prismaService.symbolProfile.findMany({ distinct: ['currency'], orderBy: [{ currency: 'asc' }], - select: { currency: true }, - where: { - currency: { - not: null - } - } + select: { currency: true } }) ).forEach((symbolProfile) => { currencies.push(symbolProfile.currency); diff --git a/apps/client/src/app/pages/portfolio/transactions/create-or-update-transaction-dialog/create-or-update-transaction-dialog.component.ts b/apps/client/src/app/pages/portfolio/transactions/create-or-update-transaction-dialog/create-or-update-transaction-dialog.component.ts index 40c38bb95..134adcdc5 100644 --- a/apps/client/src/app/pages/portfolio/transactions/create-or-update-transaction-dialog/create-or-update-transaction-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/transactions/create-or-update-transaction-dialog/create-or-update-transaction-dialog.component.ts @@ -158,11 +158,11 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy { this.activityForm.controls['type'].disable(); } - if (this.data.activity?.symbol) { + if (this.data.activity?.SymbolProfile?.symbol) { this.dataService .fetchSymbolItem({ - dataSource: this.data.activity?.dataSource, - symbol: this.data.activity?.symbol + dataSource: this.data.activity?.SymbolProfile?.dataSource, + symbol: this.data.activity?.SymbolProfile?.symbol }) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(({ marketPrice }) => { @@ -196,9 +196,7 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy { } else { this.activityForm.controls['searchSymbol'].setErrors({ incorrect: true }); - this.data.activity.currency = null; - this.data.activity.dataSource = null; - this.data.activity.symbol = null; + this.data.activity.SymbolProfile = null; } this.changeDetectorRef.markForCheck(); @@ -259,9 +257,7 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy { }) .pipe( catchError(() => { - this.data.activity.currency = null; - this.data.activity.dataSource = null; - this.data.activity.unitPrice = null; + this.data.activity.SymbolProfile = null; this.isLoading = false; diff --git a/libs/common/src/lib/helper.ts b/libs/common/src/lib/helper.ts index dbfc787f3..e337493c7 100644 --- a/libs/common/src/lib/helper.ts +++ b/libs/common/src/lib/helper.ts @@ -102,10 +102,6 @@ export function isCurrency(aSymbol = '') { return currencies[aSymbol]; } -export function isGhostfolioScraperApiSymbol(aSymbol = '') { - return aSymbol.startsWith(ghostfolioScraperApiSymbolPrefix); -} - export function resetHours(aDate: Date) { const year = getYear(aDate); const month = getMonth(aDate); diff --git a/libs/ui/src/lib/activities-table/activities-table.component.html b/libs/ui/src/lib/activities-table/activities-table.component.html index 4cb943f55..3fecdd906 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.html +++ b/libs/ui/src/lib/activities-table/activities-table.component.html @@ -144,7 +144,7 @@ class="d-none d-lg-table-cell px-1" mat-cell > - {{ element.currency }} + {{ element.SymbolProfile.currency }} {{ baseCurrency }} @@ -362,7 +362,7 @@ !row.isDraft && row.type !== 'ITEM' && onOpenPositionDialog({ - dataSource: row.dataSource, + dataSource: row.SymbolProfile.dataSource, symbol: row.SymbolProfile.symbol }) " diff --git a/prisma/migrations/20220302184222_removed_data_source_from_order/migration.sql b/prisma/migrations/20220302184222_removed_data_source_from_order/migration.sql new file mode 100644 index 000000000..5c0f278c0 --- /dev/null +++ b/prisma/migrations/20220302184222_removed_data_source_from_order/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Order" DROP COLUMN "dataSource"; diff --git a/prisma/migrations/20220302191841_removed_currency_from_order/migration.sql b/prisma/migrations/20220302191841_removed_currency_from_order/migration.sql new file mode 100644 index 000000000..7ec887e9a --- /dev/null +++ b/prisma/migrations/20220302191841_removed_currency_from_order/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Order" DROP COLUMN "currency"; diff --git a/prisma/migrations/20220302193633_removed_symbol_from_order/migration.sql b/prisma/migrations/20220302193633_removed_symbol_from_order/migration.sql new file mode 100644 index 000000000..0a6026acb --- /dev/null +++ b/prisma/migrations/20220302193633_removed_symbol_from_order/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Order" DROP COLUMN "symbol"; diff --git a/prisma/migrations/20220302200727_changed_currency_to_required_in_symbol_profile/migration.sql b/prisma/migrations/20220302200727_changed_currency_to_required_in_symbol_profile/migration.sql new file mode 100644 index 000000000..158d9318a --- /dev/null +++ b/prisma/migrations/20220302200727_changed_currency_to_required_in_symbol_profile/migration.sql @@ -0,0 +1,5 @@ +-- Set default value +UPDATE "SymbolProfile" SET "currency" = 'USD' WHERE "currency" IS NULL; + +-- AlterTable +ALTER TABLE "SymbolProfile" ALTER COLUMN "currency" SET NOT NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index bea0e3381..738797ed6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -74,14 +74,11 @@ model Order { accountId String? accountUserId String? createdAt DateTime @default(now()) - currency String? - dataSource DataSource? date DateTime fee Float id String @default(uuid()) isDraft Boolean @default(false) quantity Float - symbol String? SymbolProfile SymbolProfile @relation(fields: [symbolProfileId], references: [id]) symbolProfileId String type Type @@ -119,7 +116,7 @@ model SymbolProfile { assetSubClass AssetSubClass? countries Json? createdAt DateTime @default(now()) - currency String? + currency String dataSource DataSource id String @id @default(uuid()) name String? diff --git a/prisma/seed.js b/prisma/seed.js index 3e4996a1e..d33d8b581 100644 --- a/prisma/seed.js +++ b/prisma/seed.js @@ -192,14 +192,11 @@ async function main() { { accountId: '65cfb79d-b6c7-4591-9d46-73426bc62094', accountUserId: userDemo.id, - currency: 'USD', - dataSource: DataSource.YAHOO, date: new Date(Date.UTC(2017, 0, 3, 0, 0, 0)), fee: 30, id: 'cf7c0418-8535-4089-ae3d-5dbfa0aec2e1', quantity: 50, - symbol: 'TSLA', - symbolProfileId: 'd1ee9681-fb21-4f99-a3b7-afd4fc04df2e', + symbolProfileId: 'd1ee9681-fb21-4f99-a3b7-afd4fc04df2e', // TSLA type: Type.BUY, unitPrice: 42.97, userId: userDemo.id @@ -207,14 +204,11 @@ async function main() { { accountId: 'd804de69-0429-42dc-b6ca-b308fd7dd926', accountUserId: userDemo.id, - currency: 'USD', - dataSource: DataSource.YAHOO, date: new Date(Date.UTC(2017, 7, 16, 0, 0, 0)), fee: 29.9, id: 'a1c5d73a-8631-44e5-ac44-356827a5212c', quantity: 0.5614682, - symbol: 'BTCUSD', - symbolProfileId: 'fdc42ea6-1321-44f5-9fb0-d7f1f2cf9b1e', + symbolProfileId: 'fdc42ea6-1321-44f5-9fb0-d7f1f2cf9b1e', // BTCUSD type: Type.BUY, unitPrice: 3562.089535970158, userId: userDemo.id @@ -222,14 +216,11 @@ async function main() { { accountId: '480269ce-e12a-4fd1-ac88-c4b0ff3f899c', accountUserId: userDemo.id, - currency: 'USD', - dataSource: DataSource.YAHOO, date: new Date(Date.UTC(2018, 9, 1, 0, 0, 0)), fee: 80.79, id: '71c08e2a-4a86-44ae-a890-c337de5d5f9b', quantity: 5, - symbol: 'AMZN', - symbolProfileId: '2bd26362-136e-411c-b578-334084b4cdcc', + symbolProfileId: '2bd26362-136e-411c-b578-334084b4cdcc', // AMZN type: Type.BUY, unitPrice: 2021.99, userId: userDemo.id @@ -237,14 +228,11 @@ async function main() { { accountId: '480269ce-e12a-4fd1-ac88-c4b0ff3f899c', accountUserId: userDemo.id, - currency: 'USD', - dataSource: DataSource.YAHOO, date: new Date(Date.UTC(2019, 2, 1, 0, 0, 0)), fee: 19.9, id: '385f2c2c-d53e-4937-b0e5-e92ef6020d4e', quantity: 10, - symbol: 'VTI', - symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', + symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', // VTI type: Type.BUY, unitPrice: 144.38, userId: userDemo.id @@ -252,14 +240,11 @@ async function main() { { accountId: '480269ce-e12a-4fd1-ac88-c4b0ff3f899c', accountUserId: userDemo.id, - currency: 'USD', - dataSource: DataSource.YAHOO, date: new Date(Date.UTC(2019, 8, 3, 0, 0, 0)), fee: 19.9, id: '185f2c2c-d53e-4937-b0e5-a93ef6020d4e', quantity: 10, - symbol: 'VTI', - symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', + symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', // VTI type: Type.BUY, unitPrice: 147.99, userId: userDemo.id @@ -267,14 +252,11 @@ async function main() { { accountId: '480269ce-e12a-4fd1-ac88-c4b0ff3f899c', accountUserId: userDemo.id, - currency: 'USD', - dataSource: DataSource.YAHOO, date: new Date(Date.UTC(2020, 2, 2, 0, 0, 0)), fee: 19.9, id: '347b0430-a84f-4031-a0f9-390399066ad6', quantity: 10, - symbol: 'VTI', - symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', + symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', // VTI type: Type.BUY, unitPrice: 151.41, userId: userDemo.id @@ -282,14 +264,11 @@ async function main() { { accountId: '480269ce-e12a-4fd1-ac88-c4b0ff3f899c', accountUserId: userDemo.id, - currency: 'USD', - dataSource: DataSource.YAHOO, date: new Date(Date.UTC(2020, 8, 1, 0, 0, 0)), fee: 19.9, id: '67ec3f47-3189-4b63-ba05-60d3a06b302f', quantity: 10, - symbol: 'VTI', - symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', + symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', // VTI type: Type.BUY, unitPrice: 177.69, userId: userDemo.id @@ -297,14 +276,11 @@ async function main() { { accountId: '480269ce-e12a-4fd1-ac88-c4b0ff3f899c', accountUserId: userDemo.id, - currency: 'USD', - dataSource: DataSource.YAHOO, date: new Date(Date.UTC(2020, 2, 1, 0, 0, 0)), fee: 19.9, id: 'd01c6fbc-fa8d-47e6-8e80-66f882d2bfd2', quantity: 10, - symbol: 'VTI', - symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', + symbolProfileId: '7d9c8540-061e-4e7e-b019-0d0f4a84e796', // VTI type: Type.BUY, unitPrice: 203.15, userId: userDemo.id