@fuzzle/opencode-accountant 0.16.4 → 0.16.5-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.
Files changed (2) hide show
  1. package/dist/index.js +46 -16
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -17850,7 +17850,7 @@ function extractMetadata2(detection) {
17850
17850
  fromDate: metadata["from-date"],
17851
17851
  untilDate: metadata["until-date"],
17852
17852
  openingBalance: metadata["opening-balance"],
17853
- closingBalance: metadata["closing-balance"]
17853
+ closingBalance: metadata["closing-balance"] ? parseFloat(metadata["closing-balance"]).toFixed(2) : undefined
17854
17854
  };
17855
17855
  }
17856
17856
  function executeMoves(plannedMoves, config2, unrecognizedDir, directory) {
@@ -26997,6 +26997,7 @@ var TAX_TYPE = "Foreign Tax Withholding";
26997
26997
  var ADJUSTMENT_TYPE = "Adjustment";
26998
26998
  var FOREX_TYPE = "Forex Trade Component";
26999
26999
  var DEPOSIT_TYPE = "Deposit";
27000
+ var round2 = (n) => Math.round(n * 100) / 100;
27000
27001
  function parseIbkrCsv(content) {
27001
27002
  const transactions = [];
27002
27003
  const result = import_papaparse3.default.parse(content, {
@@ -27102,6 +27103,8 @@ async function preprocessIbkr(csvPath, directory, currency, year, lotInventoryPa
27102
27103
  const content = fs22.readFileSync(csvPath, "utf-8");
27103
27104
  const transactions = parseIbkrCsv(content);
27104
27105
  logger?.info(`Parsed ${transactions.length} IBKR transactions from ${path17.basename(csvPath)}`);
27106
+ let rawSum = 0;
27107
+ let roundedSum = 0;
27105
27108
  const deposits = [];
27106
27109
  const trades = [];
27107
27110
  const dividendTxns = [];
@@ -27128,6 +27131,8 @@ async function preprocessIbkr(csvPath, directory, currency, year, lotInventoryPa
27128
27131
  const usedAccounts = new Set;
27129
27132
  const journalEntries = [];
27130
27133
  for (const trade of trades) {
27134
+ rawSum += trade.netAmount;
27135
+ roundedSum += round2(trade.netAmount);
27131
27136
  const totalCost = Math.abs(trade.grossAmount);
27132
27137
  const unitPrice = trade.quantity !== 0 ? totalCost / Math.abs(trade.quantity) : 0;
27133
27138
  const tradeEntry = {
@@ -27180,6 +27185,8 @@ async function preprocessIbkr(csvPath, directory, currency, year, lotInventoryPa
27180
27185
  const dividendGroups = groupDividends(dividendTxns);
27181
27186
  for (const group of dividendGroups) {
27182
27187
  const netAmount = group.grossAmount - group.withholdingTax;
27188
+ rawSum += netAmount;
27189
+ roundedSum += round2(netAmount);
27183
27190
  const dividendEntry = {
27184
27191
  date: group.date,
27185
27192
  account: group.account,
@@ -27232,29 +27239,52 @@ async function preprocessIbkr(csvPath, directory, currency, year, lotInventoryPa
27232
27239
  logger?.info(`Generated IBKR journal: ${journalPath} with ${journalEntries.length} entries`);
27233
27240
  }
27234
27241
  const simpleTransactions = [...deposits, ...adjustments, ...forexTxns];
27242
+ for (const d of simpleTransactions) {
27243
+ rawSum += d.netAmount;
27244
+ roundedSum += round2(d.netAmount);
27245
+ }
27246
+ const csvRows = simpleTransactions.map((d) => [
27247
+ d.date,
27248
+ d.account,
27249
+ `"${d.description.replace(/"/g, '""')}"`,
27250
+ d.transactionType,
27251
+ d.symbol,
27252
+ d.quantity || "",
27253
+ d.price || "",
27254
+ d.priceCurrency,
27255
+ d.grossAmount ? round2(d.grossAmount) : "",
27256
+ d.commission ? round2(d.commission) : "",
27257
+ round2(d.netAmount)
27258
+ ].join(","));
27259
+ const roundingAdj = round2(round2(rawSum) - roundedSum);
27260
+ if (roundingAdj !== 0 && Math.abs(roundingAdj) <= 0.05) {
27261
+ const lastDate = transactions[transactions.length - 1]?.date ?? "";
27262
+ const account = transactions[0]?.account ?? "";
27263
+ csvRows.push([
27264
+ lastDate,
27265
+ account,
27266
+ '"Rounding adjustment"',
27267
+ "Rounding",
27268
+ "",
27269
+ "",
27270
+ "",
27271
+ "",
27272
+ "",
27273
+ "",
27274
+ roundingAdj
27275
+ ].join(","));
27276
+ logger?.info(`Added rounding adjustment: ${roundingAdj} CHF`);
27277
+ }
27235
27278
  let simpleTransactionsCsvPath = null;
27236
- if (simpleTransactions.length > 0) {
27279
+ if (csvRows.length > 0) {
27237
27280
  const filteredCsvPath = path17.join(csvDir, `${csvBasename}-filtered.csv`);
27238
27281
  const csvHeader = "Date,Account,Description,Transaction Type,Symbol,Quantity,Price,Price Currency,Gross Amount,Commission,Net Amount";
27239
- const csvRows = simpleTransactions.map((d) => [
27240
- d.date,
27241
- d.account,
27242
- `"${d.description.replace(/"/g, '""')}"`,
27243
- d.transactionType,
27244
- d.symbol,
27245
- d.quantity || "",
27246
- d.price || "",
27247
- d.priceCurrency,
27248
- d.grossAmount || "",
27249
- d.commission || "",
27250
- d.netAmount
27251
- ].join(","));
27252
27282
  fs22.writeFileSync(filteredCsvPath, csvHeader + `
27253
27283
  ` + csvRows.join(`
27254
27284
  `) + `
27255
27285
  `);
27256
27286
  simpleTransactionsCsvPath = filteredCsvPath;
27257
- logger?.info(`Generated filtered CSV: ${filteredCsvPath} (${simpleTransactions.length} rows)`);
27287
+ logger?.info(`Generated filtered CSV: ${filteredCsvPath} (${csvRows.length} rows)`);
27258
27288
  }
27259
27289
  const dividendCount = dividendGroups.length;
27260
27290
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzzle/opencode-accountant",
3
- "version": "0.16.4",
3
+ "version": "0.16.5-next.1",
4
4
  "description": "An OpenCode accounting agent, specialized in double-entry-bookkepping with hledger",
5
5
  "author": {
6
6
  "name": "ali bengali",