diff --git a/packages/desktop-client/src/components/reports/graphs/SpendingGraph.tsx b/packages/desktop-client/src/components/reports/graphs/SpendingGraph.tsx
index 2aadf407dcf..60b2b4f78ae 100644
--- a/packages/desktop-client/src/components/reports/graphs/SpendingGraph.tsx
+++ b/packages/desktop-client/src/components/reports/graphs/SpendingGraph.tsx
@@ -45,6 +45,7 @@ type CustomTooltipProps = {
payload?: PayloadItem[];
balanceTypeOp?: string;
thisMonth?: string;
+ lastYear?: string;
selection?: string;
};
@@ -53,6 +54,7 @@ const CustomTooltip = ({
payload,
balanceTypeOp,
thisMonth,
+ lastYear,
selection,
}: CustomTooltipProps) => {
if (active && payload && payload.length) {
@@ -82,21 +84,27 @@ const CustomTooltip = ({
- {payload[0].payload.months[thisMonth].cumulative && (
+ {payload[0].payload.months[thisMonth].cumulative ? (
- )}
+ ) : null}
{['cumulative'].includes(balanceTypeOp) && (
)}
- {payload[0].payload.months[thisMonth].cumulative && (
+ {payload[0].payload.months[thisMonth].cumulative ? (
- )}
+ ) : null}
@@ -129,7 +137,20 @@ export function SpendingGraph({
const balanceTypeOp = 'cumulative';
const thisMonth = monthUtils.currentMonth();
const lastMonth = monthUtils.subMonths(monthUtils.currentMonth(), 1);
- const selection = mode.toLowerCase() === 'average' ? 'average' : lastMonth;
+ const lastYear = monthUtils.prevYear(monthUtils.currentMonth());
+ let selection;
+ switch (mode) {
+ case 'Average':
+ selection = 'average';
+ break;
+ case 'lastYear':
+ selection = lastYear;
+ break;
+ default:
+ selection = lastMonth;
+ break;
+ }
+
const thisMonthMax = data.intervalData.reduce((a, b) =>
a.months[thisMonth][balanceTypeOp] < b.months[thisMonth][balanceTypeOp]
? a
@@ -139,11 +160,11 @@ export function SpendingGraph({
selection === 'average'
? data.intervalData[27].average
: data.intervalData.reduce((a, b) =>
- a.months[lastMonth][balanceTypeOp] <
- b.months[lastMonth][balanceTypeOp]
+ a.months[selection][balanceTypeOp] <
+ b.months[selection][balanceTypeOp]
? a
: b,
- ).months[lastMonth][balanceTypeOp];
+ ).months[selection][balanceTypeOp];
const maxYAxis = selectionMax > thisMonthMax;
const dataMax = Math.max(
...data.intervalData.map(i => i.months[thisMonth].cumulative),
@@ -233,6 +254,7 @@ export function SpendingGraph({
}
diff --git a/packages/desktop-client/src/components/reports/reports/Spending.tsx b/packages/desktop-client/src/components/reports/reports/Spending.tsx
index 5b6dc4aee24..5f54faaaf78 100644
--- a/packages/desktop-client/src/components/reports/reports/Spending.tsx
+++ b/packages/desktop-client/src/components/reports/reports/Spending.tsx
@@ -38,7 +38,7 @@ export function Spending() {
} = useFilters();
const [dataCheck, setDataCheck] = useState(false);
- const [mode, setMode] = useState('Last month');
+ const [mode, setMode] = useState('lastMonth');
const getGraphData = useMemo(() => {
setDataCheck(false);
@@ -57,15 +57,21 @@ export function Spending() {
if (!data) {
return null;
}
+
const showAverage =
- data.intervalData[27].months[
- monthUtils.subMonths(monthUtils.currentDay(), 3)
- ].daily !== 0;
+ Math.abs(
+ data.intervalData[27].months[
+ monthUtils.subMonths(monthUtils.currentDay(), 3)
+ ].cumulative,
+ ) > 0;
+
const todayDay =
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;
return (
- Spent MTD:}
- right={
-
-
- {amountToCurrency(
- Math.abs(data.intervalData[todayDay].thisMonth),
- )}
-
-
- }
- />
- Spent Last MTD:}
- right={
-
-
- {amountToCurrency(
- Math.abs(data.intervalData[todayDay].lastMonth),
- )}
-
-
- }
- />
+ {showLastMonth && (
+
+ Spent MTD:}
+ right={
+
+
+ {amountToCurrency(
+ Math.abs(data.intervalData[todayDay].thisMonth),
+ )}
+
+
+ }
+ />
+ Spent Last MTD:}
+ right={
+
+
+ {amountToCurrency(
+ Math.abs(data.intervalData[todayDay].lastMonth),
+ )}
+
+
+ }
+ />
+
+ )}
{showAverage && (
Spent Average MTD:}
@@ -211,46 +227,66 @@ export function Spending() {
)}
-
-
- Compare this month to:
-
- setMode('Last month')}
- >
- Last month
-
- {showAverage && (
- setMode('Average')}
+ {!showLastMonth ? (
+
+ Additional data required to generate graph
+
+ Currently, there is insufficient data to display any
+ information regarding your spending. Please input
+ transactions from last month to enable graph visualization.
+
+
+ ) : (
+ <>
+
- Average
-
- )}
-
+
+ Compare this month to:
+
+ setMode('lastMonth')}
+ >
+ Last month
+
+ {showLastYear && (
+ setMode('lastYear')}
+ >
+ Last year
+
+ )}
+ {showAverage && (
+ setMode('Average')}
+ >
+ Average
+
+ )}
+
- {dataCheck ? (
-
- ) : (
-
+ {dataCheck ? (
+
+ ) : (
+
+ )}
+ >
)}
-
{showAverage && (
diff --git a/packages/desktop-client/src/components/reports/reports/SpendingCard.tsx b/packages/desktop-client/src/components/reports/reports/SpendingCard.tsx
index 8a11dd3428c..d999494ed9b 100644
--- a/packages/desktop-client/src/components/reports/reports/SpendingCard.tsx
+++ b/packages/desktop-client/src/components/reports/reports/SpendingCard.tsx
@@ -36,6 +36,7 @@ export function SpendingCard() {
data &&
data.intervalData[todayDay].lastMonth -
data.intervalData[todayDay].thisMonth;
+ const showLastMonth = data && Math.abs(data.intervalData[27].lastMonth) > 0;
return (
@@ -57,7 +58,7 @@ export function SpendingCard() {
end={monthUtils.currentMonth()}
/>
- {data && (
+ {data && showLastMonth && (
)}
-
- {data ? (
+ {!showLastMonth ? (
+
+
+ Additional data required to generate graph
+
+
+ ) : data ? (
) : (
-
+
)}
diff --git a/packages/desktop-client/src/components/reports/spreadsheets/spending-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/spending-spreadsheet.ts
index 79981b47a77..205a1b160b3 100644
--- a/packages/desktop-client/src/components/reports/spreadsheets/spending-spreadsheet.ts
+++ b/packages/desktop-client/src/components/reports/spreadsheets/spending-spreadsheet.ts
@@ -1,5 +1,4 @@
// @ts-strict-ignore
-
import keyBy from 'lodash/keyBy';
import { runQuery } from 'loot-core/src/client/query-helpers';
@@ -35,6 +34,11 @@ export function createSpendingSpreadsheet({
setDataCheck,
}: createSpendingSpreadsheetProps) {
const [startDate, endDate] = getSpecificRange(3, null, 'Months');
+ const [lastYearStartDate, lastYearEndDate] = getSpecificRange(
+ 12,
+ 0,
+ 'Months',
+ );
const interval = 'Daily';
return async (
@@ -50,7 +54,7 @@ export function createSpendingSpreadsheet({
runQuery(
makeQuery(
'assets',
- startDate,
+ lastYearStartDate,
endDate,
interval,
categories.list,
@@ -61,7 +65,7 @@ export function createSpendingSpreadsheet({
runQuery(
makeQuery(
'debts',
- startDate,
+ lastYearStartDate,
endDate,
interval,
categories.list,
@@ -72,6 +76,9 @@ export function createSpendingSpreadsheet({
]);
const intervals = monthUtils.dayRangeInclusive(startDate, endDate);
+ intervals.push(
+ ...monthUtils.dayRangeInclusive(lastYearStartDate, lastYearEndDate),
+ );
const days = [...Array(29).keys()]
.filter(f => f > 0)
.map(n => n.toString().padStart(2, '0'));
@@ -85,6 +92,12 @@ export function createSpendingSpreadsheet({
return { month, perMonthAssets: 0, perMonthDebts: 0 };
});
+ months.unshift({
+ month: monthUtils.prevYear(monthUtils.currentMonth()),
+ perMonthAssets: 0,
+ perMonthDebts: 0,
+ });
+
const intervalData = days.map(day => {
let averageSum = 0;
let monthCount = 0;
@@ -126,7 +139,10 @@ export function createSpendingSpreadsheet({
}
return null;
});
- if (month.month !== monthUtils.currentMonth()) {
+ if (
+ month.month !== monthUtils.currentMonth() &&
+ month.month !== monthUtils.prevYear(monthUtils.currentMonth())
+ ) {
averageSum += cumulativeAssets + cumulativeDebts;
monthCount += 1;
}
@@ -165,8 +181,9 @@ export function createSpendingSpreadsheet({
months: indexedData,
day,
average: integerToAmount(averageSum) / monthCount,
- thisMonth: dayData[3].cumulative,
- lastMonth: dayData[2].cumulative,
+ thisMonth: dayData[4].cumulative,
+ lastMonth: dayData[3].cumulative,
+ lastYear: dayData[0].cumulative,
};
});
diff --git a/packages/loot-core/src/types/models/reports.d.ts b/packages/loot-core/src/types/models/reports.d.ts
index eccc1c79f99..42ed96875b3 100644
--- a/packages/loot-core/src/types/models/reports.d.ts
+++ b/packages/loot-core/src/types/models/reports.d.ts
@@ -49,6 +49,7 @@ export interface SpendingEntity {
average: number;
thisMonth: number;
lastMonth: number;
+ lastYear: number;
}[];
startDate?: string;
endDate?: string;
diff --git a/upcoming-release-notes/2806.md b/upcoming-release-notes/2806.md
new file mode 100644
index 00000000000..bfeb7b8b1d5
--- /dev/null
+++ b/upcoming-release-notes/2806.md
@@ -0,0 +1,6 @@
+---
+category: Features
+authors: [Crazypkr1099]
+---
+
+Add Year Spending Comparison Feature