From 4ed9f4fff492eca18842a3c92b2ed2c173e85bcb Mon Sep 17 00:00:00 2001 From: youngcw <calebyoung94@gmail.com> Date: Tue, 30 Apr 2024 12:19:31 -0700 Subject: [PATCH] [Goals]add template to set x month average (#2688) * add template to set x month average * error on 0 * note * lint --- .../src/server/budget/goal-template.pegjs | 2 ++ .../src/server/budget/goals/goalsAverage.ts | 31 +++++++++++++++++++ .../src/server/budget/goaltemplates.ts | 13 ++++++++ upcoming-release-notes/2688.md | 6 ++++ 4 files changed, 52 insertions(+) create mode 100644 packages/loot-core/src/server/budget/goals/goalsAverage.ts create mode 100644 upcoming-release-notes/2688.md diff --git a/packages/loot-core/src/server/budget/goal-template.pegjs b/packages/loot-core/src/server/budget/goal-template.pegjs index 094ece260..4e93301e7 100644 --- a/packages/loot-core/src/server/budget/goal-template.pegjs +++ b/packages/loot-core/src/server/budget/goal-template.pegjs @@ -22,6 +22,8 @@ expr { return { type: 'schedule', name, priority: +priority, full } } / priority: priority? _? remainder: remainder { return { type: 'remainder', priority: null, weight: remainder } } + / priority: priority? _? 'average'i _ amount: positive _ 'months'i? + { return { type: 'average', amount: +amount, priority: +priority }} repeat 'repeat interval' diff --git a/packages/loot-core/src/server/budget/goals/goalsAverage.ts b/packages/loot-core/src/server/budget/goals/goalsAverage.ts new file mode 100644 index 000000000..44151a59d --- /dev/null +++ b/packages/loot-core/src/server/budget/goals/goalsAverage.ts @@ -0,0 +1,31 @@ +// @ts-strict-ignore + +import * as monthUtils from '../../../shared/months'; +import { getSheetValue } from '../actions'; + +export async function goalsAverage( + template, + month, + category, + errors, + to_budget, +) { + // simple has an 'amount' param + let increment = 0; + if (template.amount) { + let sum = 0; + for (let i = 1; i <= template.amount; i++) { + // add up other months + const sheetName = monthUtils.sheetForMonth( + monthUtils.subMonths(month, i), + ); + sum += await getSheetValue(sheetName, `sum-amount-${category.id}`); + } + increment = sum / template.amount; + } else { + errors.push('Number of months to average is not valid'); + return { to_budget, errors }; + } + to_budget += -Math.round(increment); + return { to_budget, errors }; +} diff --git a/packages/loot-core/src/server/budget/goaltemplates.ts b/packages/loot-core/src/server/budget/goaltemplates.ts index d2d698490..aed1be666 100644 --- a/packages/loot-core/src/server/budget/goaltemplates.ts +++ b/packages/loot-core/src/server/budget/goaltemplates.ts @@ -7,6 +7,7 @@ import { batchMessages } from '../sync'; import { setBudget, getSheetValue, isReflectBudget, setGoal } from './actions'; import { parse } from './goal-template.pegjs'; +import { goalsAverage } from './goals/goalsAverage'; import { goalsBy } from './goals/goalsBy'; import { goalsPercentage } from './goals/goalsPercentage'; import { findRemainder, goalsRemainder } from './goals/goalsRemainder'; @@ -609,6 +610,18 @@ async function applyCategoryTemplate( to_budget = goalsReturn.to_budget; break; } + case 'average': { + const goalsReturn = await goalsAverage( + template, + current_month, + category, + errors, + to_budget, + ); + to_budget = goalsReturn.to_budget; + errors = goalsReturn.errors; + break; + } case 'error': return { errors }; default: diff --git a/upcoming-release-notes/2688.md b/upcoming-release-notes/2688.md new file mode 100644 index 000000000..f43506618 --- /dev/null +++ b/upcoming-release-notes/2688.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [youngcw] +--- + +Goals: Add template to budget X months average spending. Matches the funcion of the existing budget page button. -- GitLab