mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-09 06:02:22 -05:00
[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:
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
6
upcoming-release-notes/6922.md
Normal file
6
upcoming-release-notes/6922.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Bugfixes
|
||||
authors: [youngcw]
|
||||
---
|
||||
|
||||
Fix template balance carryover handling in the tracking budget
|
||||
Reference in New Issue
Block a user