// Generated, do not edit. sha256:84e73291cc02df3176d4ba8acbc3d3f1b844080d320978a75a2af8c8bde70e30 import { listSelectableAccounts } from '../data/accounts.js'; import { dayNl, localTime, toUtcIso } from '../../shared/time.js'; import { listAssets, listBookableAssets } from '../data/assets.js'; import { tableViewCfg } from '../data/preferences.js'; import { getPriceAt } from '../data/price-history.js'; import { listValuations, valuationDiffs, updateValuation, deleteValuation, createValuation, acceptValuationGap } from '../data/valuations.js'; import { t } from '../i18n/index.js'; import { assetLabelHtml } from '../ui/asset-label.js'; import * as dialog from '../ui/dialog.js'; import { esc } from '../ui/escape.js'; import { renderTable } from '../ui/table.js'; import { takeRowFocus } from '../ui/row-focus.js'; import { fmtBase, fmtBasePrice, fmtUnit, isBaseAsset, val, toSubunit, fromSubunit } from '../ui/format.js'; import { baseCurrency } from '../app-settings.js'; import { ensurePriceHistoryFor, historicalPointForVia, primarySourceKey } from '../price/providers.js'; import { bookDifference, acceptDifference } from '../actions/valuation-widget.js'; import { TARGETS, targetHash } from '../../shared/config.js'; import { emptyStateHtml } from '../ui/empty-state.js'; import { capacityCfg } from '../ui/lock.js'; import { setPageHint } from '../ui/page-hint.js'; let tableApi = null; let onlyAccount = null; let onlyAsset = null; let onlyKinds = null; const assetAllowed = a => (onlyAsset == null || a.id === onlyAsset) && (onlyKinds == null || onlyKinds.includes(a.kind)); export async function render(el, { accountId = null, assetId = null, assetKinds = null } = {}) { onlyAccount = accountId; onlyAsset = assetId; onlyKinds = assetKinds; if ((await listAssets()).length === 0) { el.innerHTML = ` ${emptyStateHtml(t('valuations.none'), { why: t('valuations.needAsset'), href: targetHash(TARGETS.ASSETS), linkText: t('common.manageAssets'), })}`; return; } el.innerHTML = `
`; if (onlyAccount == null) setPageHint(el, { title: t('nav.valuations'), rows: [t('valuations.rateNote')] }); buildTable(el); } async function assetOpts() { return (await listBookableAssets()).filter(assetAllowed).map(a => ({ value: a.id, label: `${a.symbol}: ${a.name}` })); } async function accountOpts(huidigeId) { const accounts = (await listSelectableAccounts({ ookId: Number(huidigeId) || null })) .filter(a => onlyAccount == null || a.id === onlyAccount); return [...(onlyAccount == null ? [{ value: '', label: '-' }] : []), ...accounts.map(a => ({ value: a.id, label: a.name }))]; } const meta = r => ({ kind: r.asset_kind, decimals: r.asset_decimals, unit: r.asset_unit, subunit: r.asset_subunit, displayUnit: r.asset_display_unit }); const isRekenmunt = r => isBaseAsset({ symbol: r.asset_symbol }); async function valuationPayload(v, existing) { const asset = (await listAssets()).find(a => a.id === Number(v.assetId)); const qty = parseFloat(v.balance); if (!v.valuedOn || !asset || !Number.isFinite(qty) || qty < 0) { throw new Error(t('valuations.invalid')); } const balance = toSubunit(qty, asset); const rateAt = toUtcIso(`${v.valuedOn}T${v._time || '00:00'}:00`); let fiatRate = v.fiatRate === '' || v.fiatRate == null ? null : parseFloat(v.fiatRate); if (fiatRate == null) { try { await ensurePriceHistoryFor(asset); } catch { } const readSrc = (await primarySourceKey(asset, 'daily_history')) || (await primarySourceKey(asset, 'history_point')); const at = await getPriceAt(asset.id, Math.floor(Date.parse(rateAt) / 1000), readSrc); fiatRate = at ? at.fiatPrice : null; if (fiatRate == null) { const p = await historicalPointForVia(asset, v.valuedOn).catch(() => null); fiatRate = p ? p.price : null; } if (fiatRate == null) throw new Error(t('valuations.noRate')); } const accountId = v.accountId ?? onlyAccount; return { assetId: Number(v.assetId), valuedOn: v.valuedOn, accountId: accountId !== '' && accountId != null ? Number(accountId) : null, balance, fiatRate, rateAt, source: existing ? existing.source : 'manual', }; } export async function recordBalance(v) { return createValuation(await valuationPayload({ fiatRate: '', ...v }, null)); } async function buildTable(el) { const alleAssets = await listAssets(); const verschillen = new Map(); const rows = async () => { const rijen = (await listValuations()).filter(r => (onlyAccount == null || r.accountId === onlyAccount) && (onlyAsset == null || r.assetId === onlyAsset)); verschillen.clear(); for (const s of await valuationDiffs()) verschillen.set(s.id, s); return rijen; }; const today = new Date().toISOString().slice(0, 10); const columns = [ { key: 'valuedOn', label: t('valuations.colDate'), sortable: true, render: r => dayNl(r.valuedOn), group: { value: r => r.valuedOn.slice(0, 4), label: v => v, order: 'desc' }, edit: { type: 'date', sticky: true, value: r => r ? r.valuedOn : today } }, { key: '_time', label: t('valuations.colTime'), render: r => localTime(r.rateAt), edit: { type: 'time', value: r => r && r.rateAt ? localTime(r.rateAt) : '00:00' } }, { key: 'accountId', label: t('valuations.colAccount'), sortable: true, sortValue: r => r.account_name || '', render: r => r.account_name || '-', group: { value: r => r.account_name || '-', label: v => v }, edit: { type: 'select', sticky: true, options: vals => accountOpts(vals.accountId), value: r => r ? r.accountId ?? '' : '' } }, { key: 'assetId', label: t('valuations.colAsset'), sortable: true, sortValue: r => r.asset_symbol, render: r => assetLabelHtml(r), group: { value: r => r.asset_symbol, label: v => v }, edit: { type: 'select', sticky: true, reactive: true, options: assetOpts } }, { key: 'balance', label: t('valuations.colBalance'), align: 'num', sortable: true, sortValue: r => r.balance, render: r => { const fiat = (r.fiatRate && !isRekenmunt(r)) ? fmtBase(r.balance / Math.pow(10, r.asset_decimals) * r.fiatRate) : ''; return `${val(fmtUnit(r.balance, meta(r)))}${fiat ? `