diff --git a/README.md b/README.md index e6876d0..51fa1b7 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,9 @@ INTEREST_PAYEE_NAME="Loan Interest" # optional, name of the payee for added interest transactions INVESTMENT_PAYEE_NAME="Investment" # optional, name of the cateogry group for added investment tracking transactions -INTEREST_CATEGORY_GROUP_NAME="Income" +INVESTMENT_CATEGORY_GROUP_NAME="Income" # optional, name of the category for added investment tracking transactions -INTEREST_CATEGORY_NAME="Investment" +INVESTMENT_CATEGORY_NAME="Investment" ``` ## Installation @@ -209,6 +209,9 @@ need to update this to add additional notes to look for. You can optionally change the payee used for the transactions by setting `INVESTMENT_PAYEE_NAME` in the `.env` file. +You can optionally change the category group used for the transactions by setting +`INVESTMENT_CATEGORY_GROUP_NAME` in the `.env` file. + You can optionally change the category used for the transactions by setting `INVESTMENT_CATEGORY_NAME` in the `.env` file. diff --git a/track-investments.js b/track-investments.js index 745961b..74902ed 100644 --- a/track-investments.js +++ b/track-investments.js @@ -1,7 +1,7 @@ const api = require('@actual-app/api'); const fs = require('fs'); const readline = require('readline-sync'); -const { closeBudget, ensureCategory, ensurePayee, getAccountBalance, getAccountNote, getSimpleFinID, getTransactions, openBudget } = require('./utils'); +const { closeBudget, ensureCategory, ensureCategoryGroup, ensurePayee, getAccountBalance, getAccountNote, getSimpleFinID, getTransactions, openBudget } = require('./utils'); require("dotenv").config(); @@ -72,7 +72,8 @@ const zeroTransaction = async (payment) => { await openBudget(); const payeeId = await ensurePayee(process.env.INVESTMENT_PAYEE_NAME || 'Investment'); - const categoryId = await ensureCategory(process.env.INVESTMENT_CATEGORY_NAME || 'Investment'); + const categoryGroupId = await ensureCategoryGroup(process.env.INVESTMENT_CATEGORY_GROUP_NAME || 'Income'); + const categoryId = await ensureCategory(process.env.INVESTMENT_CATEGORY_NAME || 'Investment', categoryGroupId, true); const simplefinBalances = await getSimplefinBalances(); if (simplefinBalances) { diff --git a/utils.js b/utils.js index 3470f1b..45b3f26 100644 --- a/utils.js +++ b/utils.js @@ -4,8 +4,9 @@ require("dotenv").config(); const Utils = { openBudget: async function () { process.on('unhandledRejection', (reason, p) => { - console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); - console.log(reason.stack); + console.error('Unhandled Rejection at: Promise', p, 'reason:', reason); + console.error(reason.stack); + process.exit(1); }); const url = process.env.ACTUAL_SERVER_URL || ''; @@ -32,7 +33,12 @@ const Utils = { closeBudget: async function () { console.log("done"); - await api.shutdown(); + try { + await api.shutdown(); + } catch (e) { + console.error(e); + process.exit(1); + } }, getAccountBalance: async function (account, cutoffDate=new Date()) { @@ -83,29 +89,59 @@ const Utils = { }, ensurePayee: async function (payeeName) { - const payees = await api.getPayees(); - let payeeId = payees.find(p => p.name === payeeName)?.id; - if (!payeeId) { - payeeId = await api.createPayee({ name: payeeName }); + try { + const payees = await api.getPayees(); + let payeeId = payees.find(p => p.name === payeeName)?.id; + if (!payeeId) { + payeeId = await api.createPayee({ name: payeeName }); + } + if (payeeId) { + return payeeId; + } + } catch (e) { + console.error(e); } - if (!payeeId) { - console.error('Failed to create payee:', payeeName); - process.exit(1); - } - return payeeId; + console.error('Failed to create payee:', payeeName); + process.exit(1); }, - ensureCategory: async function (categoryName) { - const categories = await api.getCategories(); - let categoryId = categories.find(c => c.name === categoryName)?.id; - if (!categoryId) { - categoryId = await api.createCategory({ name: categoryName }); + ensureCategoryGroup: async function (categoryGroupName) { + try { + const groups = await api.getCategoryGroups(); + let groupId = groups.find(g => g.name === categoryGroupName)?.id; + if (!groupId) { + groupId = await api.createCategoryGroup({ name: categoryGroupName }); + } + if (groupId) { + return groupId; + } + } catch (e) { + console.error(e); } - if (!categoryId) { - console.error('Failed to create category:', categoryName); - process.exit(1); + console.error('Failed to create category group:', categoryGroupName); + process.exit(1); + }, + + ensureCategory: async function (categoryName, groupId, is_income=false) { + try { + const categories = await api.getCategories(); + let categoryId = categories.find(c => c.name === categoryName)?.id; + if (!categoryId) { + categoryId = await api.createCategory({ + name: categoryName, + group_id: groupId, + is_income: is_income, + hidden: false, + }); + } + if (categoryId) { + return categoryId; + } + } catch (e) { + console.error(e); } - return categoryId; + console.error('Failed to create category:', categoryName); + process.exit(1); }, getTagValue: function (note, tag, defaultValue=undefined) {