From aff5bba4ec2d528501e49cd48bf6cdb8372e114f Mon Sep 17 00:00:00 2001 From: Julian Dominguez-Schatz <julian.dominguezschatz@gmail.com> Date: Tue, 21 May 2024 10:29:39 -0700 Subject: [PATCH] Template only the relevant amount in a split-schedule category (#2652) * Template only the relevant amount in a split-schedule category * Add release notes * Adjust sign correctly depending on category type --- .../loot-core/src/server/accounts/rules.ts | 5 ++-- .../src/server/budget/goals/goalsSchedule.ts | 27 ++++++++++++++----- .../loot-core/src/server/schedules/app.ts | 2 +- upcoming-release-notes/2652.md | 6 +++++ 4 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 upcoming-release-notes/2652.md diff --git a/packages/loot-core/src/server/accounts/rules.ts b/packages/loot-core/src/server/accounts/rules.ts index ab7ccd11d..96e9cd1d8 100644 --- a/packages/loot-core/src/server/accounts/rules.ts +++ b/packages/loot-core/src/server/accounts/rules.ts @@ -673,17 +673,16 @@ export class Rule { }); } - execActions(object) { + execActions<T>(object: T): Partial<T> { const result = execActions(this.actions, { ...object, - subtransactions: object.subtransactions, }); const changes = Object.keys(result).reduce((prev, cur) => { if (result[cur] !== object[cur]) { prev[cur] = result[cur]; } return prev; - }, {}); + }, {} as T); return changes; } diff --git a/packages/loot-core/src/server/budget/goals/goalsSchedule.ts b/packages/loot-core/src/server/budget/goals/goalsSchedule.ts index 6efdd323c..8d9045325 100644 --- a/packages/loot-core/src/server/budget/goals/goalsSchedule.ts +++ b/packages/loot-core/src/server/budget/goals/goalsSchedule.ts @@ -22,15 +22,28 @@ async function createScheduleList(template, current_month, category) { const conditions = rule.serialize().conditions; const { date: dateConditions, amount: amountCondition } = extractScheduleConds(conditions); - const sign = category.is_income ? 1 : -1; - const target = + const scheduleAmount = amountCondition.op === 'isbetween' - ? (sign * - Math.round( - amountCondition.value.num1 + amountCondition.value.num2, - )) / + ? Math.round(amountCondition.value.num1 + amountCondition.value.num2) / 2 - : sign * amountCondition.value; + : amountCondition.value; + const { amount: postRuleAmount, subtransactions } = rule.execActions({ + amount: scheduleAmount, + category: category.id, + subtransactions: [], + }); + const categorySubtransactions = subtransactions?.filter( + t => t.category === category.id, + ); + + // Unless the current category is relevant to the schedule, target the post-rule amount. + const sign = category.is_income ? 1 : -1; + const target = + sign * + (categorySubtransactions?.length + ? categorySubtransactions.reduce((acc, t) => acc + t.amount, 0) + : postRuleAmount ?? scheduleAmount); + const next_date_string = getNextDate( dateConditions, monthUtils._parse(current_month), diff --git a/packages/loot-core/src/server/schedules/app.ts b/packages/loot-core/src/server/schedules/app.ts index 1bd4c0eb0..ea99443d4 100644 --- a/packages/loot-core/src/server/schedules/app.ts +++ b/packages/loot-core/src/server/schedules/app.ts @@ -107,7 +107,7 @@ export function getNextDate( return null; } -export async function getRuleForSchedule(id) { +export async function getRuleForSchedule(id: string | null): Promise<Rule> { if (id == null) { throw new Error('Schedule not attached to a rule'); } diff --git a/upcoming-release-notes/2652.md b/upcoming-release-notes/2652.md new file mode 100644 index 000000000..3196e7ddd --- /dev/null +++ b/upcoming-release-notes/2652.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [jfdoming] +--- + +Template only the relevant amount in a split-schedule category -- GitLab