Feature/add asset and asset sub class to wealth items form (#880)

* Add asset and asset sub class

* Update changelog
pull/881/head^2
Thomas Kaul 2 years ago committed by GitHub
parent e9e9f1a124
commit 01103f3db4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- Extended the form to set the asset and asset sub class for (wealth) items
## 1.144.0 - 30.04.2022
### Added

@ -1,4 +1,4 @@
import { DataSource, Type } from '@prisma/client';
import { AssetClass, AssetSubClass, DataSource, Type } from '@prisma/client';
import {
IsEnum,
IsISO8601,
@ -10,14 +10,22 @@ import {
export class CreateOrderDto {
@IsString()
@IsOptional()
accountId: string;
accountId?: string;
@IsEnum(AssetClass, { each: true })
@IsOptional()
assetClass?: AssetClass;
@IsEnum(AssetSubClass, { each: true })
@IsOptional()
assetSubClass?: AssetSubClass;
@IsString()
currency: string;
@IsEnum(DataSource, { each: true })
@IsOptional()
dataSource: DataSource;
dataSource?: DataSource;
@IsISO8601()
date: string;

@ -171,6 +171,11 @@ export class OrderController {
dataSource: data.dataSource,
symbol: data.symbol
}
},
update: {
assetClass: data.assetClass,
assetSubClass: data.assetSubClass,
name: data.symbol
}
},
User: { connect: { id: this.request.user.id } }

@ -6,7 +6,14 @@ import { PrismaService } from '@ghostfolio/api/services/prisma.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
import { OrderWithAccount } from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common';
import { DataSource, Order, Prisma, Type as TypeOfOrder } from '@prisma/client';
import {
AssetClass,
AssetSubClass,
DataSource,
Order,
Prisma,
Type as TypeOfOrder
} from '@prisma/client';
import Big from 'big.js';
import { endOfToday, isAfter } from 'date-fns';
import { v4 as uuidv4 } from 'uuid';
@ -55,6 +62,8 @@ export class OrderService {
public async createOrder(
data: Prisma.OrderCreateInput & {
accountId?: string;
assetClass?: AssetClass;
assetSubClass?: AssetSubClass;
currency?: string;
dataSource?: DataSource;
symbol?: string;
@ -77,6 +86,8 @@ export class OrderService {
};
if (data.type === 'ITEM') {
const assetClass = data.assetClass;
const assetSubClass = data.assetSubClass;
const currency = data.SymbolProfile.connectOrCreate.create.currency;
const dataSource: DataSource = 'MANUAL';
const id = uuidv4();
@ -84,6 +95,8 @@ export class OrderService {
Account = undefined;
data.id = id;
data.SymbolProfile.connectOrCreate.create.assetClass = assetClass;
data.SymbolProfile.connectOrCreate.create.assetSubClass = assetSubClass;
data.SymbolProfile.connectOrCreate.create.currency = currency;
data.SymbolProfile.connectOrCreate.create.dataSource = dataSource;
data.SymbolProfile.connectOrCreate.create.name = name;
@ -120,6 +133,8 @@ export class OrderService {
await this.cacheService.flush();
delete data.accountId;
delete data.assetClass;
delete data.assetSubClass;
delete data.currency;
delete data.dataSource;
delete data.symbol;
@ -232,6 +247,8 @@ export class OrderService {
where
}: {
data: Prisma.OrderUpdateInput & {
assetClass?: AssetClass;
assetSubClass?: AssetSubClass;
currency?: string;
dataSource?: DataSource;
symbol?: string;
@ -245,10 +262,10 @@ export class OrderService {
let isDraft = false;
if (data.type === 'ITEM') {
const name = data.SymbolProfile.connect.dataSource_symbol.symbol;
data.SymbolProfile = { update: { name } };
delete data.SymbolProfile.connect;
} else {
delete data.SymbolProfile.update;
isDraft = isAfter(data.date as Date, endOfToday());
if (!isDraft) {
@ -265,6 +282,8 @@ export class OrderService {
await this.cacheService.flush();
delete data.assetClass;
delete data.assetSubClass;
delete data.currency;
delete data.dataSource;
delete data.symbol;

@ -1,10 +1,24 @@
import { DataSource, Type } from '@prisma/client';
import { IsISO8601, IsNumber, IsOptional, IsString } from 'class-validator';
import { AssetClass, AssetSubClass, DataSource, Type } from '@prisma/client';
import {
IsEnum,
IsISO8601,
IsNumber,
IsOptional,
IsString
} from 'class-validator';
export class UpdateOrderDto {
@IsOptional()
@IsString()
accountId: string;
accountId?: string;
@IsEnum(AssetClass, { each: true })
@IsOptional()
assetClass?: AssetClass;
@IsEnum(AssetSubClass, { each: true })
@IsOptional()
assetSubClass?: AssetSubClass;
@IsString()
currency: string;

@ -13,7 +13,7 @@ import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
import { UpdateOrderDto } from '@ghostfolio/api/app/order/update-order.dto';
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { DataService } from '@ghostfolio/client/services/data.service';
import { Type } from '@prisma/client';
import { AssetClass, AssetSubClass, Type } from '@prisma/client';
import { isUUID } from 'class-validator';
import { isString } from 'lodash';
import { EMPTY, Observable, Subject } from 'rxjs';
@ -39,7 +39,8 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy {
@ViewChild('autocomplete') autocomplete;
public activityForm: FormGroup;
public assetClasses = Object.keys(AssetClass);
public assetSubClasses = Object.keys(AssetSubClass);
public currencies: string[] = [];
public currentMarketPrice = null;
public filteredLookupItems: LookupItem[];
@ -67,6 +68,8 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy {
this.activityForm = this.formBuilder.group({
accountId: [this.data.activity?.accountId, Validators.required],
assetClass: [this.data.activity?.SymbolProfile?.assetClass],
assetSubClass: [this.data.activity?.SymbolProfile?.assetSubClass],
currency: [
this.data.activity?.SymbolProfile?.currency,
Validators.required
@ -234,6 +237,8 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy {
public onSubmit() {
const activity: CreateOrderDto | UpdateOrderDto = {
accountId: this.activityForm.controls['accountId'].value,
assetClass: this.activityForm.controls['assetClass'].value,
assetSubClass: this.activityForm.controls['assetSubClass'].value,
currency: this.activityForm.controls['currency'].value,
date: this.activityForm.controls['date'].value,
dataSource: this.activityForm.controls['dataSource'].value,

@ -134,6 +134,36 @@
>
</mat-form-field>
</div>
<div
[ngClass]="{ 'd-none': activityForm.controls['type']?.value !== 'ITEM' }"
>
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Asset Class</mat-label>
<mat-select formControlName="assetClass">
<mat-option [value]="null"></mat-option>
<mat-option
*ngFor="let assetClass of assetClasses"
[value]="assetClass"
>{{ assetClass }}</mat-option
>
</mat-select>
</mat-form-field>
</div>
<div
[ngClass]="{ 'd-none': activityForm.controls['type']?.value !== 'ITEM' }"
>
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Asset Sub-Class</mat-label>
<mat-select formControlName="assetSubClass">
<mat-option [value]="null"></mat-option>
<mat-option
*ngFor="let assetSubClass of assetSubClasses"
[value]="assetSubClass"
>{{ assetSubClass }}</mat-option
>
</mat-select>
</mat-form-field>
</div>
<div
[ngClass]="{ 'd-none': activityForm.controls['tags']?.value?.length <= 0 }"
>

Loading…
Cancel
Save