Improve usability and validation in cash balance transfer (#2552)
* Improve usability and validation in cash balance transfer * Update changelog --------- Co-authored-by: Thomas <4159106+dtslvr@users.noreply.github.com>
This commit is contained in:
parent
379c651ce0
commit
20cefaba19
@ -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
|
||||
|
||||
### Changed
|
||||
|
||||
- Improved the usability and validation in the cash balance transfer from one to another account
|
||||
|
||||
## 2.15.0 - 2023-10-26
|
||||
|
||||
### Added
|
||||
|
@ -190,36 +190,46 @@ export class AccountController {
|
||||
this.request.user.id
|
||||
);
|
||||
|
||||
const currentAccountIds = accountsOfUser.map(({ id }) => {
|
||||
return id;
|
||||
const accountFrom = accountsOfUser.find(({ id }) => {
|
||||
return id === accountIdFrom;
|
||||
});
|
||||
|
||||
if (
|
||||
![accountIdFrom, accountIdTo].every((accountId) => {
|
||||
return currentAccountIds.includes(accountId);
|
||||
})
|
||||
) {
|
||||
const accountTo = accountsOfUser.find(({ id }) => {
|
||||
return id === accountIdTo;
|
||||
});
|
||||
|
||||
if (!accountFrom || !accountTo) {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.NOT_FOUND),
|
||||
StatusCodes.NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
const { currency } = accountsOfUser.find(({ id }) => {
|
||||
return id === accountIdFrom;
|
||||
});
|
||||
if (accountFrom.id === accountTo.id) {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.BAD_REQUEST),
|
||||
StatusCodes.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
if (accountFrom.balance < balance) {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.BAD_REQUEST),
|
||||
StatusCodes.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
await this.accountService.updateAccountBalance({
|
||||
currency,
|
||||
accountId: accountIdFrom,
|
||||
accountId: accountFrom.id,
|
||||
amount: -balance,
|
||||
currency: accountFrom.currency,
|
||||
userId: this.request.user.id
|
||||
});
|
||||
|
||||
await this.accountService.updateAccountBalance({
|
||||
currency,
|
||||
accountId: accountIdTo,
|
||||
accountId: accountTo.id,
|
||||
amount: balance,
|
||||
currency: accountFrom.currency,
|
||||
userId: this.request.user.id
|
||||
});
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
<button
|
||||
class="align-items-center d-flex"
|
||||
mat-stroked-button
|
||||
[disabled]="dataSource?.data.length < 2"
|
||||
(click)="onTransferBalance()"
|
||||
>
|
||||
<ion-icon class="mr-2" name="arrow-redo-outline"></ion-icon>
|
||||
|
@ -13,8 +13,8 @@ import { User } from '@ghostfolio/common/interfaces';
|
||||
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
|
||||
import { Account as AccountModel } from '@prisma/client';
|
||||
import { DeviceDetectorService } from 'ngx-device-detector';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { EMPTY, Subject, Subscription } from 'rxjs';
|
||||
import { catchError, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { CreateOrUpdateAccountDialog } from './create-or-update-account-dialog/create-or-update-account-dialog.component';
|
||||
import { TransferBalanceDialog } from './transfer-balance/transfer-balance-dialog.component';
|
||||
@ -283,7 +283,6 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
|
||||
data: {
|
||||
accounts: this.accounts
|
||||
},
|
||||
height: this.deviceType === 'mobile' ? '97.5vh' : '80vh',
|
||||
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
|
||||
});
|
||||
|
||||
@ -301,7 +300,14 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
|
||||
accountIdTo,
|
||||
balance
|
||||
})
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.pipe(
|
||||
catchError(() => {
|
||||
alert($localize`Oops, transfer cash balance has failed.`);
|
||||
|
||||
return EMPTY;
|
||||
}),
|
||||
takeUntil(this.unsubscribeSubject)
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.fetchAccounts();
|
||||
});
|
||||
|
@ -4,7 +4,13 @@ import {
|
||||
Inject,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import {
|
||||
AbstractControl,
|
||||
FormBuilder,
|
||||
FormGroup,
|
||||
ValidationErrors,
|
||||
Validators
|
||||
} from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { TransferBalanceDto } from '@ghostfolio/api/app/account/transfer-balance.dto';
|
||||
import { Account } from '@prisma/client';
|
||||
@ -35,11 +41,16 @@ export class TransferBalanceDialog implements OnDestroy {
|
||||
public ngOnInit() {
|
||||
this.accounts = this.data.accounts;
|
||||
|
||||
this.transferBalanceForm = this.formBuilder.group({
|
||||
balance: [0, Validators.required],
|
||||
fromAccount: ['', Validators.required],
|
||||
toAccount: ['', Validators.required]
|
||||
});
|
||||
this.transferBalanceForm = this.formBuilder.group(
|
||||
{
|
||||
balance: ['', Validators.required],
|
||||
fromAccount: ['', Validators.required],
|
||||
toAccount: ['', Validators.required]
|
||||
},
|
||||
{
|
||||
validators: this.compareAccounts
|
||||
}
|
||||
);
|
||||
|
||||
this.transferBalanceForm.get('fromAccount').valueChanges.subscribe((id) => {
|
||||
this.currency = this.accounts.find((account) => {
|
||||
@ -66,4 +77,13 @@ export class TransferBalanceDialog implements OnDestroy {
|
||||
this.unsubscribeSubject.next();
|
||||
this.unsubscribeSubject.complete();
|
||||
}
|
||||
|
||||
private compareAccounts(control: AbstractControl): ValidationErrors {
|
||||
const accountFrom = control.get('fromAccount');
|
||||
const accountTo = control.get('toAccount');
|
||||
|
||||
if (accountFrom.value === accountTo.value) {
|
||||
return { invalid: true };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user