diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 915c2068e..a985f92ef 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -102,9 +102,17 @@ export class AdminService { ); } - return this.symbolProfileService.add( - assetProfile as Prisma.SymbolProfileCreateInput - ); + const symbolOfAssetProfile = + await this.symbolProfileService.getSymbolOfAssetProfile({ + dataSource, + symbol, + symbolOfDataProvider: assetProfile.symbol + }); + + return this.symbolProfileService.add({ + ...assetProfile, + symbol: symbolOfAssetProfile + } as Prisma.SymbolProfileCreateInput); } catch (error) { if ( error instanceof Prisma.PrismaClientKnownRequestError && diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 02e4f3e72..388a1885b 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -748,7 +748,16 @@ export class ImportService { const assetProfile = assetProfiles[getAssetProfileIdentifier({ dataSource, symbol })]; - if (assetProfile) { + const assetProfileInImport = assetProfilesWithMarketDataDto?.some( + (assetProfileWithMarketData) => { + return ( + assetProfileWithMarketData.dataSource === dataSource && + assetProfileWithMarketData.symbol === symbol + ); + } + ); + + if (assetProfile && !assetProfileInImport) { assetProfile.symbol = await this.symbolProfileService.getSymbolOfAssetProfile({ dataSource, diff --git a/apps/api/src/services/symbol-profile/symbol-profile.service.spec.ts b/apps/api/src/services/symbol-profile/symbol-profile.service.spec.ts index 757deafef..6e61583db 100644 --- a/apps/api/src/services/symbol-profile/symbol-profile.service.spec.ts +++ b/apps/api/src/services/symbol-profile/symbol-profile.service.spec.ts @@ -58,6 +58,20 @@ describe('SymbolProfileService', () => { expect(symbol).toEqual('aapl'); }); + it('Ignores an asset profile which a wildcard of the query matched', async () => { + prismaService.symbolProfile.findMany.mockResolvedValue([ + { symbol: 'AAPL' } + ]); + + const symbol = await symbolProfileService.getSymbolOfAssetProfile({ + dataSource: DataSource.YAHOO, + symbol: 'aa_l', + symbolOfDataProvider: 'AA_L' + }); + + expect(symbol).toEqual('AA_L'); + }); + it('Uses the symbol of the data provider if no asset profile exists', async () => { const symbol = await symbolProfileService.getSymbolOfAssetProfile({ dataSource: DataSource.YAHOO, diff --git a/apps/api/src/services/symbol-profile/symbol-profile.service.ts b/apps/api/src/services/symbol-profile/symbol-profile.service.ts index ac1edc9ad..1afbce69a 100644 --- a/apps/api/src/services/symbol-profile/symbol-profile.service.ts +++ b/apps/api/src/services/symbol-profile/symbol-profile.service.ts @@ -1,6 +1,9 @@ import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { UNKNOWN_KEY } from '@ghostfolio/common/config'; -import { applyAssetProfileOverrides } from '@ghostfolio/common/helper'; +import { + applyAssetProfileOverrides, + isSameSymbol +} from '@ghostfolio/common/helper'; import { AssetProfileIdentifier, EnhancedAssetProfile, @@ -140,13 +143,17 @@ export class SymbolProfileService { return symbol; } - const symbolProfiles = await this.prismaService.symbolProfile.findMany({ - orderBy: { symbol: 'asc' }, - select: { symbol: true }, - where: { - dataSource, - symbol: { equals: symbol, mode: 'insensitive' } - } + const symbolProfiles = ( + await this.prismaService.symbolProfile.findMany({ + orderBy: { symbol: 'asc' }, + select: { symbol: true }, + where: { + dataSource, + symbol: { equals: symbol, mode: 'insensitive' } + } + }) + ).filter(({ symbol: symbolOfSymbolProfile }) => { + return isSameSymbol({ symbol1: symbol, symbol2: symbolOfSymbolProfile }); }); const symbolProfile =