Skip to content
Snippets Groups Projects
Unverified Commit ed285e9a authored by youngcw's avatar youngcw Committed by GitHub
Browse files

Goals: Remainder option (#1101)

Added the option to add a remainder goal template. This will use the
remaining available funds and dump them into the respective category.
There is optional weighting. The remainder templates will be forced to
the lowest priority as to run after all other templates.

Usage: `#template remainder <weight>` Add the template line to any
categories you want to catch any remaining funds such as savings. The
amount added to the category will equal
`remaining_budget/total_of_weights*weight`. The default weight is 1.
parent c42d1789
No related branches found
No related tags found
No related merge requests found
......@@ -15,12 +15,14 @@ expr
priority: +priority
} }
/ priority: priority? _? monthly: amount limit: limit?
{ return { type: 'simple', monthly, limit, priority: +priority } }
{ return { type: 'simple', monthly, limit, priority: +priority } }
/ priority: priority? _? limit: limit
{ return { type: 'simple', limit , priority: +priority } }
/ priority: priority? _? schedule _ full:full? name: name
{ return { type: 'schedule', name, priority: +priority, full } }
{ return { type: 'schedule', name, priority: +priority, full } }
/ priority: priority? _? remainder: remainder
{ return { type: 'remainder', priority: null, weight: remainder } }
repeat 'repeat interval'
= 'month'i { return { annual: false } }
......@@ -48,6 +50,7 @@ upTo = 'up'i _ 'to'i
schedule = 'schedule'i
full = 'full'i _ {return true}
priority = '-'i number: number _ {return number}
remainder = 'remainder'i _? weight: positive? { return +weight || 1 }
_ 'space' = ' '+
d 'digit' = [0-9]
......
......@@ -80,8 +80,35 @@ async function processTemplate(month, force) {
});
}
}
// find all remainder templates, place them after all other templates
let remainder_found;
let remainder_priority = lowestPriority + 1;
let remainder_weight_total = 0;
for (let c = 0; c < categories.length; c++) {
let category = categories[c];
let templates = category_templates[category.id];
if (templates) {
for (let i = 0; i < templates.length; i++) {
if (templates[i].type === 'remainder') {
templates[i].priority = remainder_priority;
remainder_weight_total += templates[i].weight;
remainder_found = true;
}
}
}
}
// so the remainders don't get skiped
if (remainder_found) lowestPriority = remainder_priority;
for (let priority = 0; priority <= lowestPriority; priority++) {
// setup scaling for remainder
let remainder_scale = 1;
if (priority === lowestPriority) {
let sheetName = monthUtils.sheetForMonth(month);
let budgetAvailable = await getSheetValue(sheetName, `to-budget`);
remainder_scale = Math.round(budgetAvailable / remainder_weight_total);
}
for (let c = 0; c < categories.length; c++) {
let category = categories[c];
let template = category_templates[category.id];
......@@ -132,6 +159,7 @@ async function processTemplate(month, force) {
template,
month,
priority,
remainder_scale,
force,
);
if (to_budget != null) {
......@@ -235,6 +263,7 @@ async function applyCategoryTemplate(
template_lines,
month,
priority,
remainder_scale,
force,
) {
let current_month = getCorrectedDate(`${month}-01`);
......@@ -549,6 +578,12 @@ async function applyCategoryTemplate(
}
break;
}
case 'remainder': {
to_budget = Math.round(remainder_scale * template.weight);
// can over budget with the rounding, so checking that
if (to_budget > budgetAvailable) to_budget = budgetAvailable;
break;
}
case 'error':
return { errors };
default:
......
---
category: Enhancements
authors: [youngcw]
---
Goals: Add remainder option to budget all extra funds automatically.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment