Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bugfix] Cleanup tool: Add balance check #2295

Merged
merged 9 commits into from
Feb 5, 2024
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 75 additions & 8 deletions packages/loot-core/src/server/budget/cleanup-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ async function processCleanup(month: string): Promise<Notification> {
let total_weight = 0;
const errors = [];
const sinkCategory = [];
const sourceWithRollover = [];
const db_month = parseInt(month.replace('-', ''));

const category_templates = await getCategoryTemplates();
const categories = await db.all(
Expand All @@ -35,12 +37,26 @@ async function processCleanup(month: string): Promise<Notification> {
sheetName,
`budget-${category.id}`,
);
await setBudget({
category: category.id,
month,
amount: budgeted - balance,
});
num_sources += 1;
if (balance > 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to have this be >= so that way exact zeros just act like normal and don't get the warning message?

await setBudget({
category: category.id,
month,
amount: budgeted - balance,
});
num_sources += 1;
} else {
errors.push(category.name + ' does not have available funds.');
}
const carryover = await db.first(
`SELECT carryover FROM zero_budgets WHERE month = ? and category = ?`,
[db_month, category.id],
);
if (carryover !== null) {
//keep track of source categories with rollover enabled
if (carryover.carryover === 1) {
sourceWithRollover.push({ cat: category, temp: template });
}
}
}
if (template.filter(t => t.type === 'sink').length > 0) {
sinkCategory.push({ cat: category, temp: template });
Expand All @@ -51,7 +67,6 @@ async function processCleanup(month: string): Promise<Notification> {
}

//funds all underfunded categories first unless the overspending rollover is checked
const db_month = parseInt(month.replace('-', ''));
for (let c = 0; c < categories.length; c++) {
const category = categories[c];
const budgetAvailable = await getSheetValue(sheetName, `to-budget`);
Expand Down Expand Up @@ -79,11 +94,63 @@ async function processCleanup(month: string): Promise<Notification> {
month,
amount: to_budget,
});
} else if (
balance < 0 &&
!category.is_income &&
carryover.carryover === 0 &&
Math.abs(balance) > budgetAvailable
) {
await setBudget({
category: category.id,
month,
amount: budgeted + budgetAvailable,
});
}
}

const budgetAvailable = await getSheetValue(sheetName, `to-budget`);

//fund rollover categories after non-rollover categories
for (let c = 0; c < categories.length; c++) {
const category = categories[c];
const budgetAvailable = await getSheetValue(sheetName, `to-budget`);
const balance = await getSheetValue(sheetName, `leftover-${category.id}`);
const budgeted = await getSheetValue(sheetName, `budget-${category.id}`);
const to_budget = budgeted + Math.abs(balance);
const categoryId = category.id;
let carryover = await db.first(
`SELECT carryover FROM zero_budgets WHERE month = ? and category = ?`,
[db_month, categoryId],
);

if (carryover === null) {
carryover = { carryover: 0 };
}

if (
balance < 0 &&
Math.abs(balance) <= budgetAvailable &&
!category.is_income &&
carryover.carryover === 1
) {
await setBudget({
category: category.id,
month,
amount: to_budget,
});
} else if (
balance < 0 &&
!category.is_income &&
carryover.carryover === 1 &&
Math.abs(balance) > budgetAvailable
) {
await setBudget({
category: category.id,
month,
amount: budgeted + budgetAvailable,
});
}
}

if (budgetAvailable <= 0) {
errors.push('No funds are available to reallocate.');
}
Expand Down
Loading