From a0badeac605b06ec5deae89070cf243a63743e6e Mon Sep 17 00:00:00 2001 From: Thomas <4159106+dtslvr@users.noreply.github.com> Date: Sat, 10 Jun 2023 16:00:34 +0200 Subject: [PATCH] Add business logic --- apps/api/src/app/order/order.service.ts | 13 +++++-- .../src/app/portfolio/portfolio.controller.ts | 1 + .../src/app/portfolio/portfolio.service.ts | 37 +++++++++++++++---- .../portfolio-summary.component.html | 20 ++++++++++ ...ate-or-update-activity-dialog.component.ts | 27 ++++++++++++++ .../create-or-update-activity-dialog.html | 13 ++++++- .../interfaces/portfolio-summary.interface.ts | 1 + .../activities-table.component.html | 10 ++++- .../activities-table.component.scss | 4 ++ .../migration.sql | 0 10 files changed, 112 insertions(+), 14 deletions(-) rename prisma/migrations/{20230313185544_added_liability_to_order_type => 20230614345544_added_liability_to_order_type}/migration.sql (100%) diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index 696f5442e..cc9718e7d 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -96,7 +96,7 @@ export class OrderService { const updateAccountBalance = data.updateAccountBalance ?? false; const userId = data.userId; - if (data.type === 'ITEM') { + if (data.type === 'ITEM' || data.type === 'LIABILITY') { const assetClass = data.assetClass; const assetSubClass = data.assetSubClass; currency = data.SymbolProfile.connectOrCreate.create.currency; @@ -129,7 +129,10 @@ export class OrderService { } }); - const isDraft = isAfter(data.date as Date, endOfToday()); + const isDraft = + data.type === 'LIABILITY' + ? false + : isAfter(data.date as Date, endOfToday()); if (!isDraft) { // Gather symbol data of order in the background, if not draft @@ -320,7 +323,11 @@ export class OrderService { }) ) .filter((order) => { - return withExcludedAccounts || order.Account?.isExcluded === false; + return ( + withExcludedAccounts || + !order.Account || + order.Account?.isExcluded === false + ); }) .map((order) => { const value = new Big(order.quantity).mul(order.unitPrice).toNumber(); diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 1747936fd..06f841e12 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -162,6 +162,7 @@ export class PortfolioController { 'excludedAccountsAndActivities', 'fees', 'items', + 'liabilities', 'netWorth', 'totalBuy', 'totalSell' diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index aea522f40..c3b41eccf 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1478,19 +1478,37 @@ export class PortfolioService { }; } - private getItems(orders: OrderWithAccount[], date = new Date(0)) { - return orders - .filter((order) => { + private getItems(activities: OrderWithAccount[], date = new Date(0)) { + return activities + .filter((activity) => { // Filter out all orders before given date and type item return ( - isBefore(date, new Date(order.date)) && - order.type === TypeOfOrder.ITEM + isBefore(date, new Date(activity.date)) && + activity.type === TypeOfOrder.ITEM ); }) - .map((order) => { + .map(({ quantity, SymbolProfile, unitPrice }) => { return this.exchangeRateDataService.toCurrency( - new Big(order.quantity).mul(order.unitPrice).toNumber(), - order.SymbolProfile.currency, + new Big(quantity).mul(unitPrice).toNumber(), + SymbolProfile.currency, + this.request.user.Settings.settings.baseCurrency + ); + }) + .reduce( + (previous, current) => new Big(previous).plus(current), + new Big(0) + ); + } + + private getLiabilities(activities: OrderWithAccount[]) { + return activities + .filter(({ type }) => { + return type === TypeOfOrder.LIABILITY; + }) + .map(({ quantity, SymbolProfile, unitPrice }) => { + return this.exchangeRateDataService.toCurrency( + new Big(quantity).mul(unitPrice).toNumber(), + SymbolProfile.currency, this.request.user.Settings.settings.baseCurrency ); }) @@ -1601,6 +1619,7 @@ export class PortfolioService { const fees = this.getFees({ activities, userCurrency }).toNumber(); const firstOrderDate = activities[0]?.date; const items = this.getItems(activities).toNumber(); + const liabilities = this.getLiabilities(activities).toNumber(); const totalBuy = this.getTotalByType(activities, userCurrency, 'BUY'); const totalSell = this.getTotalByType(activities, userCurrency, 'SELL'); @@ -1633,6 +1652,7 @@ export class PortfolioService { .plus(performanceInformation.performance.currentValue) .plus(items) .plus(excludedAccountsAndActivities) + .minus(liabilities) .toNumber(); const daysInMarket = differenceInDays(new Date(), firstOrderDate); @@ -1659,6 +1679,7 @@ export class PortfolioService { fees, firstOrderDate, items, + liabilities, netWorth, totalBuy, totalSell, diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html index 8b507f553..3ceadb048 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -194,6 +194,26 @@