Feature/add symbol profile overrides model (#851)

* Add symbol profile overrides model

* Update changelog
pull/852/head
Thomas Kaul 2 years ago committed by GitHub
parent beb12637ce
commit 1b03ddc586
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Added support for sub-labels in the value component - Added support for sub-labels in the value component
- Added a symbol profile overrides model for manual adjustments
### Changed ### Changed
@ -21,6 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed the calculation of the total value for sell and dividend activities in the create or edit transaction dialog - Fixed the calculation of the total value for sell and dividend activities in the create or edit transaction dialog
### Todo
- Apply data migration (`yarn database:migrate`)
## 1.139.0 - 18.04.2022 ## 1.139.0 - 18.04.2022
### Added ### Added

@ -4,7 +4,12 @@ import { UNKNOWN_KEY } from '@ghostfolio/common/config';
import { Country } from '@ghostfolio/common/interfaces/country.interface'; import { Country } from '@ghostfolio/common/interfaces/country.interface';
import { Sector } from '@ghostfolio/common/interfaces/sector.interface'; import { Sector } from '@ghostfolio/common/interfaces/sector.interface';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { DataSource, Prisma, SymbolProfile } from '@prisma/client'; import {
DataSource,
Prisma,
SymbolProfile,
SymbolProfileOverrides
} from '@prisma/client';
import { continents, countries } from 'countries-list'; import { continents, countries } from 'countries-list';
import { ScraperConfiguration } from './data-provider/ghostfolio-scraper-api/interfaces/scraper-configuration.interface'; import { ScraperConfiguration } from './data-provider/ghostfolio-scraper-api/interfaces/scraper-configuration.interface';
@ -36,6 +41,7 @@ export class SymbolProfileService {
): Promise<EnhancedSymbolProfile[]> { ): Promise<EnhancedSymbolProfile[]> {
return this.prismaService.symbolProfile return this.prismaService.symbolProfile
.findMany({ .findMany({
include: { SymbolProfileOverrides: true },
where: { where: {
symbol: { symbol: {
in: symbols in: symbols
@ -45,14 +51,38 @@ export class SymbolProfileService {
.then((symbolProfiles) => this.getSymbols(symbolProfiles)); .then((symbolProfiles) => this.getSymbols(symbolProfiles));
} }
private getSymbols(symbolProfiles: SymbolProfile[]): EnhancedSymbolProfile[] { private getSymbols(
return symbolProfiles.map((symbolProfile) => ({ symbolProfiles: (SymbolProfile & {
...symbolProfile, SymbolProfileOverrides: SymbolProfileOverrides;
countries: this.getCountries(symbolProfile), })[]
scraperConfiguration: this.getScraperConfiguration(symbolProfile), ): EnhancedSymbolProfile[] {
sectors: this.getSectors(symbolProfile), return symbolProfiles.map((symbolProfile) => {
symbolMapping: this.getSymbolMapping(symbolProfile) const item = {
})); ...symbolProfile,
countries: this.getCountries(symbolProfile),
scraperConfiguration: this.getScraperConfiguration(symbolProfile),
sectors: this.getSectors(symbolProfile),
symbolMapping: this.getSymbolMapping(symbolProfile)
};
if (item.SymbolProfileOverrides) {
item.assetClass =
item.SymbolProfileOverrides.assetClass ?? item.assetClass;
item.assetSubClass =
item.SymbolProfileOverrides.assetSubClass ?? item.assetSubClass;
item.countries =
(item.SymbolProfileOverrides.sectors as unknown as Country[]) ??
item.countries;
item.name = item.SymbolProfileOverrides?.name ?? item.name;
item.sectors =
(item.SymbolProfileOverrides.sectors as unknown as Sector[]) ??
item.sectors;
delete item.SymbolProfileOverrides;
}
return item;
});
} }
private getCountries(symbolProfile: SymbolProfile): Country[] { private getCountries(symbolProfile: SymbolProfile): Country[] {

@ -0,0 +1,15 @@
-- CreateTable
CREATE TABLE "SymbolProfileOverrides" (
"assetClass" "AssetClass",
"assetSubClass" "AssetSubClass",
"countries" JSONB,
"name" TEXT,
"sectors" JSONB,
"symbolProfileId" TEXT NOT NULL,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "SymbolProfileOverrides_pkey" PRIMARY KEY ("symbolProfileId")
);
-- AddForeignKey
ALTER TABLE "SymbolProfileOverrides" ADD CONSTRAINT "SymbolProfileOverrides_symbolProfileId_fkey" FOREIGN KEY ("symbolProfileId") REFERENCES "SymbolProfile"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

@ -0,0 +1,2 @@
-- AlterEnum
ALTER TYPE "AssetSubClass" ADD VALUE 'COMMODITY';

@ -112,25 +112,37 @@ model Settings {
} }
model SymbolProfile { model SymbolProfile {
assetClass AssetClass? assetClass AssetClass?
assetSubClass AssetSubClass? assetSubClass AssetSubClass?
countries Json? countries Json?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
currency String currency String
dataSource DataSource dataSource DataSource
id String @id @default(uuid()) id String @id @default(uuid())
name String? name String?
Order Order[] Order Order[]
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
scraperConfiguration Json? scraperConfiguration Json?
sectors Json? sectors Json?
symbol String symbol String
symbolMapping Json? symbolMapping Json?
url String? SymbolProfileOverrides SymbolProfileOverrides?
url String?
@@unique([dataSource, symbol]) @@unique([dataSource, symbol])
} }
model SymbolProfileOverrides {
assetClass AssetClass?
assetSubClass AssetSubClass?
countries Json?
name String?
sectors Json?
SymbolProfile SymbolProfile @relation(fields: [symbolProfileId], references: [id])
symbolProfileId String @id
updatedAt DateTime @updatedAt
}
model Subscription { model Subscription {
createdAt DateTime @default(now()) createdAt DateTime @default(now())
expiresAt DateTime expiresAt DateTime
@ -176,6 +188,7 @@ enum AssetClass {
enum AssetSubClass { enum AssetSubClass {
BOND BOND
COMMODITY
CRYPTOCURRENCY CRYPTOCURRENCY
ETF ETF
MUTUALFUND MUTUALFUND

Loading…
Cancel
Save