Refactors pending entries and adds fiat amounts

Improves the handling of pending entries by extracting and deduplicating data from Fava's query results.

Adds support for displaying fiat amounts alongside entries and extracts them from the position data in Fava.

Streamlines receivables/payables/equity checks on the frontend by relying on BQL query to supply account type metadata and tags.
This commit is contained in:
padreug 2025-11-09 23:52:39 +01:00
parent 37fe34668f
commit 56a3e9d4e9
3 changed files with 106 additions and 64 deletions

View file

@ -1501,69 +1501,30 @@ window.app = Vue.createApp({
return new Date(dateString).toLocaleDateString()
},
getTotalAmount(entry) {
if (!entry.lines || entry.lines.length === 0) return 0
// Beancount-style: use absolute value of amounts
// All lines have amounts (positive or negative), we want the transaction size
return entry.lines.reduce((sum, line) => sum + Math.abs(line.amount || 0), 0) / 2
return entry.amount
},
getEntryFiatAmount(entry) {
// Extract fiat amount from metadata if available
if (!entry.lines || entry.lines.length === 0) return null
for (const line of entry.lines) {
if (line.metadata && line.metadata.fiat_currency && line.metadata.fiat_amount) {
return this.formatFiat(line.metadata.fiat_amount, line.metadata.fiat_currency)
}
if (entry.fiat_amount && entry.fiat_currency) {
return this.formatFiat(entry.fiat_amount, entry.fiat_currency)
}
return null
},
isReceivable(entry) {
// Check if this is a receivable entry (user owes castle)
// Receivables have a positive amount (debit) to an "Accounts Receivable" account
if (!entry.lines || entry.lines.length === 0) return false
for (const line of entry.lines) {
// Look for a line with positive amount on an accounts receivable account
// Beancount-style: positive amount = debit (asset increase)
if (line.amount > 0) {
// Check if the account is associated with this user's receivables
const account = this.accounts.find(a => a.id === line.account_id)
if (account && account.name && account.name.includes('Assets:Receivable') && account.account_type === 'asset') {
return true
}
}
}
if (entry.tags && entry.tags.includes('receivable-entry')) return true
if (entry.account && entry.account.includes('Receivable')) return true
return false
},
isPayable(entry) {
// Check if this is a payable entry (castle owes user)
// Payables have a negative amount (credit) to an "Accounts Payable" account
if (!entry.lines || entry.lines.length === 0) return false
for (const line of entry.lines) {
// Look for a line with negative amount on an accounts payable account
// Beancount-style: negative amount = credit (liability increase)
if (line.amount < 0) {
// Check if the account is associated with this user's payables
const account = this.accounts.find(a => a.id === line.account_id)
if (account && account.name && account.name.includes('Liabilities:Payable') && account.account_type === 'liability') {
return true
}
}
}
if (entry.tags && entry.tags.includes('expense-entry')) return true
if (entry.account && entry.account.includes('Payable')) return true
return false
},
isEquity(entry) {
// Check if this is an equity entry (user capital contribution/balance)
if (!entry.lines || entry.lines.length === 0) return false
for (const line of entry.lines) {
// Check if the account is an equity account
const account = this.accounts.find(a => a.id === line.account_id)
if (account && account.account_type === 'equity') {
return true
}
}
if (entry.tags && entry.tags.includes('equity-contribution')) return true
if (entry.account && entry.account.includes('Equity')) return true
return false
}
},