@fuzzle/opencode-accountant 0.12.1-next.1 → 0.12.2-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 CHANGED
@@ -24674,17 +24674,22 @@ function formatJournalEntry(match2) {
24674
24674
  const btcPrice = formatAmount(btcRow.price.amount);
24675
24675
  const priceCurrency = btcRow.price.currency;
24676
24676
  const hasFees = btcRow.fees.amount > 0;
24677
+ const isBaseCurrency = fiatCurrency === "CHF";
24678
+ const pair = `${fiatCurrency.toLowerCase()}-btc`;
24679
+ const equityFiat = `equity:conversion:${pair}:${fiatCurrency.toLowerCase()}`;
24680
+ const equityBtc = `equity:conversion:${pair}:btc`;
24681
+ const assetCostAnnotation = isBaseCurrency ? ` @ ${btcPrice} ${priceCurrency}` : "";
24677
24682
  const lines = [
24678
24683
  `${date5} Bitcoin purchase`,
24679
24684
  ` assets:bank:revolut:${fiatCurrency.toLowerCase()} -${fiatAmount} ${fiatCurrency}`,
24680
- ` equity:bitcoin:conversion ${fiatAmount} ${fiatCurrency}`,
24681
- ` equity:bitcoin:conversion -${btcQuantity} BTC @ ${btcPrice} ${priceCurrency}`,
24682
- ` assets:bank:revolut:btc ${btcQuantity} BTC @ ${btcPrice} ${priceCurrency}`
24685
+ ` ${equityFiat} ${fiatAmount} ${fiatCurrency}`,
24686
+ ` ${equityBtc} -${btcQuantity} BTC`,
24687
+ ` assets:bank:revolut:btc ${btcQuantity} BTC${assetCostAnnotation}`
24683
24688
  ];
24684
24689
  if (hasFees) {
24685
24690
  const feeAmount = formatAmount(btcRow.fees.amount);
24686
24691
  const feeCurrency = btcRow.fees.currency;
24687
- lines.push(` expenses:fees:btc ${feeAmount} ${feeCurrency}`, ` equity:bitcoin:conversion -${feeAmount} ${feeCurrency}`);
24692
+ lines.push(` expenses:fees:btc ${feeAmount} ${feeCurrency}`, ` ${equityFiat} -${feeAmount} ${feeCurrency}`);
24688
24693
  }
24689
24694
  return lines.join(`
24690
24695
  `);
@@ -25977,11 +25982,14 @@ function formatExchangeEntry(match2) {
25977
25982
  const targetCurrency = target.currency;
25978
25983
  const sourceAmount = formatAmount3(source.amount);
25979
25984
  const targetAmount = formatAmount3(target.amount);
25985
+ const pair = `${sourceCurrency.toLowerCase()}-${targetCurrency.toLowerCase()}`;
25986
+ const equitySource = `equity:conversion:${pair}:${sourceCurrency.toLowerCase()}`;
25987
+ const equityTarget = `equity:conversion:${pair}:${targetCurrency.toLowerCase()}`;
25980
25988
  return [
25981
25989
  `${date5} ${description}`,
25982
25990
  ` assets:bank:revolut:${sourceCurrency.toLowerCase()} -${sourceAmount} ${sourceCurrency}`,
25983
- ` equity:currency:conversion ${sourceAmount} ${sourceCurrency}`,
25984
- ` equity:currency:conversion -${targetAmount} ${targetCurrency}`,
25991
+ ` ${equitySource} ${sourceAmount} ${sourceCurrency}`,
25992
+ ` ${equityTarget} -${targetAmount} ${targetCurrency}`,
25985
25993
  ` assets:bank:revolut:${targetCurrency.toLowerCase()} ${targetAmount} ${targetCurrency}`
25986
25994
  ].join(`
25987
25995
  `);
@@ -211,7 +211,7 @@ See [classify-statements](classify-statements.md) for details.
211
211
  1. Finds all Revolut fiat contexts (provider=revolut, currency≠btc) from classification
212
212
  2. Parses each CSV for `EXCHANGE` rows with "Exchanged to" descriptions
213
213
  3. Matches source (debited) and target (credited) rows across CSVs by timestamp (within 1 second)
214
- 4. Generates unified 4-posting journal entries using `equity:currency:conversion` with `@ cost` notation
214
+ 4. Generates unified 4-posting journal entries using per-pair `equity:conversion:{pair}:{currency}` trading sub-accounts
215
215
  5. Appends entries to year journal, skipping duplicates
216
216
  6. Filters matched EXCHANGE rows from CSVs (writes `-filtered.csv`) so hledger import doesn't double-count them
217
217
  7. Updates import contexts to point to filtered CSVs
@@ -220,13 +220,13 @@ See [classify-statements](classify-statements.md) for details.
220
220
 
221
221
  ```journal
222
222
  2026-01-15 Exchanged to EUR
223
- assets:bank:revolut:chf -100.00 CHF @ 1.0713 EUR
224
- equity:currency:conversion 100.00 CHF
225
- equity:currency:conversion -107.13 EUR
226
- assets:bank:revolut:eur 107.13 EUR
223
+ assets:bank:revolut:chf -100.00 CHF
224
+ equity:conversion:chf-eur:chf 100.00 CHF
225
+ equity:conversion:chf-eur:eur -107.13 EUR
226
+ assets:bank:revolut:eur 107.13 EUR
227
227
  ```
228
228
 
229
- **Why**: Revolut exports currency exchanges as two separate CSV rows — one per currency. Processing each through its own rules file produces two independent 2-posting transactions with a non-zero `equity:conversion` balance. This step intercepts EXCHANGE rows before hledger import, matches them across currencies, and generates a single unified transaction with explicit cost notation that keeps `equity:currency:conversion` balanced.
229
+ **Why**: Revolut exports currency exchanges as two separate CSV rows — one per currency. Processing each through its own rules file produces two independent 2-posting transactions with a non-zero `equity:conversion` balance. This step intercepts EXCHANGE rows before hledger import, matches them across currencies, and generates a single unified transaction with per-pair trading sub-accounts that keep each `equity:conversion:{pair}` balanced.
230
230
 
231
231
  **Skipped when**: Fewer than 2 Revolut fiat CSVs with EXCHANGE rows are present among the classified files.
232
232
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzzle/opencode-accountant",
3
- "version": "0.12.1-next.1",
3
+ "version": "0.12.2-next.1",
4
4
  "description": "An OpenCode accounting agent, specialized in double-entry-bookkepping with hledger",
5
5
  "author": {
6
6
  "name": "ali bengali",