[Goals] fix tracking budget balance carryover for templates (#6922)

* fix tracking budget balance carryover for templates

* Add release notes for PR #6922

* fix note

* fix tests

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
youngcw
2026-02-10 18:52:49 -07:00
committed by GitHub
parent 2ca352aaa7
commit 07ff514c12
3 changed files with 24 additions and 9 deletions

View File

@@ -13,6 +13,7 @@ import { CategoryTemplateContext } from './category-template-context';
vi.mock('./actions', () => ({
getSheetValue: vi.fn(),
getSheetBoolean: vi.fn(),
isReflectBudget: vi.fn(),
}));
vi.mock('../db', () => ({
@@ -1051,6 +1052,7 @@ describe('CategoryTemplateContext', () => {
// Mock the sheet values needed for init
vi.mocked(actions.getSheetValue).mockResolvedValueOnce(0); // lastMonthBalance
vi.mocked(actions.getSheetBoolean).mockResolvedValueOnce(false); // carryover
vi.mocked(actions.isReflectBudget).mockResolvedValueOnce(false);
mockPreferences(false, 'USD');
// Initialize the template
@@ -1115,6 +1117,7 @@ describe('CategoryTemplateContext', () => {
// Mock the sheet values needed for init
vi.mocked(actions.getSheetValue).mockResolvedValueOnce(0); // lastMonthBalance
vi.mocked(actions.getSheetBoolean).mockResolvedValueOnce(false); // carryover
vi.mocked(actions.isReflectBudget).mockResolvedValueOnce(false);
mockPreferences(false, 'USD');
// Initialize the template
@@ -1169,6 +1172,7 @@ describe('CategoryTemplateContext', () => {
// Mock the sheet values needed for init
vi.mocked(actions.getSheetValue).mockResolvedValueOnce(0); // lastMonthBalance
vi.mocked(actions.getSheetBoolean).mockResolvedValueOnce(false); // carryover
vi.mocked(actions.isReflectBudget).mockResolvedValueOnce(false);
mockPreferences(false, 'USD');
// Initialize the template
@@ -1228,6 +1232,7 @@ describe('CategoryTemplateContext', () => {
// Mock the sheet values needed for init
vi.mocked(actions.getSheetValue).mockResolvedValueOnce(0); // lastMonthBalance
vi.mocked(actions.getSheetBoolean).mockResolvedValueOnce(false); // carryover
vi.mocked(actions.isReflectBudget).mockResolvedValueOnce(false);
mockPreferences(false, 'USD');
// Initialize the template
@@ -1270,6 +1275,7 @@ describe('CategoryTemplateContext', () => {
// Mock the sheet values needed for init
vi.mocked(actions.getSheetValue).mockResolvedValueOnce(10000); // lastMonthBalance
vi.mocked(actions.getSheetBoolean).mockResolvedValueOnce(false); // carryover
vi.mocked(actions.isReflectBudget).mockResolvedValueOnce(false);
mockPreferences(false, 'USD');
// Initialize the template
@@ -1314,6 +1320,7 @@ describe('CategoryTemplateContext', () => {
// Mock the sheet values needed for init
vi.mocked(actions.getSheetValue).mockResolvedValueOnce(0); // lastMonthBalance
vi.mocked(actions.getSheetBoolean).mockResolvedValueOnce(false); // carryover
vi.mocked(actions.isReflectBudget).mockResolvedValueOnce(false);
mockPreferences(true, 'USD');
// Initialize the template
@@ -1356,6 +1363,7 @@ describe('CategoryTemplateContext', () => {
vi.mocked(actions.getSheetValue).mockResolvedValueOnce(0);
vi.mocked(actions.getSheetBoolean).mockResolvedValueOnce(false);
vi.mocked(actions.isReflectBudget).mockResolvedValueOnce(false);
mockPreferences(true, 'JPY');
const instance = await CategoryTemplateContext.init(
@@ -1387,6 +1395,7 @@ describe('CategoryTemplateContext', () => {
vi.mocked(actions.getSheetValue).mockResolvedValueOnce(0);
vi.mocked(actions.getSheetBoolean).mockResolvedValueOnce(false);
vi.mocked(actions.isReflectBudget).mockResolvedValueOnce(false);
mockPreferences(true, 'JPY');
const instance = await CategoryTemplateContext.init(

View File

@@ -21,7 +21,7 @@ import type {
import { aqlQuery } from '../aql';
import * as db from '../db';
import { getSheetBoolean, getSheetValue } from './actions';
import { getSheetBoolean, getSheetValue, isReflectBudget } from './actions';
import { runSchedule } from './schedule-template';
import { getActiveSchedules } from './statements';
@@ -55,7 +55,7 @@ export class CategoryTemplateContext {
const lastMonthSheet = monthUtils.sheetForMonth(
monthUtils.subMonths(month, 1),
);
const lastMonthBalance = await getSheetValue(
let fromLastMonth = await getSheetValue(
lastMonthSheet,
`leftover-${category.id}`,
);
@@ -63,15 +63,15 @@ export class CategoryTemplateContext {
lastMonthSheet,
`carryover-${category.id}`,
);
let fromLastMonth;
if (lastMonthBalance < 0 && !carryover) {
if (
(fromLastMonth < 0 && !carryover) || // overspend no carryover
category.is_income || // tracking budget income categories
(isReflectBudget() && !carryover) // tracking budget regular categories
) {
fromLastMonth = 0;
} else if (category.is_income) {
//for tracking budget
fromLastMonth = 0;
} else {
fromLastMonth = lastMonthBalance;
}
// run all checks
await CategoryTemplateContext.checkByAndScheduleAndSpend(templates, month);
await CategoryTemplateContext.checkPercentage(templates);

View File

@@ -0,0 +1,6 @@
---
category: Bugfixes
authors: [youngcw]
---
Fix template balance carryover handling in the tracking budget