Browse Source

Move to import controller

pull/1560/head
Thomas 3 years ago
parent
commit
d0093b4a08
  1. 32
      apps/api/src/app/import/import.controller.ts
  2. 4
      apps/api/src/app/import/import.module.ts
  3. 62
      apps/api/src/app/import/import.service.ts
  4. 23
      apps/api/src/app/symbol/symbol.controller.ts
  5. 4
      apps/api/src/app/symbol/symbol.module.ts
  6. 63
      apps/api/src/app/symbol/symbol.service.ts
  7. 2
      apps/client/src/app/services/data.service.ts

32
apps/api/src/app/import/import.controller.ts

@ -1,19 +1,26 @@
import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request.interceptor';
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response.interceptor';
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
import { ImportResponse } from '@ghostfolio/common/interfaces';
import type { RequestWithUser } from '@ghostfolio/common/types';
import {
Body,
Controller,
Get,
HttpException,
Inject,
Logger,
Param,
Post,
Query,
UseGuards
UseGuards,
UseInterceptors
} from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import { DataSource } from '@prisma/client';
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { isEmpty } from 'lodash';
import { ImportDataDto } from './import-data.dto';
import { ImportService } from './import.service';
@ -74,4 +81,27 @@ export class ImportController {
);
}
}
@Get('dividends/:dataSource/:symbol')
@UseGuards(AuthGuard('jwt'))
@UseInterceptors(TransformDataSourceInRequestInterceptor)
@UseInterceptors(TransformDataSourceInResponseInterceptor)
public async gatherDividends(
@Param('dataSource') dataSource: DataSource,
@Param('symbol') symbol: string
): Promise<ImportResponse> {
const result = await this.importService.getDividends({
dataSource,
symbol
});
if (!result || isEmpty(result)) {
throw new HttpException(
getReasonPhrase(StatusCodes.NOT_FOUND),
StatusCodes.NOT_FOUND
);
}
return result;
}
}

4
apps/api/src/app/import/import.module.ts

@ -7,6 +7,7 @@ import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering.mod
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data.module';
import { PrismaModule } from '@ghostfolio/api/services/prisma.module';
import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile.module';
import { Module } from '@nestjs/common';
import { ImportController } from './import.controller';
@ -23,7 +24,8 @@ import { ImportService } from './import.service';
ExchangeRateDataModule,
OrderModule,
PrismaModule,
RedisCacheModule
RedisCacheModule,
SymbolProfileModule
],
providers: [ImportService]
})

62
apps/api/src/app/import/import.service.ts

@ -4,11 +4,14 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interf
import { OrderService } from '@ghostfolio/api/app/order/order.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
import { parseDate } from '@ghostfolio/common/helper';
import { ImportResponse, UniqueAsset } from '@ghostfolio/common/interfaces';
import { OrderWithAccount } from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common';
import { SymbolProfile } from '@prisma/client';
import Big from 'big.js';
import { endOfToday, isAfter, isSameDay, parseISO } from 'date-fns';
import { endOfToday, isAfter, isSameDay, parseISO, subYears } from 'date-fns';
import { v4 as uuidv4 } from 'uuid';
@Injectable()
@ -17,9 +20,64 @@ export class ImportService {
private readonly accountService: AccountService,
private readonly dataProviderService: DataProviderService,
private readonly exchangeRateDataService: ExchangeRateDataService,
private readonly orderService: OrderService
private readonly orderService: OrderService,
private readonly symbolProfileService: SymbolProfileService
) {}
public async getDividends({
dataSource,
symbol
}: UniqueAsset): Promise<ImportResponse> {
try {
const date = new Date();
const [[assetProfile], historicalData] = await Promise.all([
this.symbolProfileService.getSymbolProfiles([
{
dataSource,
symbol
}
]),
await this.dataProviderService.getDividends({
dataSource,
symbol,
from: subYears(date, 5),
granularity: 'day',
to: date
})
]);
return {
activities: Object.entries(historicalData).map(
([dateString, historicalDataItem]) => {
return {
accountId: undefined,
accountUserId: undefined,
comment: undefined,
createdAt: undefined,
date: parseDate(dateString),
fee: 0,
feeInBaseCurrency: 0,
id: assetProfile.id,
isDraft: false,
quantity: 0,
SymbolProfile: <SymbolProfile>(<unknown>assetProfile),
symbolProfileId: undefined,
type: 'DIVIDEND',
unitPrice: historicalDataItem.marketPrice,
updatedAt: undefined,
userId: undefined,
value: 0,
valueInBaseCurrency: 0
};
}
)
};
} catch {
return { activities: [] };
}
}
public async import({
activitiesDto,
isDryRun = false,

23
apps/api/src/app/symbol/symbol.controller.ts

@ -76,29 +76,6 @@ export class SymbolController {
return result;
}
@Get(':dataSource/:symbol/dividends')
@UseGuards(AuthGuard('jwt'))
@UseInterceptors(TransformDataSourceInRequestInterceptor)
@UseInterceptors(TransformDataSourceInResponseInterceptor)
public async gatherDividends(
@Param('dataSource') dataSource: DataSource,
@Param('symbol') symbol: string
): Promise<ImportResponse> {
const result = await this.symbolService.getDividends({
dataSource,
symbol
});
if (!result || isEmpty(result)) {
throw new HttpException(
getReasonPhrase(StatusCodes.NOT_FOUND),
StatusCodes.NOT_FOUND
);
}
return result;
}
@Get(':dataSource/:symbol/:dateString')
@UseGuards(AuthGuard('jwt'))
public async gatherSymbolForDate(

4
apps/api/src/app/symbol/symbol.module.ts

@ -2,7 +2,6 @@ import { ConfigurationModule } from '@ghostfolio/api/services/configuration.modu
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { MarketDataModule } from '@ghostfolio/api/services/market-data.module';
import { PrismaModule } from '@ghostfolio/api/services/prisma.module';
import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile.module';
import { Module } from '@nestjs/common';
import { SymbolController } from './symbol.controller';
@ -15,8 +14,7 @@ import { SymbolService } from './symbol.service';
ConfigurationModule,
DataProviderModule,
MarketDataModule,
PrismaModule,
SymbolProfileModule
PrismaModule
],
providers: [SymbolService]
})

