diff --git a/packages/desktop-client/src/components/reports/ReportOptions.ts b/packages/desktop-client/src/components/reports/ReportOptions.ts index 3d582ca7234..f13e873b684 100644 --- a/packages/desktop-client/src/components/reports/ReportOptions.ts +++ b/packages/desktop-client/src/components/reports/ReportOptions.ts @@ -121,6 +121,16 @@ const dateRangeOptions: dateRangeProps[] = [ Monthly: true, Yearly: false, }, + { + description: t('Last 30 days'), + key: 'Last 30 days', + name: 'last30Days', + type: 'Day', + Daily: true, + Weekly: true, + Monthly: true, + Yearly: false, + }, { description: t('Last 3 months'), key: 'Last 3 months', diff --git a/packages/desktop-client/src/components/reports/disabledList.ts b/packages/desktop-client/src/components/reports/disabledList.ts index f5c07a0dcd6..52a922b74e1 100644 --- a/packages/desktop-client/src/components/reports/disabledList.ts +++ b/packages/desktop-client/src/components/reports/disabledList.ts @@ -34,6 +34,10 @@ const currentIntervalOptions = [ description: t('This month'), disableInclude: true, }, + { + description: t('Last 30 days'), + disableInclude: true, + }, { description: t('Year to date'), disableInclude: true, diff --git a/packages/desktop-client/src/components/reports/getLiveRange.test.ts b/packages/desktop-client/src/components/reports/getLiveRange.test.ts new file mode 100644 index 00000000000..476dabb632d --- /dev/null +++ b/packages/desktop-client/src/components/reports/getLiveRange.test.ts @@ -0,0 +1,65 @@ +import { getLiveRange } from './getLiveRange'; + +// In test mode, monthUtils.currentDay() returns '2017-01-01' +const EARLIEST = '2015-01-01'; +const LATEST = '2017-01-01'; + +describe('getLiveRange', () => { + describe('Last 30 days', () => { + it('returns the last 30 days ending today', () => { + const [start, end] = getLiveRange( + 'Last 30 days', + EARLIEST, + LATEST, + false, + ); + // currentDay() = '2017-01-01', so 29 days before = '2016-12-03' + expect(start).toBe('2016-12-03'); + expect(end).toBe('2017-01-01'); + }); + + it('is not affected by the includeCurrentInterval flag', () => { + const [startExclude, endExclude] = getLiveRange( + 'Last 30 days', + EARLIEST, + LATEST, + false, + ); + const [startInclude, endInclude] = getLiveRange( + 'Last 30 days', + EARLIEST, + LATEST, + true, + ); + expect(startExclude).toBe(startInclude); + expect(endExclude).toBe(endInclude); + }); + + it('clamps start date to earliestTransaction when data is scarce', () => { + const [start, end] = getLiveRange( + 'Last 30 days', + '2016-12-20', + LATEST, + false, + ); + expect(start).toBe('2016-12-20'); + expect(end).toBe('2017-01-01'); + }); + + it('clamps end date to latestTransaction when it precedes today', () => { + const [start, end] = getLiveRange( + 'Last 30 days', + EARLIEST, + '2016-12-25', + false, + ); + expect(start).toBe('2016-12-03'); + expect(end).toBe('2016-12-25'); + }); + + it('returns sliding-window mode', () => { + const [, , mode] = getLiveRange('Last 30 days', EARLIEST, LATEST, false); + expect(mode).toBe('sliding-window'); + }); + }); +}); diff --git a/packages/desktop-client/src/components/reports/getLiveRange.ts b/packages/desktop-client/src/components/reports/getLiveRange.ts index 91634e88b3d..c80a54f5444 100644 --- a/packages/desktop-client/src/components/reports/getLiveRange.ts +++ b/packages/desktop-client/src/components/reports/getLiveRange.ts @@ -58,6 +58,15 @@ export function getLiveRange( ); break; } + case 'last30Days': { + [dateStart, dateEnd] = validateRange( + earliestTransaction, + latestTransaction, + monthUtils.subDays(monthUtils.currentDay(), 29), + monthUtils.currentDay(), + ); + break; + } case 'allTime': { dateStart = earliestTransaction; dateEnd = latestTransaction; diff --git a/upcoming-release-notes/7217.md b/upcoming-release-notes/7217.md new file mode 100644 index 00000000000..b447e74009e --- /dev/null +++ b/upcoming-release-notes/7217.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [kenkuo] +--- + +Add "Last 30 days" date range option to custom reports live mode