|
|
|
@ -17,6 +17,7 @@ import {
|
|
|
|
|
Filter,
|
|
|
|
|
UniqueAsset
|
|
|
|
|
} from '@ghostfolio/common/interfaces';
|
|
|
|
|
import { MarketDataQuery } from '@ghostfolio/common/types';
|
|
|
|
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
|
|
|
|
import { AssetSubClass, Prisma, Property, SymbolProfile } from '@prisma/client';
|
|
|
|
|
import { differenceInDays } from 'date-fns';
|
|
|
|
@ -103,12 +104,14 @@ export class AdminService {
|
|
|
|
|
|
|
|
|
|
public async getMarketData({
|
|
|
|
|
filters,
|
|
|
|
|
queryId,
|
|
|
|
|
sortColumn,
|
|
|
|
|
sortDirection,
|
|
|
|
|
skip,
|
|
|
|
|
take = DEFAULT_PAGE_SIZE
|
|
|
|
|
take = Number.MAX_SAFE_INTEGER
|
|
|
|
|
}: {
|
|
|
|
|
filters?: Filter[];
|
|
|
|
|
queryId?: MarketDataQuery;
|
|
|
|
|
skip?: number;
|
|
|
|
|
sortColumn?: string;
|
|
|
|
|
sortDirection?: Prisma.SortOrder;
|
|
|
|
@ -118,6 +121,13 @@ export class AdminService {
|
|
|
|
|
[{ symbol: 'asc' }];
|
|
|
|
|
const where: Prisma.SymbolProfileWhereInput = {};
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
queryId === 'ETF_WITHOUT_COUNTRIES' ||
|
|
|
|
|
queryId === 'ETF_WITHOUT_SECTORS'
|
|
|
|
|
) {
|
|
|
|
|
filters = [{ id: 'ETF', type: 'ASSET_SUB_CLASS' }];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { ASSET_SUB_CLASS: filtersByAssetSubClass } = groupBy(
|
|
|
|
|
filters,
|
|
|
|
|
(filter) => {
|
|
|
|
@ -146,7 +156,7 @@ export class AdminService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const [assetProfiles, count] = await Promise.all([
|
|
|
|
|
let [assetProfiles, count] = await Promise.all([
|
|
|
|
|
this.prismaService.symbolProfile.findMany({
|
|
|
|
|
orderBy,
|
|
|
|
|
skip,
|
|
|
|
@ -174,44 +184,60 @@ export class AdminService {
|
|
|
|
|
this.prismaService.symbolProfile.count({ where })
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
count,
|
|
|
|
|
marketData: assetProfiles.map(
|
|
|
|
|
({
|
|
|
|
|
_count,
|
|
|
|
|
let marketData = assetProfiles.map(
|
|
|
|
|
({
|
|
|
|
|
_count,
|
|
|
|
|
assetClass,
|
|
|
|
|
assetSubClass,
|
|
|
|
|
comment,
|
|
|
|
|
countries,
|
|
|
|
|
dataSource,
|
|
|
|
|
Order,
|
|
|
|
|
sectors,
|
|
|
|
|
symbol
|
|
|
|
|
}) => {
|
|
|
|
|
const countriesCount = countries ? Object.keys(countries).length : 0;
|
|
|
|
|
const marketDataItemCount =
|
|
|
|
|
marketDataItems.find((marketDataItem) => {
|
|
|
|
|
return (
|
|
|
|
|
marketDataItem.dataSource === dataSource &&
|
|
|
|
|
marketDataItem.symbol === symbol
|
|
|
|
|
);
|
|
|
|
|
})?._count ?? 0;
|
|
|
|
|
const sectorsCount = sectors ? Object.keys(sectors).length : 0;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
assetClass,
|
|
|
|
|
assetSubClass,
|
|
|
|
|
comment,
|
|
|
|
|
countries,
|
|
|
|
|
countriesCount,
|
|
|
|
|
dataSource,
|
|
|
|
|
Order,
|
|
|
|
|
sectors,
|
|
|
|
|
symbol
|
|
|
|
|
}) => {
|
|
|
|
|
const countriesCount = countries ? Object.keys(countries).length : 0;
|
|
|
|
|
const marketDataItemCount =
|
|
|
|
|
marketDataItems.find((marketDataItem) => {
|
|
|
|
|
return (
|
|
|
|
|
marketDataItem.dataSource === dataSource &&
|
|
|
|
|
marketDataItem.symbol === symbol
|
|
|
|
|
);
|
|
|
|
|
})?._count ?? 0;
|
|
|
|
|
const sectorsCount = sectors ? Object.keys(sectors).length : 0;
|
|
|
|
|
symbol,
|
|
|
|
|
marketDataItemCount,
|
|
|
|
|
sectorsCount,
|
|
|
|
|
activitiesCount: _count.Order,
|
|
|
|
|
date: Order?.[0]?.date
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
assetClass,
|
|
|
|
|
assetSubClass,
|
|
|
|
|
comment,
|
|
|
|
|
countriesCount,
|
|
|
|
|
dataSource,
|
|
|
|
|
symbol,
|
|
|
|
|
marketDataItemCount,
|
|
|
|
|
sectorsCount,
|
|
|
|
|
activitiesCount: _count.Order,
|
|
|
|
|
date: Order?.[0]?.date
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
if (queryId) {
|
|
|
|
|
if (queryId === 'ETF_WITHOUT_COUNTRIES') {
|
|
|
|
|
marketData = marketData.filter(({ countriesCount }) => {
|
|
|
|
|
return countriesCount === 0;
|
|
|
|
|
});
|
|
|
|
|
} else if (queryId === 'ETF_WITHOUT_SECTORS') {
|
|
|
|
|
marketData = marketData.filter(({ sectorsCount }) => {
|
|
|
|
|
return sectorsCount === 0;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
count = marketData.length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
count,
|
|
|
|
|
marketData
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|