Transfer cash balance between accounts (#2455)
* Transfer cash balance between accounts * Update changelog --------- Co-authored-by: Thomas <4159106+dtslvr@users.noreply.github.com>
This commit is contained in:
parent
827270704a
commit
0ac97bd112
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### 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)
|
- Extended the markets overview by benchmarks (date of last all time high)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -29,6 +29,7 @@ import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
|||||||
|
|
||||||
import { AccountService } from './account.service';
|
import { AccountService } from './account.service';
|
||||||
import { CreateAccountDto } from './create-account.dto';
|
import { CreateAccountDto } from './create-account.dto';
|
||||||
|
import { TransferBalanceDto } from './transfer-balance.dto';
|
||||||
import { UpdateAccountDto } from './update-account.dto';
|
import { UpdateAccountDto } from './update-account.dto';
|
||||||
|
|
||||||
@Controller('account')
|
@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')
|
@Put(':id')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
public async update(@Param('id') id: string, @Body() data: UpdateAccountDto) {
|
public async update(@Param('id') id: string, @Body() data: UpdateAccountDto) {
|
||||||
|
@ -109,7 +109,7 @@ export class AccountService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAccounts(aUserId: string) {
|
public async getAccounts(aUserId: string): Promise<Account[]> {
|
||||||
const accounts = await this.accounts({
|
const accounts = await this.accounts({
|
||||||
include: { Order: true, Platform: true },
|
include: { Order: true, Platform: true },
|
||||||
orderBy: { name: 'asc' },
|
orderBy: { name: 'asc' },
|
||||||
@ -218,13 +218,13 @@ export class AccountService {
|
|||||||
accountId,
|
accountId,
|
||||||
amount,
|
amount,
|
||||||
currency,
|
currency,
|
||||||
date,
|
date = new Date(),
|
||||||
userId
|
userId
|
||||||
}: {
|
}: {
|
||||||
accountId: string;
|
accountId: string;
|
||||||
amount: number;
|
amount: number;
|
||||||
currency: string;
|
currency: string;
|
||||||
date: Date;
|
date?: Date;
|
||||||
userId: string;
|
userId: string;
|
||||||
}) {
|
}) {
|
||||||
const { balance, currency: currencyOfAccount } = await this.account({
|
const { balance, currency: currencyOfAccount } = await this.account({
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div *ngIf="false" class="d-flex justify-content-end">
|
<div class="d-flex justify-content-end">
|
||||||
<button
|
<button
|
||||||
class="align-items-center d-flex"
|
class="align-items-center d-flex"
|
||||||
mat-stroked-button
|
mat-stroked-button
|
||||||
|
@ -295,9 +295,16 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
|
|||||||
const { accountIdFrom, accountIdTo, balance }: TransferBalanceDto =
|
const { accountIdFrom, accountIdTo, balance }: TransferBalanceDto =
|
||||||
data?.account;
|
data?.account;
|
||||||
|
|
||||||
console.log(
|
this.dataService
|
||||||
`Transfer cash balance of ${balance} from account ${accountIdFrom} to account ${accountIdTo}`
|
.transferAccountBalance({
|
||||||
);
|
accountIdFrom,
|
||||||
|
accountIdTo,
|
||||||
|
balance
|
||||||
|
})
|
||||||
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
|
.subscribe(() => {
|
||||||
|
this.fetchAccounts();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.router.navigate(['.'], { relativeTo: this.route });
|
this.router.navigate(['.'], { relativeTo: this.route });
|
||||||
|
@ -2,6 +2,7 @@ import { HttpClient, HttpParams } from '@angular/common/http';
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto';
|
import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto';
|
||||||
import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto';
|
import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto';
|
||||||
|
import { TransferBalanceDto } from '@ghostfolio/api/app/account/transfer-balance.dto';
|
||||||
import { UpdateAccountDto } from '@ghostfolio/api/app/account/update-account.dto';
|
import { UpdateAccountDto } from '@ghostfolio/api/app/account/update-account.dto';
|
||||||
import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
|
import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
|
||||||
import { Activities } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
import { Activities } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||||
@ -505,6 +506,18 @@ export class DataService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public transferAccountBalance({
|
||||||
|
accountIdFrom,
|
||||||
|
accountIdTo,
|
||||||
|
balance
|
||||||
|
}: TransferBalanceDto) {
|
||||||
|
return this.http.post('/api/v1/account/transfer-balance', {
|
||||||
|
accountIdFrom,
|
||||||
|
accountIdTo,
|
||||||
|
balance
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public updateInfo() {
|
public updateInfo() {
|
||||||
this.http.get<InfoItem>('/api/v1/info').subscribe((info) => {
|
this.http.get<InfoItem>('/api/v1/info').subscribe((info) => {
|
||||||
const utmSource = <'ios' | 'trusted-web-activity'>(
|
const utmSource = <'ios' | 'trusted-web-activity'>(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user