From 2799dbee3e68217ff70037ddb7af017ee440e6f3 Mon Sep 17 00:00:00 2001
From: Neil <55785687+carkom@users.noreply.github.com>
Date: Wed, 31 Jul 2024 21:35:23 +0100
Subject: [PATCH] Spending Report: Add Last Month (#3132)
* AddLastMonth
* notes
* Add data for last month a year ago
* Adjustments for save button
* spending card fix
* notes
* fix typecheck
* fix averages
---
.../reports/graphs/SpendingGraph.tsx | 29 +++--
.../components/reports/reports/Spending.tsx | 107 +++++++++++++++---
.../reports/reports/SpendingCard.tsx | 15 ++-
.../spreadsheets/spending-spreadsheet.ts | 48 ++++++--
.../loot-core/src/types/models/reports.d.ts | 10 +-
packages/loot-core/src/types/prefs.d.ts | 1 +
upcoming-release-notes/3132.md | 6 +
7 files changed, 178 insertions(+), 38 deletions(-)
create mode 100644 upcoming-release-notes/3132.md
diff --git a/packages/desktop-client/src/components/reports/graphs/SpendingGraph.tsx b/packages/desktop-client/src/components/reports/graphs/SpendingGraph.tsx
index 1592e0b99b..f6ad918a54 100644
--- a/packages/desktop-client/src/components/reports/graphs/SpendingGraph.tsx
+++ b/packages/desktop-client/src/components/reports/graphs/SpendingGraph.tsx
@@ -47,6 +47,7 @@ type CustomTooltipProps = {
thisMonth?: string;
lastYear?: string;
selection?: string;
+ compare?: string;
};
const CustomTooltip = ({
@@ -56,6 +57,7 @@ const CustomTooltip = ({
thisMonth,
lastYear,
selection,
+ compare,
}: CustomTooltipProps) => {
if (active && payload && payload.length) {
const comparison =
@@ -86,7 +88,7 @@ const CustomTooltip = ({
{payload[0].payload.months[thisMonth].cumulative ? (
@@ -125,6 +129,7 @@ type SpendingGraphProps = {
data: SpendingEntity;
compact?: boolean;
mode: string;
+ compare: string;
};
export function SpendingGraph({
@@ -132,12 +137,19 @@ export function SpendingGraph({
data,
compact,
mode,
+ compare,
}: SpendingGraphProps) {
const privacyMode = usePrivacyMode();
const balanceTypeOp = 'cumulative';
- const thisMonth = monthUtils.currentMonth();
- const lastMonth = monthUtils.subMonths(monthUtils.currentMonth(), 1);
- const lastYear = monthUtils.prevYear(monthUtils.currentMonth());
+ const thisMonth = monthUtils.subMonths(
+ monthUtils.currentMonth(),
+ compare === 'thisMonth' ? 0 : 1,
+ );
+ const previousMonth = monthUtils.subMonths(
+ monthUtils.currentMonth(),
+ compare === 'thisMonth' ? 1 : 2,
+ );
+ const lastYear = monthUtils.prevYear(thisMonth);
let selection;
switch (mode) {
case 'average':
@@ -147,7 +159,7 @@ export function SpendingGraph({
selection = lastYear;
break;
default:
- selection = lastMonth;
+ selection = previousMonth;
break;
}
@@ -256,6 +268,7 @@ export function SpendingGraph({
thisMonth={thisMonth}
lastYear={lastYear}
selection={selection}
+ compare={compare}
/>
}
formatter={numberFormatterTooltip}
diff --git a/packages/desktop-client/src/components/reports/reports/Spending.tsx b/packages/desktop-client/src/components/reports/reports/Spending.tsx
index 529c62c06f..82992ae933 100644
--- a/packages/desktop-client/src/components/reports/reports/Spending.tsx
+++ b/packages/desktop-client/src/components/reports/reports/Spending.tsx
@@ -14,6 +14,7 @@ import { AlignedText } from '../../common/AlignedText';
import { Block } from '../../common/Block';
import { Button } from '../../common/Button';
import { Paragraph } from '../../common/Paragraph';
+import { Select } from '../../common/Select';
import { Text } from '../../common/Text';
import { Tooltip } from '../../common/Tooltip';
import { View } from '../../common/View';
@@ -45,15 +46,19 @@ export function Spending() {
);
const [spendingReportTime = 'lastMonth', setSpendingReportTime] =
useLocalPref('spendingReportTime');
+ const [spendingReportCompare = 'thisMonth', setSpendingReportCompare] =
+ useLocalPref('spendingReportCompare');
const [dataCheck, setDataCheck] = useState(false);
+ const [compare, setCompare] = useState(spendingReportCompare);
const [mode, setMode] = useState(spendingReportTime);
const parseFilter = spendingReportFilter && JSON.parse(spendingReportFilter);
const filterSaved =
JSON.stringify(parseFilter.conditions) === JSON.stringify(conditions) &&
parseFilter.conditionsOp === conditionsOp &&
- spendingReportTime === mode;
+ spendingReportTime === mode &&
+ spendingReportCompare === compare;
useEffect(() => {
const checkFilter =
@@ -70,8 +75,9 @@ export function Spending() {
conditions,
conditionsOp,
setDataCheck,
+ compare,
});
- }, [categories, conditions, conditionsOp]);
+ }, [categories, conditions, conditionsOp, compare]);
const data = useReport('default', getGraphData);
const navigate = useNavigate();
@@ -89,6 +95,7 @@ export function Spending() {
}),
);
setSpendingReportTime(mode);
+ setSpendingReportCompare(compare);
};
const showAverage =
@@ -99,12 +106,20 @@ export function Spending() {
) > 0;
const todayDay =
- monthUtils.getDay(monthUtils.currentDay()) - 1 >= 28
+ compare === 'lastMonth'
? 27
- : monthUtils.getDay(monthUtils.currentDay()) - 1;
+ : monthUtils.getDay(monthUtils.currentDay()) - 1 >= 28
+ ? 27
+ : monthUtils.getDay(monthUtils.currentDay()) - 1;
- const showLastYear = Math.abs(data.intervalData[27].lastYear) > 0;
- const showLastMonth = Math.abs(data.intervalData[27].lastMonth) > 0;
+ const showLastYear =
+ Math.abs(
+ data.intervalData[27][
+ compare === 'thisMonth' ? 'lastYear' : 'lastYearPrevious'
+ ],
+ ) > 0;
+ const showPreviousMonth =
+ Math.abs(data.intervalData[27][spendingReportTime]) > 0;
return (
- {showLastMonth && (
+ {showPreviousMonth && (
Spent MTD:}
+ left={
+
+ Spent{' '}
+ {compare === 'thisMonth' ? 'MTD' : 'Last Month'}:
+
+ }
right={
{amountToCurrency(
- Math.abs(data.intervalData[todayDay].thisMonth),
+ Math.abs(
+ data.intervalData[todayDay][
+ compare === 'thisMonth'
+ ? 'thisMonth'
+ : 'lastMonth'
+ ],
+ ),
)}
}
/>
Spent Last MTD:}
+ left={
+
+ Spent{' '}
+ {compare === 'thisMonth'
+ ? ' Last MTD'
+ : '2 Months Ago'}
+ :
+
+ }
right={
{amountToCurrency(
- Math.abs(data.intervalData[todayDay].lastMonth),
+ Math.abs(
+ data.intervalData[todayDay][
+ compare === 'thisMonth'
+ ? 'lastMonth'
+ : 'twoMonthsPrevious'
+ ],
+ ),
)}
@@ -267,7 +307,11 @@ export function Spending() {
)}
{showAverage && (
Spent Average MTD:}
+ left={
+
+ Spent Average{compare === 'thisMonth' && ' MTD'}:
+
+ }
right={
@@ -281,7 +325,7 @@ export function Spending() {
)}
- {!showLastMonth ? (
+ {!showPreviousMonth ? (
Additional data required to generate graph
@@ -298,18 +342,46 @@ export function Spending() {
flexDirection: 'row',
}}
>
+
+ Compare
+
+