diff --git a/CHANGELOG.md b/CHANGELOG.md index e8f1c342a..8bff6b300 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added support to transfer a part of the cash balance from one to another account - Extended the markets overview by benchmarks (date of last all time high) ### Changed diff --git a/apps/api/src/app/account/account.controller.ts b/apps/api/src/app/account/account.controller.ts index bf15d998f..05d0c11de 100644 --- a/apps/api/src/app/account/account.controller.ts +++ b/apps/api/src/app/account/account.controller.ts @@ -29,6 +29,7 @@ import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { AccountService } from './account.service'; import { CreateAccountDto } from './create-account.dto'; +import { TransferBalanceDto } from './transfer-balance.dto'; import { UpdateAccountDto } from './update-account.dto'; @Controller('account') @@ -154,6 +155,58 @@ export class AccountController { } } + @Post('transfer-balance') + @UseGuards(AuthGuard('jwt')) + public async transferAccountBalance( + @Body() { accountIdFrom, accountIdTo, balance }: TransferBalanceDto + ) { + if ( + !hasPermission(this.request.user.permissions, permissions.updateAccount) + ) { + throw new HttpException( + getReasonPhrase(StatusCodes.FORBIDDEN), + StatusCodes.FORBIDDEN + ); + } + + const accountsOfUser = await this.accountService.getAccounts( + this.request.user.id + ); + + const currentAccountIds = accountsOfUser.map(({ id }) => { + return id; + }); + + if ( + ![accountIdFrom, accountIdTo].every((accountId) => { + return currentAccountIds.includes(accountId); + }) + ) { + throw new HttpException( + getReasonPhrase(StatusCodes.NOT_FOUND), + StatusCodes.NOT_FOUND + ); + } + + const { currency } = accountsOfUser.find(({ id }) => { + return id === accountIdFrom; + }); + + await this.accountService.updateAccountBalance({ + currency, + accountId: accountIdFrom, + amount: -balance, + userId: this.request.user.id + }); + + await this.accountService.updateAccountBalance({ + currency, + accountId: accountIdTo, + amount: balance, + userId: this.request.user.id + }); + } + @Put(':id') @UseGuards(AuthGuard('jwt')) public async update(@Param('id') id: string, @Body() data: UpdateAccountDto) { diff --git a/apps/api/src/app/account/account.service.ts b/apps/api/src/app/account/account.service.ts index dc049108c..bc6abcc7a 100644 --- a/apps/api/src/app/account/account.service.ts +++ b/apps/api/src/app/account/account.service.ts @@ -109,7 +109,7 @@ export class AccountService { }); } - public async getAccounts(aUserId: string) { + public async getAccounts(aUserId: string): Promise { const accounts = await this.accounts({ include: { Order: true, Platform: true }, orderBy: { name: 'asc' }, @@ -218,13 +218,13 @@ export class AccountService { accountId, amount, currency, - date, + date = new Date(), userId }: { accountId: string; amount: number; currency: string; - date: Date; + date?: Date; userId: string; }) { const { balance, currency: currencyOfAccount } = await this.account({ 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 664694735..a4548c1b9 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 @@ -1,4 +1,4 @@ -
+