diff --git a/apps/api/src/app/account/account.controller.ts b/apps/api/src/app/account/account.controller.ts index 6b3152712..581e52c0b 100644 --- a/apps/api/src/app/account/account.controller.ts +++ b/apps/api/src/app/account/account.controller.ts @@ -17,8 +17,7 @@ import { } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; -import { Order as OrderModel } from '@prisma/client'; -import { parseISO } from 'date-fns'; +import { Account as AccountModel } from '@prisma/client'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { AccountService } from './account.service'; @@ -35,11 +34,11 @@ export class AccountController { @Delete(':id') @UseGuards(AuthGuard('jwt')) - public async deleteOrder(@Param('id') id: string): Promise { + public async deleteAccount(@Param('id') id: string): Promise { if ( !hasPermission( getPermissions(this.request.user.role), - permissions.deleteOrder + permissions.deleteAccount ) ) { throw new HttpException( @@ -48,7 +47,7 @@ export class AccountController { ); } - return this.accountService.deleteOrder( + return this.accountService.deleteAccount( { id_userId: { id, @@ -61,23 +60,17 @@ export class AccountController { @Get() @UseGuards(AuthGuard('jwt')) - public async getAllOrders( + public async getAllAccounts( @Headers('impersonation-id') impersonationId - ): Promise { + ): Promise { const impersonationUserId = await this.impersonationService.validateImpersonationId( impersonationId, this.request.user.id ); - let orders = await this.accountService.orders({ - include: { - Account: { - include: { - Platform: true - } - } - }, - orderBy: { date: 'desc' }, + let accounts = await this.accountService.accounts({ + include: { Platform: true }, + orderBy: { name: 'desc' }, where: { userId: impersonationUserId || this.request.user.id } }); @@ -88,16 +81,20 @@ export class AccountController { permissions.readForeignPortfolio ) ) { - orders = nullifyValuesInObjects(orders, ['fee', 'quantity', 'unitPrice']); + accounts = nullifyValuesInObjects(accounts, [ + 'fee', + 'quantity', + 'unitPrice' + ]); } - return orders; + return accounts; } @Get(':id') @UseGuards(AuthGuard('jwt')) - public async getOrderById(@Param('id') id: string): Promise { - return this.accountService.order({ + public async getAccountById(@Param('id') id: string): Promise { + return this.accountService.account({ id_userId: { id, userId: this.request.user.id @@ -107,13 +104,13 @@ export class AccountController { @Post() @UseGuards(AuthGuard('jwt')) - public async createOrder( + public async createAccount( @Body() data: CreateAccountDto - ): Promise { + ): Promise { if ( !hasPermission( getPermissions(this.request.user.role), - permissions.createOrder + permissions.createAccount ) ) { throw new HttpException( @@ -122,24 +119,13 @@ export class AccountController { ); } - const date = parseISO(data.date); - - const accountId = data.accountId; - delete data.accountId; - if (data.platformId) { const platformId = data.platformId; delete data.platformId; - return this.accountService.createOrder( + return this.accountService.createAccount( { ...data, - date, - Account: { - connect: { - id_userId: { id: accountId, userId: this.request.user.id } - } - }, Platform: { connect: { id: platformId } }, User: { connect: { id: this.request.user.id } } }, @@ -148,15 +134,9 @@ export class AccountController { } else { delete data.platformId; - return this.accountService.createOrder( + return this.accountService.createAccount( { ...data, - date, - Account: { - connect: { - id_userId: { id: accountId, userId: this.request.user.id } - } - }, User: { connect: { id: this.request.user.id } } }, this.request.user.id @@ -170,7 +150,7 @@ export class AccountController { if ( !hasPermission( getPermissions(this.request.user.role), - permissions.updateOrder + permissions.updateAccount ) ) { throw new HttpException( @@ -179,32 +159,21 @@ export class AccountController { ); } - const originalOrder = await this.accountService.order({ + const originalAccount = await this.accountService.account({ id_userId: { id, userId: this.request.user.id } }); - const date = parseISO(data.date); - - const accountId = data.accountId; - delete data.accountId; - if (data.platformId) { const platformId = data.platformId; delete data.platformId; - return this.accountService.updateOrder( + return this.accountService.updateAccount( { data: { ...data, - date, - Account: { - connect: { - id_userId: { id: accountId, userId: this.request.user.id } - } - }, Platform: { connect: { id: platformId } }, User: { connect: { id: this.request.user.id } } }, @@ -221,17 +190,11 @@ export class AccountController { // platformId is null, remove it delete data.platformId; - return this.accountService.updateOrder( + return this.accountService.updateAccount( { data: { ...data, - date, - Account: { - connect: { - id_userId: { id: accountId, userId: this.request.user.id } - } - }, - Platform: originalOrder.platformId + Platform: originalAccount.platformId ? { disconnect: true } : undefined, User: { connect: { id: this.request.user.id } } diff --git a/apps/api/src/app/account/account.module.ts b/apps/api/src/app/account/account.module.ts index 89d088022..3ac6c0ad0 100644 --- a/apps/api/src/app/account/account.module.ts +++ b/apps/api/src/app/account/account.module.ts @@ -1,5 +1,4 @@ import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; -import { DataGatheringService } from '@ghostfolio/api/services/data-gathering.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider.service'; import { AlphaVantageService } from '@ghostfolio/api/services/data-provider/alpha-vantage/alpha-vantage.service'; import { GhostfolioScraperApiService } from '@ghostfolio/api/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service'; @@ -9,7 +8,6 @@ import { ImpersonationService } from '@ghostfolio/api/services/impersonation.ser import { PrismaService } from '@ghostfolio/api/services/prisma.service'; import { Module } from '@nestjs/common'; -import { CacheService } from '../cache/cache.service'; import { RedisCacheModule } from '../redis-cache/redis-cache.module'; import { AccountController } from './account.controller'; import { AccountService } from './account.service'; @@ -20,9 +18,7 @@ import { AccountService } from './account.service'; providers: [ AccountService, AlphaVantageService, - CacheService, ConfigurationService, - DataGatheringService, DataProviderService, GhostfolioScraperApiService, ImpersonationService, diff --git a/apps/api/src/app/account/account.service.ts b/apps/api/src/app/account/account.service.ts index cb3812856..92d39695c 100644 --- a/apps/api/src/app/account/account.service.ts +++ b/apps/api/src/app/account/account.service.ts @@ -1,40 +1,35 @@ -import { DataGatheringService } from '@ghostfolio/api/services/data-gathering.service'; import { PrismaService } from '@ghostfolio/api/services/prisma.service'; import { Injectable } from '@nestjs/common'; -import { Order, Prisma } from '@prisma/client'; +import { Account, Prisma } from '@prisma/client'; -import { CacheService } from '../cache/cache.service'; import { RedisCacheService } from '../redis-cache/redis-cache.service'; -import { OrderWithPlatform } from './interfaces/order-with-platform.type'; @Injectable() export class AccountService { public constructor( - private readonly cacheService: CacheService, - private readonly dataGatheringService: DataGatheringService, private readonly redisCacheService: RedisCacheService, private prisma: PrismaService ) {} - public async order( - orderWhereUniqueInput: Prisma.OrderWhereUniqueInput - ): Promise { - return this.prisma.order.findUnique({ - where: orderWhereUniqueInput + public async account( + accountWhereUniqueInput: Prisma.AccountWhereUniqueInput + ): Promise { + return this.prisma.account.findUnique({ + where: accountWhereUniqueInput }); } - public async orders(params: { - include?: Prisma.OrderInclude; + public async accounts(params: { + include?: Prisma.AccountInclude; skip?: number; take?: number; - cursor?: Prisma.OrderWhereUniqueInput; - where?: Prisma.OrderWhereInput; - orderBy?: Prisma.OrderOrderByInput; - }): Promise { + cursor?: Prisma.AccountWhereUniqueInput; + where?: Prisma.AccountWhereInput; + orderBy?: Prisma.AccountOrderByInput; + }): Promise { const { include, skip, take, cursor, where, orderBy } = params; - return this.prisma.order.findMany({ + return this.prisma.account.findMany({ cursor, include, orderBy, @@ -44,60 +39,35 @@ export class AccountService { }); } - public async createOrder( - data: Prisma.OrderCreateInput, + public async createAccount( + data: Prisma.AccountCreateInput, aUserId: string - ): Promise { - this.redisCacheService.remove(`${aUserId}.portfolio`); - - // Gather symbol data of order in the background - this.dataGatheringService.gatherSymbols([ - { - date: data.date, - symbol: data.symbol - } - ]); - - await this.cacheService.flush(aUserId); - - return this.prisma.order.create({ + ): Promise { + return this.prisma.account.create({ data }); } - public async deleteOrder( - where: Prisma.OrderWhereUniqueInput, + public async deleteAccount( + where: Prisma.AccountWhereUniqueInput, aUserId: string - ): Promise { + ): Promise { this.redisCacheService.remove(`${aUserId}.portfolio`); - return this.prisma.order.delete({ + return this.prisma.account.delete({ where }); } - public async updateOrder( + public async updateAccount( params: { - where: Prisma.OrderWhereUniqueInput; - data: Prisma.OrderUpdateInput; + where: Prisma.AccountWhereUniqueInput; + data: Prisma.AccountUpdateInput; }, aUserId: string - ): Promise { + ): Promise { const { data, where } = params; - - this.redisCacheService.remove(`${aUserId}.portfolio`); - - // Gather symbol data of order in the background - this.dataGatheringService.gatherSymbols([ - { - date: data.date, - symbol: data.symbol - } - ]); - - await this.cacheService.flush(aUserId); - - return this.prisma.order.update({ + return this.prisma.account.update({ data, where }); diff --git a/apps/client/src/app/app.component.ts b/apps/client/src/app/app.component.ts index 71fe416f5..22e7fe6f8 100644 --- a/apps/client/src/app/app.component.ts +++ b/apps/client/src/app/app.component.ts @@ -74,7 +74,7 @@ export class AppComponent implements OnDestroy, OnInit { this.canCreateAccount = hasPermission( this.user.permissions, - permissions.createAccount + permissions.createUserAccount ); this.cd.markForCheck(); diff --git a/apps/client/src/app/components/accounts-table/accounts-table.component.html b/apps/client/src/app/components/accounts-table/accounts-table.component.html index 6f4deab5e..5796d82ac 100644 --- a/apps/client/src/app/components/accounts-table/accounts-table.component.html +++ b/apps/client/src/app/components/accounts-table/accounts-table.component.html @@ -9,49 +9,44 @@ Name -
- - {{ element.Account?.name }} -
+ {{ element.name }}
Type - -
- - {{ element.type }} + +
+ {{ element.accountType }}
- + Platform - {{ element.symbol }} + +
+ + {{ element.Platform?.name }} +
+
@@ -66,10 +61,10 @@ - - diff --git a/apps/client/src/app/components/accounts-table/accounts-table.component.ts b/apps/client/src/app/components/accounts-table/accounts-table.component.ts index 9c3009819..a35751172 100644 --- a/apps/client/src/app/components/accounts-table/accounts-table.component.ts +++ b/apps/client/src/app/components/accounts-table/accounts-table.component.ts @@ -29,8 +29,8 @@ export class AccountsTableComponent implements OnChanges, OnDestroy, OnInit { @Input() locale: string; @Input() showActions: boolean; - @Output() transactionDeleted = new EventEmitter(); - @Output() transactionToUpdate = new EventEmitter(); + @Output() accountDeleted = new EventEmitter(); + @Output() accountToUpdate = new EventEmitter(); @ViewChild(MatSort) sort: MatSort; @@ -50,7 +50,7 @@ export class AccountsTableComponent implements OnChanges, OnDestroy, OnInit { public ngOnInit() {} public ngOnChanges() { - this.displayedColumns = ['account', 'type', 'symbol']; + this.displayedColumns = ['account', 'type', 'platform']; this.isLoading = true; @@ -66,18 +66,16 @@ export class AccountsTableComponent implements OnChanges, OnDestroy, OnInit { } } - public onDeleteTransaction(aId: string) { - const confirmation = confirm( - 'Do you really want to delete this transaction?' - ); + public onDeleteAccount(aId: string) { + const confirmation = confirm('Do you really want to delete this account?'); if (confirmation) { - this.transactionDeleted.emit(aId); + this.accountDeleted.emit(aId); } } - public onUpdateTransaction(aTransaction: OrderModel) { - this.transactionToUpdate.emit(aTransaction); + public onUpdateAccount(aAccount: OrderModel) { + this.accountToUpdate.emit(aAccount); } public ngOnDestroy() { diff --git a/apps/client/src/app/components/transactions-table/transactions-table.component.html b/apps/client/src/app/components/transactions-table/transactions-table.component.html index bacf72849..7c0bd479d 100644 --- a/apps/client/src/app/components/transactions-table/transactions-table.component.html +++ b/apps/client/src/app/components/transactions-table/transactions-table.component.html @@ -23,7 +23,7 @@
diff --git a/apps/client/src/app/pages/accounts/accounts-page.component.ts b/apps/client/src/app/pages/accounts/accounts-page.component.ts index 1ff8fdf9e..ad3ccfbc0 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.component.ts +++ b/apps/client/src/app/pages/accounts/accounts-page.component.ts @@ -23,8 +23,8 @@ export class AccountsPageComponent implements OnInit { public accounts: OrderModel[]; public deviceType: string; public hasImpersonationId: boolean; - public hasPermissionToCreateOrder: boolean; - public hasPermissionToDeleteOrder: boolean; + public hasPermissionToCreateAccount: boolean; + public hasPermissionToDeleteAccount: boolean; public routeQueryParams: Subscription; public user: User; @@ -47,14 +47,14 @@ export class AccountsPageComponent implements OnInit { .pipe(takeUntil(this.unsubscribeSubject)) .subscribe((params) => { if (params['createDialog']) { - this.openCreateTransactionDialog(); + this.openCreateAccountDialog(); } else if (params['editDialog']) { if (this.accounts) { - const transaction = this.accounts.find((transaction) => { - return transaction.id === params['transactionId']; + const account = this.accounts.find((account) => { + return account.id === params['transactionId']; }); - this.openUpdateTransactionDialog(transaction); + this.openUpdateAccountDialog(account); } else { this.router.navigate(['.'], { relativeTo: this.route }); } @@ -80,13 +80,13 @@ export class AccountsPageComponent implements OnInit { .subscribe(() => { this.dataService.fetchUser().subscribe((user) => { this.user = user; - this.hasPermissionToCreateOrder = hasPermission( + this.hasPermissionToCreateAccount = hasPermission( user.permissions, - permissions.createOrder + permissions.createAccount ); - this.hasPermissionToDeleteOrder = hasPermission( + this.hasPermissionToDeleteAccount = hasPermission( user.permissions, - permissions.deleteOrder + permissions.deleteAccount ); this.cd.markForCheck(); @@ -108,7 +108,7 @@ export class AccountsPageComponent implements OnInit { }); } - public onDeleteTransaction(aId: string) { + public onDeleteAccount(aId: string) { this.dataService.deleteAccount(aId).subscribe({ next: () => { this.fetchAccounts(); @@ -116,13 +116,13 @@ export class AccountsPageComponent implements OnInit { }); } - public onUpdateTransaction(aTransaction: OrderModel) { + public onUpdateAccount(aAccount: OrderModel) { this.router.navigate([], { - queryParams: { editDialog: true, transactionId: aTransaction.id } + queryParams: { editDialog: true, transactionId: aAccount.id } }); } - public openUpdateTransactionDialog({ + public openUpdateAccountDialog({ accountId, currency, dataSource, @@ -176,7 +176,7 @@ export class AccountsPageComponent implements OnInit { this.unsubscribeSubject.complete(); } - private openCreateTransactionDialog(): void { + private openCreateAccountDialog(): void { const dialogRef = this.dialog.open(CreateOrUpdateAccountDialog, { data: { accounts: this.user?.accounts, diff --git a/apps/client/src/app/pages/accounts/accounts-page.html b/apps/client/src/app/pages/accounts/accounts-page.html index c8bfabfd6..f4cc36223 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.html +++ b/apps/client/src/app/pages/accounts/accounts-page.html @@ -7,15 +7,15 @@ [baseCurrency]="user?.settings?.baseCurrency" [deviceType]="deviceType" [locale]="user?.settings?.locale" - [showActions]="!hasImpersonationId && hasPermissionToDeleteOrder" - (transactionDeleted)="onDeleteTransaction($event)" - (transactionToUpdate)="onUpdateTransaction($event)" + [showActions]="!hasImpersonationId && hasPermissionToDeleteAccount" + (accountDeleted)="onDeleteAccount($event)" + (accountToUpdate)="onUpdateAccount($event)" >