Add data source to transaction model (#53)
This commit is contained in:
parent
2d04d7b8d5
commit
40c95a541d
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## 0.95.0 - 28.04.2021
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added a data source attribute to the transactions model
|
||||||
|
|
||||||
## 0.94.0 - 27.04.2021
|
## 0.94.0 - 27.04.2021
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -39,6 +39,7 @@ export class ExperimentalService {
|
|||||||
accountId: undefined,
|
accountId: undefined,
|
||||||
accountUserId: undefined,
|
accountUserId: undefined,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
|
dataSource: undefined,
|
||||||
date: parseISO(order.date),
|
date: parseISO(order.date),
|
||||||
fee: 0,
|
fee: 0,
|
||||||
id: undefined,
|
id: undefined,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Currency, Type } from '@prisma/client';
|
import { Currency, DataSource, Type } from '@prisma/client';
|
||||||
import { IsISO8601, IsNumber, IsString, ValidateIf } from 'class-validator';
|
import { IsISO8601, IsNumber, IsString, ValidateIf } from 'class-validator';
|
||||||
|
|
||||||
export class CreateOrderDto {
|
export class CreateOrderDto {
|
||||||
@ -8,6 +8,9 @@ export class CreateOrderDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
currency: Currency;
|
currency: Currency;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
dataSource: DataSource;
|
||||||
|
|
||||||
@IsISO8601()
|
@IsISO8601()
|
||||||
date: string;
|
date: string;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Currency, Type } from '@prisma/client';
|
import { Currency, DataSource, Type } from '@prisma/client';
|
||||||
import { IsISO8601, IsNumber, IsString, ValidateIf } from 'class-validator';
|
import { IsISO8601, IsNumber, IsString, ValidateIf } from 'class-validator';
|
||||||
|
|
||||||
export class UpdateOrderDto {
|
export class UpdateOrderDto {
|
||||||
@ -8,6 +8,9 @@ export class UpdateOrderDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
currency: Currency;
|
currency: Currency;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
dataSource: DataSource;
|
||||||
|
|
||||||
@IsISO8601()
|
@IsISO8601()
|
||||||
date: string;
|
date: string;
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
import { Currency } from '@prisma/client';
|
||||||
|
|
||||||
export interface PortfolioPositionDetail {
|
export interface PortfolioPositionDetail {
|
||||||
averagePrice: number;
|
averagePrice: number;
|
||||||
currency: string;
|
currency: Currency;
|
||||||
firstBuyDate: string;
|
firstBuyDate: string;
|
||||||
grossPerformance: number;
|
grossPerformance: number;
|
||||||
grossPerformancePercent: number;
|
grossPerformancePercent: number;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Currency } from '@prisma/client';
|
import { Currency, DataSource } from '@prisma/client';
|
||||||
|
|
||||||
export interface SymbolItem {
|
export interface SymbolItem {
|
||||||
currency: Currency;
|
currency: Currency;
|
||||||
|
dataSource: DataSource;
|
||||||
marketPrice: number;
|
marketPrice: number;
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,10 @@ export class SymbolService {
|
|||||||
|
|
||||||
public async get(aSymbol: string): Promise<SymbolItem> {
|
public async get(aSymbol: string): Promise<SymbolItem> {
|
||||||
const response = await this.dataProviderService.get([aSymbol]);
|
const response = await this.dataProviderService.get([aSymbol]);
|
||||||
const { currency, marketPrice } = response[aSymbol];
|
const { currency, dataSource, marketPrice } = response[aSymbol];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
dataSource,
|
||||||
marketPrice,
|
marketPrice,
|
||||||
currency: <Currency>(<unknown>currency)
|
currency: <Currency>(<unknown>currency)
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { DataSource } from '.prisma/client';
|
||||||
import { getYesterday } from '@ghostfolio/helper';
|
import { getYesterday } from '@ghostfolio/helper';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import * as bent from 'bent';
|
import * as bent from 'bent';
|
||||||
@ -45,6 +46,7 @@ export class GhostfolioScraperApiService implements DataProviderInterface {
|
|||||||
[symbol]: {
|
[symbol]: {
|
||||||
marketPrice,
|
marketPrice,
|
||||||
currency: scraperConfig?.currency,
|
currency: scraperConfig?.currency,
|
||||||
|
dataSource: DataSource.GHOSTFOLIO,
|
||||||
marketState: MarketState.delayed,
|
marketState: MarketState.delayed,
|
||||||
name: scraperConfig?.name
|
name: scraperConfig?.name
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { DataSource } from '.prisma/client';
|
||||||
import { getToday, getYesterday } from '@ghostfolio/helper';
|
import { getToday, getYesterday } from '@ghostfolio/helper';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import * as bent from 'bent';
|
import * as bent from 'bent';
|
||||||
@ -39,6 +40,7 @@ export class RakutenRapidApiService implements DataProviderInterface {
|
|||||||
return {
|
return {
|
||||||
'GF.FEAR_AND_GREED_INDEX': {
|
'GF.FEAR_AND_GREED_INDEX': {
|
||||||
currency: undefined,
|
currency: undefined,
|
||||||
|
dataSource: DataSource.RAKUTEN,
|
||||||
marketPrice: fgi.now.value,
|
marketPrice: fgi.now.value,
|
||||||
marketState: MarketState.open,
|
marketState: MarketState.open,
|
||||||
name: RakutenRapidApiService.FEAR_AND_GREED_INDEX_NAME
|
name: RakutenRapidApiService.FEAR_AND_GREED_INDEX_NAME
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { DataSource } from '.prisma/client';
|
||||||
import { isCrypto, isCurrency, parseCurrency } from '@ghostfolio/helper';
|
import { isCrypto, isCurrency, parseCurrency } from '@ghostfolio/helper';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
@ -49,6 +50,7 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
|
|
||||||
response[symbol] = {
|
response[symbol] = {
|
||||||
currency: parseCurrency(value.price?.currency),
|
currency: parseCurrency(value.price?.currency),
|
||||||
|
dataSource: DataSource.YAHOO,
|
||||||
exchange: this.parseExchange(value.price?.exchangeName),
|
exchange: this.parseExchange(value.price?.exchangeName),
|
||||||
marketState:
|
marketState:
|
||||||
value.price?.marketState === 'REGULAR' || isCrypto(symbol)
|
value.price?.marketState === 'REGULAR' || isCrypto(symbol)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Currency, Platform } from '@prisma/client';
|
import { Currency, DataSource, Platform } from '@prisma/client';
|
||||||
|
|
||||||
import { OrderType } from '../../models/order-type';
|
import { OrderType } from '../../models/order-type';
|
||||||
|
|
||||||
@ -51,6 +51,7 @@ export interface IDataProviderHistoricalResponse {
|
|||||||
|
|
||||||
export interface IDataProviderResponse {
|
export interface IDataProviderResponse {
|
||||||
currency: Currency;
|
currency: Currency;
|
||||||
|
dataSource: DataSource;
|
||||||
exchange?: string;
|
exchange?: string;
|
||||||
industry?: Industry;
|
industry?: Industry;
|
||||||
marketChange?: number;
|
marketChange?: number;
|
||||||
|
@ -78,8 +78,9 @@ export class CreateOrUpdateTransactionDialog {
|
|||||||
this.dataService
|
this.dataService
|
||||||
.fetchSymbolItem(this.data.transaction.symbol)
|
.fetchSymbolItem(this.data.transaction.symbol)
|
||||||
.pipe(takeUntil(this.unsubscribeSubject))
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
.subscribe(({ currency, marketPrice }) => {
|
.subscribe(({ currency, dataSource, marketPrice }) => {
|
||||||
this.data.transaction.currency = currency;
|
this.data.transaction.currency = currency;
|
||||||
|
this.data.transaction.dataSource = dataSource;
|
||||||
this.data.transaction.unitPrice = marketPrice;
|
this.data.transaction.unitPrice = marketPrice;
|
||||||
|
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
@ -90,6 +91,7 @@ export class CreateOrUpdateTransactionDialog {
|
|||||||
|
|
||||||
public onUpdateSymbolByTyping(value: string) {
|
public onUpdateSymbolByTyping(value: string) {
|
||||||
this.data.transaction.currency = null;
|
this.data.transaction.currency = null;
|
||||||
|
this.data.transaction.dataSource = null;
|
||||||
this.data.transaction.unitPrice = null;
|
this.data.transaction.unitPrice = null;
|
||||||
|
|
||||||
this.data.transaction.symbol = value;
|
this.data.transaction.symbol = value;
|
||||||
|
@ -58,6 +58,18 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="d-none">
|
||||||
|
<mat-form-field appearance="outline" class="w-100">
|
||||||
|
<mat-label i18n>Data Source</mat-label>
|
||||||
|
<input
|
||||||
|
disabled
|
||||||
|
matInput
|
||||||
|
name="dataSource"
|
||||||
|
required
|
||||||
|
[(ngModel)]="data.transaction.dataSource"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<mat-form-field appearance="outline" class="w-100">
|
<mat-form-field appearance="outline" class="w-100">
|
||||||
<mat-label i18n>Date</mat-label>
|
<mat-label i18n>Date</mat-label>
|
||||||
@ -113,6 +125,7 @@
|
|||||||
<mat-form-field appearance="outline" class="w-100">
|
<mat-form-field appearance="outline" class="w-100">
|
||||||
<mat-label i18n>Account</mat-label>
|
<mat-label i18n>Account</mat-label>
|
||||||
<mat-select
|
<mat-select
|
||||||
|
disabled
|
||||||
name="accountId"
|
name="accountId"
|
||||||
required
|
required
|
||||||
[(value)]="data.transaction.accountId"
|
[(value)]="data.transaction.accountId"
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
import { Currency, DataSource } from '.prisma/client';
|
||||||
|
|
||||||
export interface Order {
|
export interface Order {
|
||||||
accountId: string;
|
accountId: string;
|
||||||
currency: string;
|
currency: Currency;
|
||||||
|
dataSource: DataSource;
|
||||||
date: Date;
|
date: Date;
|
||||||
fee: number;
|
fee: number;
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -125,6 +125,7 @@ export class TransactionsPageComponent implements OnInit {
|
|||||||
public openUpdateTransactionDialog({
|
public openUpdateTransactionDialog({
|
||||||
accountId,
|
accountId,
|
||||||
currency,
|
currency,
|
||||||
|
dataSource,
|
||||||
date,
|
date,
|
||||||
fee,
|
fee,
|
||||||
id,
|
id,
|
||||||
@ -140,6 +141,7 @@ export class TransactionsPageComponent implements OnInit {
|
|||||||
transaction: {
|
transaction: {
|
||||||
accountId,
|
accountId,
|
||||||
currency,
|
currency,
|
||||||
|
dataSource,
|
||||||
date,
|
date,
|
||||||
fee,
|
fee,
|
||||||
id,
|
id,
|
||||||
@ -177,9 +179,9 @@ export class TransactionsPageComponent implements OnInit {
|
|||||||
private openCreateTransactionDialog(): void {
|
private openCreateTransactionDialog(): void {
|
||||||
const dialogRef = this.dialog.open(CreateOrUpdateTransactionDialog, {
|
const dialogRef = this.dialog.open(CreateOrUpdateTransactionDialog, {
|
||||||
data: {
|
data: {
|
||||||
accounts: this.user.accounts,
|
accounts: this.user?.accounts,
|
||||||
transaction: {
|
transaction: {
|
||||||
accountId: this.user.accounts.find((account) => {
|
accountId: this.user?.accounts.find((account) => {
|
||||||
return account.isDefault;
|
return account.isDefault;
|
||||||
})?.id,
|
})?.id,
|
||||||
currency: null,
|
currency: null,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ghostfolio",
|
"name": "ghostfolio",
|
||||||
"version": "0.94.0",
|
"version": "0.95.0",
|
||||||
"homepage": "https://ghostfol.io",
|
"homepage": "https://ghostfol.io",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -59,22 +59,23 @@ model MarketData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Order {
|
model Order {
|
||||||
Account Account? @relation(fields: [accountId, accountUserId], references: [id, userId])
|
Account Account? @relation(fields: [accountId, accountUserId], references: [id, userId])
|
||||||
accountId String?
|
accountId String?
|
||||||
accountUserId String?
|
accountUserId String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
currency Currency
|
currency Currency
|
||||||
|
dataSource DataSource @default(YAHOO)
|
||||||
date DateTime
|
date DateTime
|
||||||
fee Float
|
fee Float
|
||||||
id String @default(uuid())
|
id String @default(uuid())
|
||||||
Platform Platform? @relation(fields: [platformId], references: [id])
|
Platform Platform? @relation(fields: [platformId], references: [id])
|
||||||
platformId String?
|
platformId String?
|
||||||
quantity Float
|
quantity Float
|
||||||
symbol String
|
symbol String
|
||||||
type Type
|
type Type
|
||||||
unitPrice Float
|
unitPrice Float
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
User User @relation(fields: [userId], references: [id])
|
User User @relation(fields: [userId], references: [id])
|
||||||
userId String
|
userId String
|
||||||
|
|
||||||
@@id([id, userId])
|
@@id([id, userId])
|
||||||
@ -128,6 +129,12 @@ enum Currency {
|
|||||||
USD
|
USD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum DataSource {
|
||||||
|
GHOSTFOLIO
|
||||||
|
RAKUTEN
|
||||||
|
YAHOO
|
||||||
|
}
|
||||||
|
|
||||||
enum Provider {
|
enum Provider {
|
||||||
ANONYMOUS
|
ANONYMOUS
|
||||||
GOOGLE
|
GOOGLE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user