From 7d80c3eda6694f219d82ff0457944c8c7157b21e Mon Sep 17 00:00:00 2001
From: youngcw <calebyoung94@gmail.com>
Date: Sun, 7 May 2023 06:35:04 -0700
Subject: [PATCH] Goal Templates: add option to prevent removing funds when
 using "up to" in goal (#1004)

---
 .../loot-core/src/server/budget/goal-template.pegjs   |  6 ++++--
 packages/loot-core/src/server/budget/goaltemplates.ts | 11 ++++++++---
 upcoming-release-notes/1004.md                        |  6 ++++++
 3 files changed, 18 insertions(+), 5 deletions(-)
 create mode 100644 upcoming-release-notes/1004.md

diff --git a/packages/loot-core/src/server/budget/goal-template.pegjs b/packages/loot-core/src/server/budget/goal-template.pegjs
index 164602a51..26b7ac630 100644
--- a/packages/loot-core/src/server/budget/goal-template.pegjs
+++ b/packages/loot-core/src/server/budget/goal-template.pegjs
@@ -16,7 +16,7 @@ expr
     } }
   / priority: priority? _? monthly: amount limit: limit?
     { return { type: 'simple', monthly, limit, priority: +priority  } }
-  / priority: priority? _? upTo _ limit: amount
+  / priority: priority? _? limit: limit
     { return { type: 'simple', limit , priority: +priority } }
   / priority: priority? _? schedule _ name: name
     { return { type: 'schedule', name, priority: +priority } }
@@ -27,7 +27,9 @@ repeat 'repeat interval'
   / 'year'i { return { annual: true } }
   / years: d _ 'years'i { return { annual: true, repeat: +years } }
 
-limit = _ upTo? _ amount: amount { return amount }
+limit =  _? upTo _ amount: amount _ 'hold'i { return {amount: amount, hold: true } }
+		/ _? upTo _ amount: amount { return {amount: amount, hold: false } }
+
 
 weekCount
   = week { return null }
diff --git a/packages/loot-core/src/server/budget/goaltemplates.ts b/packages/loot-core/src/server/budget/goaltemplates.ts
index 805e4ad16..f1772935c 100644
--- a/packages/loot-core/src/server/budget/goaltemplates.ts
+++ b/packages/loot-core/src/server/budget/goaltemplates.ts
@@ -299,6 +299,7 @@ async function applyCategoryTemplate(
   let budgetAvailable = await getSheetValue(sheetName, `to-budget`);
   let to_budget = budgeted;
   let limit;
+  let hold;
   let last_month_balance = balance - spent - budgeted;
   let totalTarget = 0;
   let totalMonths = 0;
@@ -313,7 +314,8 @@ async function applyCategoryTemplate(
             errors.push(`More than one “up to” limit found.`);
             return { errors };
           } else {
-            limit = amountToInteger(template.limit);
+            limit = amountToInteger(template.limit.amount);
+            hold = template.limit.hold;
           }
         }
         let increment = 0;
@@ -381,7 +383,8 @@ async function applyCategoryTemplate(
             errors.push(`More than one “up to” limit found.`);
             return { errors };
           } else {
-            limit = amountToInteger(template.limit);
+            limit = amountToInteger(template.limit.amount);
+            hold = template.limit.hold;
           }
         }
         let w = new Date(template.starting);
@@ -548,7 +551,9 @@ async function applyCategoryTemplate(
   }
 
   if (limit != null) {
-    if (to_budget + last_month_balance > limit) {
+    if (hold && balance > limit) {
+      to_budget = 0;
+    } else if (to_budget + last_month_balance > limit) {
       to_budget = limit - last_month_balance;
     }
   }
diff --git a/upcoming-release-notes/1004.md b/upcoming-release-notes/1004.md
new file mode 100644
index 000000000..ec7d62d16
--- /dev/null
+++ b/upcoming-release-notes/1004.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [youngcw]
+---
+
+Add option to not remove funds when using an "up to" goal template.
-- 
GitLab