From 3332f58376639a8c313f8cdc14bb3c6e82d4b4fd Mon Sep 17 00:00:00 2001 From: Neil <55785687+carkom@users.noreply.github.com> Date: Mon, 24 Jun 2024 20:08:59 +0100 Subject: [PATCH] Custom Reports: Adjust Net values (#2871) * Add Net value * notes * fix * revert changes * balanceTypeOpType * lint fix * add net numbers * bar fix * nit fixes and fix clicks * remove abs --- .../src/components/reports/ReportOptions.ts | 2 + .../src/components/reports/ReportSummary.tsx | 17 ++++--- .../src/components/reports/disabledList.ts | 8 ++-- .../components/reports/graphs/AreaGraph.tsx | 25 +++++++++-- .../components/reports/graphs/BarGraph.tsx | 35 ++++++++++++--- .../components/reports/graphs/DonutGraph.tsx | 9 ++-- .../components/reports/graphs/LineGraph.tsx | 7 ++- .../reports/graphs/StackedBarGraph.tsx | 8 +++- .../components/reports/graphs/showActivity.ts | 12 ++--- .../reports/graphs/tableGraph/ReportTable.tsx | 3 +- .../graphs/tableGraph/ReportTableHeader.tsx | 7 ++- .../graphs/tableGraph/ReportTableList.tsx | 2 + .../graphs/tableGraph/ReportTableRow.tsx | 7 ++- .../graphs/tableGraph/ReportTableTotals.tsx | 2 + .../reports/reports/CustomReport.tsx | 5 ++- .../reports/spreadsheets/calculateLegend.ts | 3 +- .../spreadsheets/custom-spreadsheet.ts | 45 ++++++++++++++++--- .../reports/spreadsheets/filterEmptyRows.ts | 7 ++- .../spreadsheets/grouped-spreadsheet.ts | 25 ++++++++++- .../reports/spreadsheets/recalculate.ts | 14 ++++-- .../loot-core/src/types/models/reports.d.ts | 13 ++++++ upcoming-release-notes/2871.md | 6 +++ 22 files changed, 210 insertions(+), 52 deletions(-) create mode 100644 upcoming-release-notes/2871.md diff --git a/packages/desktop-client/src/components/reports/ReportOptions.ts b/packages/desktop-client/src/components/reports/ReportOptions.ts index 25fc2555182..6fe42586be1 100644 --- a/packages/desktop-client/src/components/reports/ReportOptions.ts +++ b/packages/desktop-client/src/components/reports/ReportOptions.ts @@ -35,6 +35,8 @@ const balanceTypeOptions = [ { description: 'Payment', format: 'totalDebts' as const }, { description: 'Deposit', format: 'totalAssets' as const }, { description: 'Net', format: 'totalTotals' as const }, + { description: 'Net Payment', format: 'netDebts' as const }, + { description: 'Net Deposit', format: 'netAssets' as const }, ]; const groupByOptions = [ diff --git a/packages/desktop-client/src/components/reports/ReportSummary.tsx b/packages/desktop-client/src/components/reports/ReportSummary.tsx index 9e25d548cfe..88968e67a0a 100644 --- a/packages/desktop-client/src/components/reports/ReportSummary.tsx +++ b/packages/desktop-client/src/components/reports/ReportSummary.tsx @@ -6,7 +6,10 @@ import { integerToCurrency, amountToInteger, } from 'loot-core/src/shared/util'; -import { type DataEntity } from 'loot-core/src/types/models/reports'; +import { + type balanceTypeOpType, + type DataEntity, +} from 'loot-core/src/types/models/reports'; import { theme, styles } from '../../style'; import { Text } from '../common/Text'; @@ -19,7 +22,7 @@ type ReportSummaryProps = { startDate: string; endDate: string; data: DataEntity; - balanceTypeOp: 'totalDebts' | 'totalAssets' | 'totalTotals'; + balanceTypeOp: balanceTypeOpType; interval: string; intervalsCount: number; }; @@ -33,9 +36,13 @@ export function ReportSummary({ intervalsCount, }: ReportSummaryProps) { const net = - Math.abs(data.totalDebts) > Math.abs(data.totalAssets) - ? 'PAYMENT' - : 'DEPOSIT'; + balanceTypeOp === 'netAssets' + ? 'DEPOSIT' + : balanceTypeOp === 'netDebts' + ? 'PAYMENT' + : Math.abs(data.totalDebts) > Math.abs(data.totalAssets) + ? 'PAYMENT' + : 'DEPOSIT'; const average = amountToInteger(data[balanceTypeOp]) / intervalsCount; return ( )} + {['netAssets'].includes(balanceTypeOp) && ( + + )} + {['netDebts'].includes(balanceTypeOp) && ( + + )} {['totalTotals'].includes(balanceTypeOp) && ( )} + {['netAssets'].includes(balanceTypeOp) && ( + + )} + {['netDebts'].includes(balanceTypeOp) && ( + + )} {['totalTotals'].includes(balanceTypeOp) && ( { - if (balanceTypeOp === 'totalDebts') { - return -1 * obj.totalDebts; - } else { + if (balanceTypeOp === 'totalTotals' && groupBy === 'Interval') { return obj.totalAssets; } + + if (['totalDebts', 'netDebts'].includes(balanceTypeOp)) { + return -1 * obj[balanceTypeOp]; + } + + return obj[balanceTypeOp]; }; const longestLabelLength = data[splitData] diff --git a/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx b/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx index 3eab0f182d4..d6b02490b9f 100644 --- a/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx @@ -4,7 +4,10 @@ import React, { useState } from 'react'; import { PieChart, Pie, Cell, Sector, ResponsiveContainer } from 'recharts'; import { amountToCurrency } from 'loot-core/src/shared/util'; -import { type DataEntity } from 'loot-core/src/types/models/reports'; +import { + type balanceTypeOpType, + type DataEntity, +} from 'loot-core/src/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../hooks/useAccounts'; @@ -181,7 +184,7 @@ type DonutGraphProps = { data: DataEntity; filters: RuleConditionEntity[]; groupBy: string; - balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; + balanceTypeOp: balanceTypeOpType; compact?: boolean; viewLabels: boolean; showHiddenCategories?: boolean; @@ -209,7 +212,7 @@ export function DonutGraph({ const [pointer, setPointer] = useState(''); const getVal = obj => { - if (balanceTypeOp === 'totalDebts') { + if (['totalDebts', 'netDebts'].includes(balanceTypeOp)) { return -1 * obj[balanceTypeOp]; } else { return obj[balanceTypeOp]; diff --git a/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx b/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx index d47575f88b9..14c53ad28e1 100644 --- a/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx @@ -16,7 +16,10 @@ import { amountToCurrency, amountToCurrencyNoDecimal, } from 'loot-core/src/shared/util'; -import { type DataEntity } from 'loot-core/types/models/reports'; +import { + type balanceTypeOpType, + type DataEntity, +} from 'loot-core/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../hooks/useAccounts'; @@ -115,7 +118,7 @@ type LineGraphProps = { filters: RuleConditionEntity[]; groupBy: string; compact?: boolean; - balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; + balanceTypeOp: balanceTypeOpType; showHiddenCategories?: boolean; showOffBudget?: boolean; interval?: string; diff --git a/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx b/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx index 81463d147d8..309fa8618dc 100644 --- a/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx @@ -17,7 +17,10 @@ import { amountToCurrency, amountToCurrencyNoDecimal, } from 'loot-core/src/shared/util'; -import { type DataEntity } from 'loot-core/src/types/models/reports'; +import { + type balanceTypeOpType, + type DataEntity, +} from 'loot-core/src/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../hooks/useAccounts'; @@ -144,7 +147,7 @@ type StackedBarGraphProps = { groupBy: string; compact?: boolean; viewLabels: boolean; - balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; + balanceTypeOp: balanceTypeOpType; showHiddenCategories?: boolean; showOffBudget?: boolean; interval?: string; @@ -194,6 +197,7 @@ export function StackedBarGraph({ data={data.intervalData} margin={{ top: 0, right: 0, left: leftMargin, bottom: 10 }} style={{ cursor: pointer }} + stackOffset="sign" //stacked by sign > {(!isNarrowWidth || !compact) && ( ; handleScroll: UIEventHandler; groupBy: string; - balanceTypeOp: 'totalDebts' | 'totalTotals' | 'totalAssets'; + balanceTypeOp: balanceTypeOpType; data: DataEntity; filters?: RuleConditionEntity[]; mode: string; diff --git a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableHeader.tsx b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableHeader.tsx index 2dea557dea7..926beef7ecc 100644 --- a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableHeader.tsx +++ b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableHeader.tsx @@ -1,6 +1,9 @@ import React, { type RefObject, type UIEventHandler } from 'react'; -import { type IntervalEntity } from 'loot-core/src/types/models/reports'; +import { + type balanceTypeOpType, + type IntervalEntity, +} from 'loot-core/src/types/models/reports'; import { theme } from '../../../../style'; import { type CSSProperties } from '../../../../style/types'; @@ -12,7 +15,7 @@ type ReportTableHeaderProps = { groupBy: string; interval: string; data: IntervalEntity[]; - balanceTypeOp: 'totalDebts' | 'totalTotals' | 'totalAssets'; + balanceTypeOp: balanceTypeOpType; headerScrollRef: RefObject; handleScroll: UIEventHandler; compact: boolean; diff --git a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableList.tsx b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableList.tsx index f3ba6bad8a2..e26b51367d5 100644 --- a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableList.tsx +++ b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableList.tsx @@ -38,6 +38,8 @@ export function ReportTableList({ date: interval.date, totalAssets: interval.totalAssets, totalDebts: interval.totalDebts, + netAssets: interval.netAssets, + netDebts: interval.netDebts, totalTotals: interval.totalTotals, intervalData: [], categories: [], diff --git a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableRow.tsx b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableRow.tsx index c18cf54c9ca..11a8dea359e 100644 --- a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableRow.tsx +++ b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableRow.tsx @@ -5,7 +5,10 @@ import { amountToInteger, integerToCurrency, } from 'loot-core/src/shared/util'; -import { type GroupedEntity } from 'loot-core/types/models/reports'; +import { + type balanceTypeOpType, + type GroupedEntity, +} from 'loot-core/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../../hooks/useAccounts'; @@ -20,7 +23,7 @@ import { showActivity } from '../showActivity'; type ReportTableRowProps = { item: GroupedEntity; - balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; + balanceTypeOp: balanceTypeOpType; groupBy: string; mode: string; filters?: RuleConditionEntity[]; diff --git a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableTotals.tsx b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableTotals.tsx index 8690fc709e5..ed192f0c4eb 100644 --- a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableTotals.tsx +++ b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableTotals.tsx @@ -85,6 +85,8 @@ export function ReportTableTotals({ intervalData: data.intervalData, totalAssets: data.totalAssets, totalDebts: data.totalDebts, + netAssets: data.netAssets, + netDebts: data.netDebts, totalTotals: data.totalTotals, }; diff --git a/packages/desktop-client/src/components/reports/reports/CustomReport.tsx b/packages/desktop-client/src/components/reports/reports/CustomReport.tsx index 2fb2a375c1b..edeba3fbf22 100644 --- a/packages/desktop-client/src/components/reports/reports/CustomReport.tsx +++ b/packages/desktop-client/src/components/reports/reports/CustomReport.tsx @@ -8,6 +8,7 @@ import * as monthUtils from 'loot-core/src/shared/months'; import { amountToCurrency } from 'loot-core/src/shared/util'; import { type CategoryEntity } from 'loot-core/types/models/category'; import { + type balanceTypeOpType, type CustomReportEntity, type DataEntity, } from 'loot-core/types/models/reports'; @@ -248,7 +249,7 @@ export function CustomReport() { } }, [interval, startDate, endDate, firstDayOfWeekIdx]); - const balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals' = + const balanceTypeOp: balanceTypeOpType = ReportOptions.balanceTypeMap.get(balanceType) || 'totalDebts'; const payees = usePayees(); const accounts = useAccounts(); @@ -692,7 +693,7 @@ export function CustomReport() { right={ - {amountToCurrency(Math.abs(data[balanceTypeOp]))} + {amountToCurrency(data[balanceTypeOp])} } diff --git a/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts b/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts index 7ada7dec8d9..93a80014fee 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts @@ -2,6 +2,7 @@ import { type LegendEntity, type IntervalEntity, type GroupedEntity, + type balanceTypeOpType, } from 'loot-core/src/types/models/reports'; import { theme } from '../../../style'; @@ -12,7 +13,7 @@ export function calculateLegend( calcDataFiltered: GroupedEntity[], groupBy: string, graphType?: string, - balanceTypeOp?: 'totalAssets' | 'totalDebts' | 'totalTotals', + balanceTypeOp?: balanceTypeOpType, ): LegendEntity[] { const colorScale = getColorScale('qualitative'); const chooseData = diff --git a/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts index 0ad83924bf9..86a2fd6ebeb 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts @@ -13,6 +13,7 @@ import { type CategoryGroupEntity, } from 'loot-core/src/types/models'; import { + type balanceTypeOpType, type DataEntity, type GroupedEntity, type IntervalEntity, @@ -46,7 +47,7 @@ export type createCustomSpreadsheetProps = { showHiddenCategories: boolean; showUncategorized: boolean; groupBy?: string; - balanceTypeOp?: 'totalAssets' | 'totalDebts' | 'totalTotals'; + balanceTypeOp?: balanceTypeOpType; payees?: PayeeEntity[]; accounts?: AccountEntity[]; graphType?: string; @@ -153,11 +154,16 @@ export function createCustomSpreadsheet({ let totalAssets = 0; let totalDebts = 0; + let netAssets = 0; + let netDebts = 0; const intervalData = intervals.reduce( (arr: IntervalEntity[], intervalItem, index) => { let perIntervalAssets = 0; let perIntervalDebts = 0; + let perIntervalNetAssets = 0; + let perIntervalNetDebts = 0; + let perIntervalTotals = 0; const stacked: Record = {}; groupByList.map(item => { @@ -193,20 +199,43 @@ export function createCustomSpreadsheet({ .reduce((a, v) => (a = a + v.amount), 0); perIntervalDebts += intervalDebts; + const netAmounts = intervalAssets + intervalDebts; + if (balanceTypeOp === 'totalAssets') { stackAmounts += intervalAssets; } if (balanceTypeOp === 'totalDebts') { - stackAmounts += intervalDebts; + stackAmounts += Math.abs(intervalDebts); + } + if (balanceTypeOp === 'netAssets') { + stackAmounts += netAmounts > 0 ? netAmounts : 0; + } + if (balanceTypeOp === 'netDebts') { + stackAmounts = netAmounts < 0 ? Math.abs(netAmounts) : 0; + } + if (balanceTypeOp === 'totalTotals') { + stackAmounts += netAmounts; } if (stackAmounts !== 0) { - stacked[item.name] = integerToAmount(Math.abs(stackAmounts)); + stacked[item.name] = integerToAmount(stackAmounts); } + perIntervalNetAssets = + netAmounts > 0 + ? perIntervalNetAssets + netAmounts + : perIntervalNetAssets; + perIntervalNetDebts = + netAmounts < 0 + ? perIntervalNetDebts + netAmounts + : perIntervalNetDebts; + perIntervalTotals += netAmounts; + return null; }); totalAssets += perIntervalAssets; totalDebts += perIntervalDebts; + netAssets += perIntervalNetAssets; + netDebts += perIntervalNetDebts; arr.push({ date: d.format( @@ -219,9 +248,11 @@ export function createCustomSpreadsheet({ index + 1 === intervals.length ? endDate : monthUtils.subDays(intervals[index + 1], 1), - totalDebts: integerToAmount(perIntervalDebts), totalAssets: integerToAmount(perIntervalAssets), - totalTotals: integerToAmount(perIntervalDebts + perIntervalAssets), + totalDebts: integerToAmount(perIntervalDebts), + netAssets: integerToAmount(perIntervalNetAssets), + netDebts: integerToAmount(perIntervalNetDebts), + totalTotals: integerToAmount(perIntervalTotals), }); return arr; @@ -262,8 +293,10 @@ export function createCustomSpreadsheet({ legend, startDate, endDate, - totalDebts: integerToAmount(totalDebts), totalAssets: integerToAmount(totalAssets), + totalDebts: integerToAmount(totalDebts), + netAssets: integerToAmount(netAssets), + netDebts: integerToAmount(netDebts), totalTotals: integerToAmount(totalAssets + totalDebts), }); setDataCheck?.(true); diff --git a/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts b/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts index b133a67da13..922696e9cf7 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts @@ -1,4 +1,7 @@ -import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { + type balanceTypeOpType, + type GroupedEntity, +} from 'loot-core/src/types/models/reports'; export function filterEmptyRows({ showEmpty, @@ -7,7 +10,7 @@ export function filterEmptyRows({ }: { showEmpty: boolean; data: GroupedEntity; - balanceTypeOp?: 'totalAssets' | 'totalDebts' | 'totalTotals'; + balanceTypeOp?: balanceTypeOpType; }): boolean { let showHide: boolean; if (balanceTypeOp === 'totalTotals') { diff --git a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts index ed3048d291d..414bb93a8b2 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts @@ -111,11 +111,16 @@ export function createGroupedSpreadsheet({ group => { let totalAssets = 0; let totalDebts = 0; + let netAssets = 0; + let netDebts = 0; const intervalData = intervals.reduce( (arr: IntervalEntity[], intervalItem) => { let groupedAssets = 0; let groupedDebts = 0; + let groupedNetAssets = 0; + let groupedNetDebts = 0; + let groupedTotals = 0; if (!group.categories) { return []; @@ -151,16 +156,32 @@ export function createGroupedSpreadsheet({ ) .reduce((a, v) => (a = a + v.amount), 0); groupedDebts += intervalDebts; + + const intervalTotals = intervalAssets + intervalDebts; + + groupedNetAssets = + intervalTotals > 0 + ? groupedNetAssets + intervalTotals + : groupedNetAssets; + groupedNetDebts = + intervalTotals < 0 + ? groupedNetDebts + intervalTotals + : groupedNetDebts; + groupedTotals += intervalTotals; }); totalAssets += groupedAssets; totalDebts += groupedDebts; + netAssets += groupedNetAssets; + netDebts += groupedNetDebts; arr.push({ date: intervalItem, totalAssets: integerToAmount(groupedAssets), totalDebts: integerToAmount(groupedDebts), - totalTotals: integerToAmount(groupedDebts + groupedAssets), + netAssets: integerToAmount(groupedNetAssets), + netDebts: integerToAmount(groupedNetDebts), + totalTotals: integerToAmount(groupedTotals), }); return arr; @@ -191,6 +212,8 @@ export function createGroupedSpreadsheet({ name: group.name, totalAssets: integerToAmount(totalAssets), totalDebts: integerToAmount(totalDebts), + netAssets: integerToAmount(netAssets), + netDebts: integerToAmount(netDebts), totalTotals: integerToAmount(totalAssets + totalDebts), intervalData, categories: diff --git a/packages/desktop-client/src/components/reports/spreadsheets/recalculate.ts b/packages/desktop-client/src/components/reports/spreadsheets/recalculate.ts index 3f4bc44b7b4..d0dc1e1c9f9 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/recalculate.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/recalculate.ts @@ -73,14 +73,18 @@ export function recalculate({ .reduce((a, v) => (a = a + v.amount), 0); totalDebts += intervalDebts; + const intervalTotals = intervalAssets + intervalDebts; + const change = last - ? intervalAssets + intervalDebts - amountToInteger(last.totalTotals) + ? intervalTotals - amountToInteger(last.totalTotals) : 0; arr.push({ totalAssets: integerToAmount(intervalAssets), totalDebts: integerToAmount(intervalDebts), - totalTotals: integerToAmount(intervalAssets + intervalDebts), + netAssets: intervalTotals > 0 ? integerToAmount(intervalTotals) : 0, + netDebts: intervalTotals < 0 ? integerToAmount(intervalTotals) : 0, + totalTotals: integerToAmount(intervalTotals), change, intervalStartDate: index === 0 ? startDate : intervalItem, intervalEndDate: @@ -94,12 +98,16 @@ export function recalculate({ [], ); + const totalTotals = totalAssets + totalDebts; + return { id: item.id || '', name: item.name, totalAssets: integerToAmount(totalAssets), totalDebts: integerToAmount(totalDebts), - totalTotals: integerToAmount(totalAssets + totalDebts), + netAssets: totalTotals > 0 ? integerToAmount(totalTotals) : 0, + netDebts: totalTotals < 0 ? integerToAmount(totalTotals) : 0, + totalTotals: integerToAmount(totalTotals), intervalData, }; } diff --git a/packages/loot-core/src/types/models/reports.d.ts b/packages/loot-core/src/types/models/reports.d.ts index d7e04a5f816..da645278614 100644 --- a/packages/loot-core/src/types/models/reports.d.ts +++ b/packages/loot-core/src/types/models/reports.d.ts @@ -25,6 +25,13 @@ export interface CustomReportEntity { tombstone?: boolean; } +export type balanceTypeOpType = + | 'totalAssets' + | 'totalDebts' + | 'totalTotals' + | 'netAssets' + | 'netDebts'; + export type SpendingMonthEntity = Record< string | number, { @@ -68,6 +75,8 @@ export interface DataEntity { endDate?: string; totalDebts: number; totalAssets: number; + netAssets: number; + netDebts: number; totalTotals: number; } @@ -84,6 +93,8 @@ export type IntervalEntity = { intervalEndDate?: string; totalAssets: number; totalDebts: number; + netAssets: number; + netDebts: number; totalTotals: number; }; @@ -95,6 +106,8 @@ export interface GroupedEntity { totalAssets: number; totalDebts: number; totalTotals: number; + netAssets: number; + netDebts: number; categories?: GroupedEntity[]; } diff --git a/upcoming-release-notes/2871.md b/upcoming-release-notes/2871.md new file mode 100644 index 00000000000..6488461265f --- /dev/null +++ b/upcoming-release-notes/2871.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [carkom] +--- + +Custom reports - rework "net" numbers to work more intuitively and allow for greater customization