63
apps/api/src/app/symbol/symbol.service.ts

@ -4,15 +4,13 @@ import {
IDataProviderHistoricalResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
import {
HistoricalDataItem,
ImportResponse
} from '@ghostfolio/common/interfaces';
import { Injectable, Logger } from '@nestjs/common';
import { SymbolProfile } from '@prisma/client';
import { format, subDays, subYears } from 'date-fns';
import { format, subDays } from 'date-fns';
import { LookupItem } from './interfaces/lookup-item.interface';
import { SymbolItem } from './interfaces/symbol-item.interface';
@ -21,8 +19,7 @@ import { SymbolItem } from './interfaces/symbol-item.interface';
export class SymbolService {
public constructor(
private readonly dataProviderService: DataProviderService,
private readonly marketDataService: MarketDataService,
private readonly symbolProfileService: SymbolProfileService
private readonly marketDataService: MarketDataService
) {}
public async get({
@ -68,60 +65,6 @@ export class SymbolService {
return undefined;
}
public async getDividends({
dataSource,
symbol
}: IDataGatheringItem): Promise<ImportResponse> {
try {
const date = new Date();
const [[assetProfile], historicalData] = await Promise.all([
this.symbolProfileService.getSymbolProfiles([
{
dataSource,
symbol
}
]),
await this.dataProviderService.getDividends({
dataSource,
symbol,
from: subYears(date, 5),
granularity: 'day',
to: date
})
]);
return {
activities: Object.entries(historicalData).map(
([dateString, historicalDataItem]) => {
return {
accountId: undefined,
accountUserId: undefined,
comment: undefined,
createdAt: undefined,
date: parseDate(dateString),
fee: 0,
feeInBaseCurrency: 0,
id: assetProfile.id,
isDraft: false,
quantity: 0,
SymbolProfile: <SymbolProfile>(<unknown>assetProfile),
symbolProfileId: undefined,
type: 'DIVIDEND',
unitPrice: historicalDataItem.marketPrice,
updatedAt: undefined,
userId: undefined,
value: 0,
valueInBaseCurrency: 0
};
}
)
};
} catch {
return { activities: [] };
}
}
public async getForDate({
dataSource,
date = new Date(),

2
apps/client/src/app/services/data.service.ts

@ -122,7 +122,7 @@ export class DataService {
public fetchDividendsImport({ dataSource, symbol }: UniqueAsset) {
return this.http.get<ImportResponse>(
`/api/v1/symbol/${dataSource}/${symbol}/dividends`
`/api/v1/import/dividends/${dataSource}/${symbol}`
);
}

Loading…
Cancel
Save