@fuzzle/opencode-accountant 0.7.3 → 0.7.4-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +36 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23050,7 +23050,7 @@ function findRulesForCsv(csvPath, mapping) {
|
|
|
23050
23050
|
// src/utils/hledgerExecutor.ts
|
|
23051
23051
|
var {$: $2 } = globalThis.Bun;
|
|
23052
23052
|
var STDERR_TRUNCATE_LENGTH = 500;
|
|
23053
|
-
var TX_HEADER_PATTERN = /^(\d{4})-(\d{2}-\d{2})\s+(.+)
|
|
23053
|
+
var TX_HEADER_PATTERN = /^(\d{4})-(\d{2}-\d{2})(\s+(.+))?$/;
|
|
23054
23054
|
async function defaultHledgerExecutor(cmdArgs) {
|
|
23055
23055
|
try {
|
|
23056
23056
|
const result = await $2`hledger ${cmdArgs}`.quiet().nothrow();
|
|
@@ -23088,7 +23088,7 @@ function parseUnknownPostings(hledgerOutput) {
|
|
|
23088
23088
|
const headerMatch = line.match(TX_HEADER_PATTERN);
|
|
23089
23089
|
if (headerMatch) {
|
|
23090
23090
|
currentDate = `${headerMatch[1]}-${headerMatch[2]}`;
|
|
23091
|
-
currentDescription = headerMatch[
|
|
23091
|
+
currentDescription = (headerMatch[4] || "").trim();
|
|
23092
23092
|
continue;
|
|
23093
23093
|
}
|
|
23094
23094
|
const postingMatch = line.match(/^\s+(income:unknown|expenses:unknown)\s+([^\s]+(?:\s+[^\s=]+)?)\s*(?:=\s*(.+))?$/);
|
|
@@ -24921,7 +24921,7 @@ async function executeAccountDeclarationsStep(context, contextId, logger) {
|
|
|
24921
24921
|
}
|
|
24922
24922
|
}
|
|
24923
24923
|
if (!transactionYear) {
|
|
24924
|
-
context.result.steps.accountDeclarations = buildStepResult(
|
|
24924
|
+
context.result.steps.accountDeclarations = buildStepResult(true, "No transactions found, skipping account declarations", {
|
|
24925
24925
|
accountsAdded: [],
|
|
24926
24926
|
journalUpdated: "",
|
|
24927
24927
|
rulesScanned: Array.from(matchedRulesFiles).map((f) => path12.relative(context.directory, f))
|
|
@@ -25064,6 +25064,13 @@ async function executeImportStep(context, contextId, logger) {
|
|
|
25064
25064
|
transactionCount: importParsed.summary?.totalTransactions
|
|
25065
25065
|
});
|
|
25066
25066
|
}
|
|
25067
|
+
const totalTx = importParsed.summary?.totalTransactions ?? 0;
|
|
25068
|
+
const hasNoTransactions = totalTx === 0 && (importParsed.summary?.unknown ?? 0) === 0 && (importParsed.summary?.filesWithErrors ?? 0) === 0;
|
|
25069
|
+
if (hasNoTransactions) {
|
|
25070
|
+
logger?.info("No transactions found for this context");
|
|
25071
|
+
logger?.endSection();
|
|
25072
|
+
throw new NoTransactionsError;
|
|
25073
|
+
}
|
|
25067
25074
|
if (!importParsed.success) {
|
|
25068
25075
|
if (detailsLog) {
|
|
25069
25076
|
logger?.error("Import found unknown accounts or errors");
|
|
@@ -25076,10 +25083,6 @@ async function executeImportStep(context, contextId, logger) {
|
|
|
25076
25083
|
context.result.hint = detailsLog ? "Add rules to categorize unknown transactions, then retry. See details above for suggestions." : undefined;
|
|
25077
25084
|
throw new Error("Import failed");
|
|
25078
25085
|
}
|
|
25079
|
-
if (importParsed.summary?.totalTransactions === 0) {
|
|
25080
|
-
logger?.endSection();
|
|
25081
|
-
throw new NoTransactionsError;
|
|
25082
|
-
}
|
|
25083
25086
|
logger?.endSection();
|
|
25084
25087
|
}
|
|
25085
25088
|
async function executeReconcileStep(context, contextId, logger) {
|
|
@@ -25123,8 +25126,12 @@ async function executeReconcileStep(context, contextId, logger) {
|
|
|
25123
25126
|
logger?.endSection();
|
|
25124
25127
|
}
|
|
25125
25128
|
function handleNoTransactions(result) {
|
|
25126
|
-
result.steps.import
|
|
25127
|
-
|
|
25129
|
+
if (!result.steps.import) {
|
|
25130
|
+
result.steps.import = buildStepResult(true, "No transactions to import");
|
|
25131
|
+
}
|
|
25132
|
+
if (!result.steps.reconcile) {
|
|
25133
|
+
result.steps.reconcile = buildStepResult(true, "Reconciliation skipped (no transactions)");
|
|
25134
|
+
}
|
|
25128
25135
|
return buildPipelineSuccessResult(result, "No transactions found to import");
|
|
25129
25136
|
}
|
|
25130
25137
|
async function importPipeline(directory, agent, options, configLoader = loadImportConfig, hledgerExecutor = defaultHledgerExecutor) {
|
|
@@ -25158,14 +25165,29 @@ async function importPipeline(directory, agent, options, configLoader = loadImpo
|
|
|
25158
25165
|
}
|
|
25159
25166
|
executePreprocessBtcStep(context, contextIds, logger);
|
|
25160
25167
|
await executeBtcPurchaseStep(context, contextIds, logger);
|
|
25168
|
+
const orderedContextIds = [...contextIds].sort((a, b) => {
|
|
25169
|
+
const ctxA = loadContext(context.directory, a);
|
|
25170
|
+
const ctxB = loadContext(context.directory, b);
|
|
25171
|
+
const isBtcA = ctxA.provider === "revolut" && ctxA.currency === "btc" ? 1 : 0;
|
|
25172
|
+
const isBtcB = ctxB.provider === "revolut" && ctxB.currency === "btc" ? 1 : 0;
|
|
25173
|
+
return isBtcA - isBtcB;
|
|
25174
|
+
});
|
|
25161
25175
|
let totalTransactions = 0;
|
|
25162
|
-
for (const contextId of
|
|
25176
|
+
for (const contextId of orderedContextIds) {
|
|
25163
25177
|
const importContext = loadContext(context.directory, contextId);
|
|
25164
25178
|
logger.info(`Processing: ${importContext.filename} (${importContext.accountNumber || "unknown account"})`);
|
|
25165
|
-
|
|
25166
|
-
|
|
25167
|
-
|
|
25168
|
-
|
|
25179
|
+
try {
|
|
25180
|
+
await executeAccountDeclarationsStep(context, contextId, logger);
|
|
25181
|
+
await executeImportStep(context, contextId, logger);
|
|
25182
|
+
await executeReconcileStep(context, contextId, logger);
|
|
25183
|
+
totalTransactions += context.result.steps.import?.details?.summary?.totalTransactions || 0;
|
|
25184
|
+
} catch (error45) {
|
|
25185
|
+
if (error45 instanceof NoTransactionsError) {
|
|
25186
|
+
logger.info(`No transactions to import for ${importContext.filename}, skipping`);
|
|
25187
|
+
continue;
|
|
25188
|
+
}
|
|
25189
|
+
throw error45;
|
|
25190
|
+
}
|
|
25169
25191
|
}
|
|
25170
25192
|
logger.startSection("Summary");
|
|
25171
25193
|
logger.info(`Import completed successfully`);
|