Files
actual-helpers/budget.js
T
rlkollman 850c0d7a6a
Create and publish Docker image on GHCR / publish-docker-image (push) Has been cancelled
Get latest Actual release / get-version (push) Has been cancelled
Add budget.js
2026-05-24 09:12:52 -05:00

74 lines
3.2 KiB
JavaScript

const api = require('@actual-app/api');
const { closeBudget, ensurePayee, getAccountBalance, getAccountNote, getTagValue, openBudget, showPercent, sleep,
getBudgetMonth, getCategoryGroups, getCategories } = require('./utils');
require("dotenv").config();
(async function () {
await openBudget();
var today = new Date();
var yyyy = today.getFullYear();
var mm = (today.getMonth() + 1).toString().padStart(2, '0');
var budgetMonth = yyyy + '-' + mm;
const budget = await api.getBudgetMonth(budgetMonth);
console.log('');
console.log('~~!!'); // Make it easy to parse for e-mail
console.log('Budget for Month: ' + budgetMonth);
console.log('Total Budget: $' + (budget.totalBudgeted * .01).toFixed(2).padStart(8, ' '));
console.log('Income: $' + (budget.totalIncome * .01).toFixed(2).padStart(8, ' '));
console.log('Spent: $' + (budget.totalSpent * .01).toFixed(2).padStart(8, ' '));
console.log('Balance: $' + (budget.totalBalance * .01).toFixed(2).padStart(8, ' '));
console.log('----------------------------------------------------');
const categoryGroups = await api.getCategoryGroups();
for (const categoryGroup of budget.categoryGroups) {
if (categoryGroup.hidden || categoryGroup.budgeted == 0 || categoryGroup.is_income) {
continue;
}
const categorySpentPercent = ((categoryGroup.spent * .01) / (categoryGroup.budgeted * .01) * -100);
const categoryBalancePercent = ((categoryGroup.balance * .01) / (categoryGroup.budgeted * .01) * 10);
console.log(categoryGroup.name.padEnd(21, ' ') + ' ' + categorySpentPercent.toFixed(1).trim().padStart(7, ' ') + '% spent of $' + (categoryGroup.budgeted * .01).toFixed(2).trim().padStart(8, ' '));
}
console.log('!!~~'); // Make it easy to parse for e-mail
console.log('');
var transactionDate = new Date();
transactionDate.setDate(transactionDate.getDate() - 1);
let txDate = transactionDate.toISOString().substring(0, 10);
console.log('Transactions on ' + txDate);
console.log('DATE ACCOUNT PAYEE NOTES / MEMO AMOUNT');
console.log('-------------------------------------------------------------------------------------------------------------------------');
const payees = await api.getPayees();
const accounts = await api.getAccounts();
( await api.runQuery(
api.q('transactions')
.filter({
date: { $gte: txDate },
})
.select('*')
)
).data.map(row => {
let payeeName = payees.find(p => p.id === row.payee)?.name;
let accountName = accounts.find(a => a.id === row.account)?.name;
console.log(row.date + ' ' +
fixedStringLength(accountName, 20) + ' ' +
fixedStringLength(payeeName, 25) + ' ' +
fixedStringLength(row.notes, 45) + ' ' +
('$' + (row.amount / 100).toFixed(2).trim()).padStart(11, ' '));
});
await closeBudget();
})();
function fixedStringLength(str, length) {
if (str === null) {
str = '';
}
return str.padEnd(length).substring(0, length);
}