Browse Source

Unit price not converted in the frontend

csehatt741 3 weeks ago
committed by Attila Cseh
parent
commit
bac0f0f4f4
  1. 4
      apps/api/src/app/order/order.service.ts
  2. 88
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts
  3. 74
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html
  4. 2
      libs/ui/src/lib/activities-table/activities-table.component.html

4
apps/api/src/app/order/order.service.ts

@ -537,7 +537,7 @@ export class OrderService {
feeInBaseCurrency: feeInBaseCurrency:
await this.exchangeRateDataService.toCurrencyAtDate( await this.exchangeRateDataService.toCurrencyAtDate(
order.fee, order.fee,
order.SymbolProfile.currency, order.currency ?? order.SymbolProfile.currency,
userCurrency, userCurrency,
order.date order.date
), ),
@ -545,7 +545,7 @@ export class OrderService {
valueInBaseCurrency: valueInBaseCurrency:
await this.exchangeRateDataService.toCurrencyAtDate( await this.exchangeRateDataService.toCurrencyAtDate(
value, value,
order.SymbolProfile.currency, order.currency ?? order.SymbolProfile.currency,
userCurrency, userCurrency,
order.date order.date
) )

88
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts

@ -15,7 +15,7 @@ import { DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AssetClass, AssetSubClass, Tag, Type } from '@prisma/client'; import { AssetClass, AssetSubClass, Tag, Type } from '@prisma/client';
import { isAfter, isToday } from 'date-fns'; import { isAfter, isToday } from 'date-fns';
import { EMPTY, Subject, lastValueFrom } from 'rxjs'; import { EMPTY, Subject } from 'rxjs';
import { catchError, delay, takeUntil } from 'rxjs/operators'; import { catchError, delay, takeUntil } from 'rxjs/operators';
import { DataService } from '../../../../services/data.service'; import { DataService } from '../../../../services/data.service';
@ -101,17 +101,13 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
this.data.activity?.SymbolProfile?.currency, this.data.activity?.SymbolProfile?.currency,
Validators.required Validators.required
], ],
currencyOfUnitPrice: [ currencyOfUnitPrice: [this.data.activity?.currency, Validators.required],
this.data.activity?.SymbolProfile?.currency,
Validators.required
],
dataSource: [ dataSource: [
this.data.activity?.SymbolProfile?.dataSource, this.data.activity?.SymbolProfile?.dataSource,
Validators.required Validators.required
], ],
date: [this.data.activity?.date, Validators.required], date: [this.data.activity?.date, Validators.required],
fee: [this.data.activity?.fee, Validators.required], fee: [this.data.activity?.fee, Validators.required],
feeInCustomCurrency: [this.data.activity?.fee, Validators.required],
name: [this.data.activity?.SymbolProfile?.name, Validators.required], name: [this.data.activity?.SymbolProfile?.name, Validators.required],
quantity: [this.data.activity?.quantity, Validators.required], quantity: [this.data.activity?.quantity, Validators.required],
searchSymbol: [ searchSymbol: [
@ -133,10 +129,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
], ],
type: [undefined, Validators.required], // Set after value changes subscription type: [undefined, Validators.required], // Set after value changes subscription
unitPrice: [this.data.activity?.unitPrice, Validators.required], unitPrice: [this.data.activity?.unitPrice, Validators.required],
unitPriceInCustomCurrency: [
this.data.activity?.unitPrice,
Validators.required
],
updateAccountBalance: [false] updateAccountBalance: [false]
}); });
@ -148,57 +140,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
takeUntil(this.unsubscribeSubject) takeUntil(this.unsubscribeSubject)
) )
.subscribe(async () => { .subscribe(async () => {
let exchangeRateOfUnitPrice = 1;
this.activityForm.get('feeInCustomCurrency').setErrors(null);
this.activityForm.get('unitPriceInCustomCurrency').setErrors(null);
const currency = this.activityForm.get('currency').value;
const currencyOfUnitPrice = this.activityForm.get(
'currencyOfUnitPrice'
).value;
const date = this.activityForm.get('date').value;
if (
currency &&
currencyOfUnitPrice &&
currency !== currencyOfUnitPrice &&
date
) {
try {
const { marketPrice } = await lastValueFrom(
this.dataService
.fetchExchangeRateForDate({
date,
symbol: `${currencyOfUnitPrice}-${currency}`
})
.pipe(takeUntil(this.unsubscribeSubject))
);
exchangeRateOfUnitPrice = marketPrice;
} catch {
this.activityForm.get('unitPriceInCustomCurrency').setErrors({
invalid: true
});
}
}
const feeInCustomCurrency =
this.activityForm.get('feeInCustomCurrency').value *
exchangeRateOfUnitPrice;
const unitPriceInCustomCurrency =
this.activityForm.get('unitPriceInCustomCurrency').value *
exchangeRateOfUnitPrice;
this.activityForm.get('fee').setValue(feeInCustomCurrency, {
emitEvent: false
});
this.activityForm.get('unitPrice').setValue(unitPriceInCustomCurrency, {
emitEvent: false
});
if ( if (
this.activityForm.get('type').value === 'BUY' || this.activityForm.get('type').value === 'BUY' ||
this.activityForm.get('type').value === 'FEE' || this.activityForm.get('type').value === 'FEE' ||
@ -265,10 +206,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
this.activityForm.get('type').value this.activityForm.get('type').value
) )
) { ) {
this.activityForm
.get('dataSource')
.setValue(this.activityForm.get('searchSymbol').value.dataSource);
this.updateSymbol(); this.updateSymbol();
} }
@ -297,7 +234,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
.get('dataSource') .get('dataSource')
.removeValidators(Validators.required); .removeValidators(Validators.required);
this.activityForm.get('dataSource').updateValueAndValidity(); this.activityForm.get('dataSource').updateValueAndValidity();
this.activityForm.get('feeInCustomCurrency').reset(); this.activityForm.get('fee').reset();
this.activityForm.get('name').setValidators(Validators.required); this.activityForm.get('name').setValidators(Validators.required);
this.activityForm.get('name').updateValueAndValidity(); this.activityForm.get('name').updateValueAndValidity();
this.activityForm.get('quantity').setValue(1); this.activityForm.get('quantity').setValue(1);
@ -331,12 +268,11 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
this.activityForm.get('dataSource').updateValueAndValidity(); this.activityForm.get('dataSource').updateValueAndValidity();
if ( if (
(type === 'FEE' && (type === 'FEE' && this.activityForm.get('fee').value === 0) ||
this.activityForm.get('feeInCustomCurrency').value === 0) ||
type === 'INTEREST' || type === 'INTEREST' ||
type === 'LIABILITY' type === 'LIABILITY'
) { ) {
this.activityForm.get('feeInCustomCurrency').reset(); this.activityForm.get('fee').reset();
} }
this.activityForm.get('name').setValidators(Validators.required); this.activityForm.get('name').setValidators(Validators.required);
@ -354,7 +290,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
this.activityForm.get('searchSymbol').updateValueAndValidity(); this.activityForm.get('searchSymbol').updateValueAndValidity();
if (type === 'FEE') { if (type === 'FEE') {
this.activityForm.get('unitPriceInCustomCurrency').setValue(0); this.activityForm.get('unitPrice').setValue(0);
} }
if ( if (
@ -410,7 +346,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
public applyCurrentMarketPrice() { public applyCurrentMarketPrice() {
this.activityForm.patchValue({ this.activityForm.patchValue({
currencyOfUnitPrice: this.activityForm.get('currency').value, currencyOfUnitPrice: this.activityForm.get('currency').value,
unitPriceInCustomCurrency: this.currentMarketPrice unitPrice: this.currentMarketPrice
}); });
} }
@ -496,7 +432,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
this.dataService this.dataService
.fetchSymbolItem({ .fetchSymbolItem({
dataSource: this.activityForm.get('dataSource').value, dataSource: this.activityForm.get('searchSymbol').value.dataSource,
symbol: this.activityForm.get('searchSymbol').value.symbol symbol: this.activityForm.get('searchSymbol').value.symbol
}) })
.pipe( .pipe(
@ -512,9 +448,11 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
takeUntil(this.unsubscribeSubject) takeUntil(this.unsubscribeSubject)
) )
.subscribe(({ currency, dataSource, marketPrice }) => { .subscribe(({ currency, dataSource, marketPrice }) => {
this.activityForm.get('currency').setValue(currency); if (this.mode === 'create') {
this.activityForm.get('currencyOfUnitPrice').setValue(currency); this.activityForm.get('currency').setValue(currency);
this.activityForm.get('dataSource').setValue(dataSource); this.activityForm.get('currencyOfUnitPrice').setValue(currency);
this.activityForm.get('dataSource').setValue(dataSource);
}
this.currentMarketPrice = marketPrice; this.currentMarketPrice = marketPrice;

74
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html

@ -214,11 +214,7 @@
} }
} }
</mat-label> </mat-label>
<input <input formControlName="unitPrice" matInput type="number" />
formControlName="unitPriceInCustomCurrency"
matInput
type="number"
/>
<div <div
class="ml-2" class="ml-2"
matTextSuffix matTextSuffix
@ -232,19 +228,6 @@
} }
</mat-select> </mat-select>
</div> </div>
@if (
activityForm.get('unitPriceInCustomCurrency').hasError('invalid')
) {
<mat-error
><ng-container i18n
>Oops! Could not get the historical exchange rate
from</ng-container
>
{{
activityForm.get('date')?.value | date: defaultDateFormat
}}</mat-error
>
}
</mat-form-field> </mat-form-field>
@if ( @if (
currentMarketPrice && currentMarketPrice &&
@ -263,36 +246,6 @@
} }
</div> </div>
</div> </div>
<div class="d-none">
<mat-form-field appearance="outline" class="w-100">
<mat-label>
@switch (activityForm.get('type')?.value) {
@case ('DIVIDEND') {
<ng-container i18n>Dividend</ng-container>
}
@case ('FEE') {
<ng-container i18n>Value</ng-container>
}
@case ('INTEREST') {
<ng-container i18n>Value</ng-container>
}
@case ('ITEM') {
<ng-container i18n>Value</ng-container>
}
@case ('LIABILITY') {
<ng-container i18n>Value</ng-container>
}
@default {
<ng-container i18n>Unit Price</ng-container>
}
}
</mat-label>
<input formControlName="unitPrice" matInput type="number" />
<span class="ml-2" matTextSuffix>{{
activityForm.get('currency').value
}}</span>
</mat-form-field>
</div>
<div <div
class="mb-3" class="mb-3"
[ngClass]="{ [ngClass]="{
@ -304,7 +257,7 @@
> >
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Fee</mat-label> <mat-label i18n>Fee</mat-label>
<input formControlName="feeInCustomCurrency" matInput type="number" /> <input formControlName="fee" matInput type="number" />
<div <div
class="ml-2" class="ml-2"
matTextSuffix matTextSuffix
@ -312,26 +265,6 @@
> >
{{ activityForm.get('currencyOfUnitPrice').value }} {{ activityForm.get('currencyOfUnitPrice').value }}
</div> </div>
@if (activityForm.get('feeInCustomCurrency').hasError('invalid')) {
<mat-error
><ng-container i18n
>Oops! Could not get the historical exchange rate
from</ng-container
>
{{
activityForm.get('date')?.value | date: defaultDateFormat
}}</mat-error
>
}
</mat-form-field>
</div>
<div class="d-none">
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Fee</mat-label>
<input formControlName="fee" matInput type="number" />
<span class="ml-2" matTextSuffix>{{
activityForm.get('currency').value
}}</span>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="mb-3"> <div class="mb-3">
@ -392,7 +325,8 @@
[isCurrency]="true" [isCurrency]="true"
[locale]="data.user?.settings?.locale" [locale]="data.user?.settings?.locale"
[unit]=" [unit]="
activityForm.get('currency')?.value ?? data.user?.settings?.baseCurrency activityForm.get('currencyOfUnitPrice')?.value ??
data.user?.settings?.baseCurrency
" "
[value]="total" [value]="total"
/> />

2
libs/ui/src/lib/activities-table/activities-table.component.html

@ -280,7 +280,7 @@
class="d-none d-lg-table-cell px-1" class="d-none d-lg-table-cell px-1"
mat-cell mat-cell
> >
{{ element.SymbolProfile?.currency }} {{ element.currency }}
</td> </td>
</ng-container> </ng-container>

Loading…
Cancel
Save