doku
All checks were successful
Deploy / deploy-staging (push) Successful in 32s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-08-21 01:04:21 +02:00
parent 70c86bd8ce
commit 95100d3a78
9 changed files with 66 additions and 37 deletions

View File

@@ -3191,21 +3191,14 @@
const totalHoldingsValue = latest ? convertMeasurementMoney(latest, latest.total_holdings_value, reportCurrency) : null;
const earnedValue = latest ? convertMeasurementMoney(latest, latest.earned_value, reportCurrency) : null;
const settledCryptoSpendValue = latest ? convertMeasurementMoney(latest, latest.settled_crypto_spend_value, reportCurrency) : null;
const totalEarnedOverall = latest && latest.growth_since_baseline !== null && latest.growth_since_baseline !== undefined
? Number(latest.growth_since_baseline)
const variableEarnedCurrentAsset = latest && latest.holdings_current_asset !== null && latest.holdings_current_asset !== undefined
? Number(latest.holdings_current_asset)
: null;
const totalEarnedOverallFiat = totalEarnedOverall !== null
? convertCurrencyValue(totalEarnedOverall, currentCoinCurrency, reportCurrency)
const fixedCryptoSpendCurrentAsset = latest && latest.fixed_crypto_spend_current_asset !== null && latest.fixed_crypto_spend_current_asset !== undefined
? Number(latest.fixed_crypto_spend_current_asset)
: null;
const totalSpentOverallCurrentAsset = latest
? convertMeasurementMoney(
latest,
(Number(latest.cash_invested_capital) || 0) + (Number(latest.reinvested_capital) || 0),
currentCoinCurrency
)
: null;
const totalSpentOverallFiat = totalSpentOverallCurrentAsset !== null
? convertCurrencyValue(totalSpentOverallCurrentAsset, currentCoinCurrency, reportCurrency)
const totalEarnedCurrentAsset = latest && latest.earned_current_asset !== null && latest.earned_current_asset !== undefined
? Number(latest.earned_current_asset)
: null;
const spentByType = allMinerRows.reduce((summary, row) => {
const amount = Number(row?.effective_amount);
@@ -3279,19 +3272,20 @@
h(StatCard, {
key: 'earned-overall',
label: `Bisher verdient gesamt ${currentCoinCurrency}`,
value: totalEarnedOverall !== null ? fmtNumber(totalEarnedOverall, 6) : 'n/a',
value: totalEarnedCurrentAsset !== null ? fmtNumber(totalEarnedCurrentAsset, 6) : 'n/a',
sub: [
totalEarnedOverallFiat !== null ? ` ${fmtMoney(totalEarnedOverallFiat, reportCurrency)}` : null,
variableEarnedCurrentAsset !== null ? `Variabel ${fmtNumber(variableEarnedCurrentAsset, 6)} ${currentCoinCurrency}` : null,
fixedCryptoSpendCurrentAsset !== null ? `Fix ${fmtNumber(fixedCryptoSpendCurrentAsset, 6)} ${currentCoinCurrency}` : null,
currentSettings?.baseline_measured_at ? `Seit Baseline ${fmtDate(currentSettings.baseline_measured_at)}` : 'Benötigt Baseline',
].filter(Boolean).join(' · '),
}),
h(StatCard, {
key: 'spent-overall',
label: `Bisher ausgegeben gesamt ${currentCoinCurrency}`,
value: totalSpentOverallCurrentAsset !== null ? fmtNumber(totalSpentOverallCurrentAsset, 6) : 'n/a',
label: `Krypto-Ausgaben fix ${currentCoinCurrency}`,
value: fixedCryptoSpendCurrentAsset !== null ? fmtNumber(fixedCryptoSpendCurrentAsset, 6) : 'n/a',
sub: [
totalSpentOverallFiat !== null ? `${fmtMoney(totalSpentOverallFiat, reportCurrency)}` : null,
`Krypto ${fmtNumber(spentByType.crypto, 6)} ${currentCoinCurrency}`,
settledCryptoSpendValue !== null ? `Historischer Gegenwert ${fmtMoney(settledCryptoSpendValue, reportCurrency)}` : null,
'Kurs aus gespeichertem fx-rates-Snapshot',
`FIAT ${fmtMoney(spentByType.fiat, reportCurrency)}`,
].filter(Boolean).join(' · '),
}),
@@ -3317,11 +3311,11 @@
value: earnedValue !== null ? fmtMoney(earnedValue, reportCurrency) : 'n/a',
sub: [
holdingsCurrentAsset !== null && holdingsCurrentAsset !== undefined
? `Gesamtbestand ${fmtNumber(holdingsCurrentAsset, 6)} ${currentCoinCurrency}`
? `Variabel ${fmtNumber(holdingsCurrentAsset, 6)} ${currentCoinCurrency}`
: null,
latestValue !== null ? `Miner ${fmtMoney(latestValue, reportCurrency)}` : null,
walletValue !== null ? `Wallet ${fmtMoney(walletValue, reportCurrency)}` : null,
settledCryptoSpendValue !== null ? `Ausgegeben ${fmtMoney(settledCryptoSpendValue, reportCurrency)}` : null,
settledCryptoSpendValue !== null ? `Fix ausgegeben ${fmtMoney(settledCryptoSpendValue, reportCurrency)}` : null,
latestPrice !== null
? `Kurs ${fmtNumber(latestPrice, 6)} ${reportCurrency}${latest && latest.price_is_fallback ? ' · Fallback aus letztem Kurs' : ''}`
: null,

View File

@@ -132,10 +132,11 @@ Diese Regeln sind bei jeder Erweiterung der Wallet-, Miner- oder Uebersichtslogi
1. Ein Miner wird zu einem festen Zeitpunkt gemietet. Fiat-Mieten koennen bei Ablauf zum gleichen Preis verlaengert werden; Krypto-Mieten haben eine feste Laufzeit.
2. Erwirtschaftete Coins bleiben zuerst im Mining-Tool. Erst ein erfasster Transfer aus dem Mining-Tool erhoeht den Bestand des hier verfolgten Wallets.
3. Solange Coins im Mining-Tool oder im Wallet liegen, wird ihr Gegenwert mit dem aktuellen Kurs der jeweiligen Waehrung bewertet.
4. Wird ein Miner mit der Kryptowaehrung bezahlt, reduziert der Kauf den Walletbestand um den gezahlten Coin-Betrag. Gleichzeitig wird dessen Fiat-Gegenwert zum Kaufzeitpunkt als feste Buchung gespeichert. Dieser Betrag darf durch spaetere Kursaenderungen nicht mehr beeinflusst werden.
4. Wird ein Miner mit der Kryptowaehrung bezahlt, reduziert der Kauf den Walletbestand um den gezahlten Coin-Betrag. Gleichzeitig wird dessen Gegenwert zum Kaufzeitpunkt als feste Buchung gespeichert. Dieser Betrag darf durch spaetere Kursaenderungen nicht mehr beeinflusst werden.
5. Ein Wallet-Screenshot ist fuer seinen Zeitstempel autoritativ. Sein erkannter Hauptbestand ueberschreibt die rechnerische Wallet-Historie bis zu diesem Zeitpunkt; erst danach werden weitere Transfers, Krypto-Minerkaeufe und externe Wallet-Auszahlungen verrechnet.
6. Jede erfasste Auszahlung aus dem Mining-Tool muss den Walletbestand automatisch fortschreiben. Externe Auszahlungen aus dem hier verfolgten Wallet reduzieren ihn.
7. Der angezeigte bisherige Wert ist die Summe aus aktuellem Gegenwert im Mining-Tool, aktuellem Gegenwert im Wallet und allen festgeschriebenen Gegenwerten von mit Krypto bezahlten Minern.
7. Der angezeigte bisherige Wert trennt variable Werte (Coins im Mining-Tool und Wallet zum aktuellen Kurs) von fixen Werten (bereits mit Krypto bezahlte Miner zum Ausgabezeitpunkt). Die Gesamtsumme besteht aus beiden Kategorien.
8. Jede neue feste Krypto-Buchung referenziert die `fetch_id` des Moduls `fx-rates`. Der Mining-Checker fuehrt keine eigene Kurstabelle. Umrechnungen in andere Berichtswährungen verwenden fuer fixe Werte denselben historischen API-Snapshot.
### Historische Krypto-Miner
@@ -143,7 +144,7 @@ Beim Schema-Upgrade werden vorhandene Krypto-Miner einmalig bewertet:
1. Gibt es einen Referenzpreis in einer anderen Waehrung als der gezahlten Kryptowaehrung, wird dieser als historisch nachvollziehbarer, fester Gegenwert verwendet.
2. Fehlt eine belastbare historische Referenz, wird der ausgegebene Coin-Betrag mit dem fest vereinbarten Fallback `0,07 EUR` pro Coin bewertet und dauerhaft gespeichert.
3. Die feste Bewertung wird in `settled_value_amount` und `settled_value_currency` des jeweiligen gekauften Miners gespeichert. Das Schema-Upgrade ist nach dem Deployment auszufuehren.
3. Die feste Bewertung wird in `settled_value_amount`, `settled_value_currency` und bei neuen Buchungen zusaetzlich in `settled_fx_fetch_id` des jeweiligen gekauften Miners gespeichert. Das Schema-Upgrade ist nach dem Deployment auszufuehren.
## Verbindliche Fachregeln: Zielminer-ETA

View File

@@ -224,6 +224,7 @@ CREATE TABLE IF NOT EXISTS miningcheck_purchased_miners (
reference_price_currency VARCHAR(10) NULL,
settled_value_amount DECIMAL(20,8) NULL,
settled_value_currency VARCHAR(10) NULL,
settled_fx_fetch_id BIGINT UNSIGNED NULL,
daily_cost_amount DECIMAL(20,10) NULL,
daily_cost_currency VARCHAR(10) NULL,
auto_renew TINYINT(1) NOT NULL DEFAULT 0,

View File

@@ -241,6 +241,7 @@ CREATE TABLE IF NOT EXISTS miningcheck_purchased_miners (
reference_price_currency VARCHAR(10),
settled_value_amount NUMERIC(20,8),
settled_value_currency VARCHAR(10),
settled_fx_fetch_id BIGINT,
daily_cost_amount NUMERIC(20,10),
daily_cost_currency VARCHAR(10),
auto_renew BOOLEAN NOT NULL DEFAULT FALSE,

View File

@@ -224,6 +224,7 @@ CREATE TABLE IF NOT EXISTS miningcheck_purchased_miners (
reference_price_currency VARCHAR(10) NULL,
settled_value_amount DECIMAL(20,8) NULL,
settled_value_currency VARCHAR(10) NULL,
settled_fx_fetch_id BIGINT UNSIGNED NULL,
daily_cost_amount DECIMAL(20,10) NULL,
daily_cost_currency VARCHAR(10) NULL,
auto_renew TINYINT(1) NOT NULL DEFAULT 0,

View File

@@ -2116,11 +2116,20 @@ final class Router
: $this->currentTimestamp();
$settledValueAmount = null;
$settledValueCurrency = null;
$settledFxFetchId = null;
if ($this->isCryptoCurrencyCode($purchaseCurrency)) {
$settledValueCurrency = $this->requiredCurrency($settings['report_currency'] ?? 'EUR', 'report_currency');
$settledFxFetchId = $this->resolveMeasurementFxFetchId($projectKey, ['measured_at' => $purchasedAt], true);
if ($settledFxFetchId === null) {
throw new ApiException(
'Es konnte kein FX-Snapshot fuer die Krypto-Zahlung gespeichert werden. Der Miner wird nicht ohne historische Kursreferenz angelegt.',
422,
['currency' => $purchaseCurrency, 'purchased_at' => $purchasedAt]
);
}
$settledValueAmount = $purchaseCurrency === $settledValueCurrency
? $purchaseCost
: $this->convertMiningAssetAmount((float) $purchaseCost, $purchaseCurrency, $settledValueCurrency, $purchasedAt);
: $this->convertMiningAssetAmount((float) $purchaseCost, $purchaseCurrency, $settledValueCurrency, $purchasedAt, $settledFxFetchId);
if ($settledValueAmount === null) {
throw new ApiException(
'Der aktuelle Kurs fuer die Krypto-Zahlung konnte nicht ermittelt werden. Der Miner wird nicht ohne feste Bewertung gespeichert.',
@@ -2145,6 +2154,7 @@ final class Router
'reference_price_currency' => $referencePriceCurrency,
'settled_value_amount' => $settledValueAmount,
'settled_value_currency' => $settledValueCurrency,
'settled_fx_fetch_id' => $settledFxFetchId,
'auto_renew' => $isAutoRenew ? 1 : 0,
'note' => $this->optionalString($input['note'] ?? ($offer['note'] ?? null), 1000),
'is_active' => 1,

View File

@@ -463,6 +463,12 @@ final class AnalyticsService
$settledCryptoSpendValue = $latestCurrency !== ''
? $this->settledCryptoSpendValue($purchasedMiners, $latestCurrency, $latest)
: null;
$settledCryptoSpendCurrentAsset = $latestAsset !== ''
? $this->settledCryptoSpendValue($purchasedMiners, $latestAsset, $latest)
: null;
$earnedCurrentAsset = $settledCryptoSpendCurrentAsset !== null
? $holdingsCurrentAsset + $settledCryptoSpendCurrentAsset
: $holdingsCurrentAsset;
$earnedValue = ($totalHoldingsValue !== null || $settledCryptoSpendValue !== null)
? (float) ($totalHoldingsValue ?? 0.0) + (float) ($settledCryptoSpendValue ?? 0.0)
: null;
@@ -504,10 +510,14 @@ final class AnalyticsService
'wallet_balance_current_asset' => $this->roundOrNull($walletBalanceCurrentAssetEquivalent, 6),
'wallet_balance_current_asset_direct' => $this->roundOrNull($walletBalanceCurrentAssetDirect, 6),
'holdings_current_asset' => $this->roundOrNull($holdingsCurrentAsset, 6),
'earned_current_asset' => $this->roundOrNull($earnedCurrentAsset, 6),
'wallet_value' => $this->roundOrNull($walletValue, 8),
'wallet_snapshot_measured_at' => $useWalletSnapshot ? (string) ($latestWalletSnapshot['measured_at'] ?? '') : null,
'total_holdings_value' => $this->roundOrNull($totalHoldingsValue, 8),
'variable_holdings_value' => $this->roundOrNull($totalHoldingsValue, 8),
'settled_crypto_spend_value' => $this->roundOrNull($settledCryptoSpendValue, 8),
'fixed_crypto_spend_value' => $this->roundOrNull($settledCryptoSpendValue, 8),
'fixed_crypto_spend_current_asset' => $this->roundOrNull($settledCryptoSpendCurrentAsset, 8),
'earned_value' => $this->roundOrNull($earnedValue, 8),
'break_even_remaining_amount' => $this->roundOrNull($breakEvenRemainingAmount, 8),
'break_even_days_overall' => $this->roundOrNull($breakEvenDaysOverall, 4),
@@ -1677,7 +1687,11 @@ final class AnalyticsService
continue;
}
$converted = $this->convertAmount($amount, $currency, $targetCurrency, $fxContext);
$historicalFxContext = [
'fx_fetch_id' => $miner['settled_fx_fetch_id'] ?? null,
'measured_at' => $miner['purchased_at'] ?? null,
];
$converted = $this->convertAmount($amount, $currency, $targetCurrency, $historicalFxContext);
if ($converted === null) {
continue;
}

View File

@@ -1005,12 +1005,12 @@ final class MiningRepository
'INSERT INTO ' . $this->table('purchased_miners') . ' (
project_key, owner_sub, miner_offer_id, purchased_at, label, runtime_months,
mining_speed_value, mining_speed_unit, bonus_speed_value, bonus_speed_unit,
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency, settled_value_amount, settled_value_currency,
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency, settled_value_amount, settled_value_currency, settled_fx_fetch_id,
daily_cost_amount, daily_cost_currency, auto_renew, note, is_active
) VALUES (
:project_key, :owner_sub, :miner_offer_id, :purchased_at, :label, :runtime_months,
:mining_speed_value, :mining_speed_unit, :bonus_speed_value, :bonus_speed_unit,
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency, :settled_value_amount, :settled_value_currency,
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency, :settled_value_amount, :settled_value_currency, :settled_fx_fetch_id,
:daily_cost_amount, :daily_cost_currency, :auto_renew, :note, :is_active
)
RETURNING *'
@@ -1023,12 +1023,12 @@ final class MiningRepository
'INSERT INTO ' . $this->table('purchased_miners') . ' (
project_key, owner_sub, miner_offer_id, purchased_at, label, runtime_months,
mining_speed_value, mining_speed_unit, bonus_speed_value, bonus_speed_unit,
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency, settled_value_amount, settled_value_currency,
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency, settled_value_amount, settled_value_currency, settled_fx_fetch_id,
daily_cost_amount, daily_cost_currency, auto_renew, note, is_active
) VALUES (
:project_key, :owner_sub, :miner_offer_id, :purchased_at, :label, :runtime_months,
:mining_speed_value, :mining_speed_unit, :bonus_speed_value, :bonus_speed_unit,
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency, :settled_value_amount, :settled_value_currency,
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency, :settled_value_amount, :settled_value_currency, :settled_fx_fetch_id,
:daily_cost_amount, :daily_cost_currency, :auto_renew, :note, :is_active
)'
);
@@ -1059,6 +1059,7 @@ final class MiningRepository
'reference_price_currency' => $payload['reference_price_currency'] ?? null,
'settled_value_amount' => $payload['settled_value_amount'] ?? null,
'settled_value_currency' => $payload['settled_value_currency'] ?? null,
'settled_fx_fetch_id' => $payload['settled_fx_fetch_id'] ?? null,
'daily_cost_amount' => $payload['daily_cost_amount'] ?? $this->deriveDailyCostAmount($payload['total_cost_amount'] ?? null, $payload['runtime_months'] ?? null),
'daily_cost_currency' => $payload['daily_cost_currency'] ?? ($payload['currency'] ?? null),
'auto_renew' => $payload['auto_renew'] ?? 0,
@@ -1071,12 +1072,12 @@ final class MiningRepository
'INSERT INTO ' . $this->table('purchased_miners') . ' (
project_key, owner_sub, miner_offer_id, purchased_at, label, runtime_months,
mining_speed_value, mining_speed_unit, bonus_speed_value, bonus_speed_unit,
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency, settled_value_amount, settled_value_currency,
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency, settled_value_amount, settled_value_currency, settled_fx_fetch_id,
daily_cost_amount, daily_cost_currency, auto_renew, note, is_active
) VALUES (
:project_key, :owner_sub, :miner_offer_id, :purchased_at, :label, :runtime_months,
:mining_speed_value, :mining_speed_unit, :bonus_speed_value, :bonus_speed_unit,
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency, :settled_value_amount, :settled_value_currency,
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency, :settled_value_amount, :settled_value_currency, :settled_fx_fetch_id,
:daily_cost_amount, :daily_cost_currency, :auto_renew, :note, :is_active
)
RETURNING *'
@@ -1089,12 +1090,12 @@ final class MiningRepository
'INSERT INTO ' . $this->table('purchased_miners') . ' (
project_key, owner_sub, miner_offer_id, purchased_at, label, runtime_months,
mining_speed_value, mining_speed_unit, bonus_speed_value, bonus_speed_unit,
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency, settled_value_amount, settled_value_currency,
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency, settled_value_amount, settled_value_currency, settled_fx_fetch_id,
daily_cost_amount, daily_cost_currency, auto_renew, note, is_active
) VALUES (
:project_key, :owner_sub, :miner_offer_id, :purchased_at, :label, :runtime_months,
:mining_speed_value, :mining_speed_unit, :bonus_speed_value, :bonus_speed_unit,
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency, :settled_value_amount, :settled_value_currency,
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency, :settled_value_amount, :settled_value_currency, :settled_fx_fetch_id,
:daily_cost_amount, :daily_cost_currency, :auto_renew, :note, :is_active
)'
);
@@ -1650,6 +1651,7 @@ final class MiningRepository
'reference_price_currency' => $payload['reference_price_currency'] ?? null,
'settled_value_amount' => $payload['settled_value_amount'] ?? null,
'settled_value_currency' => $payload['settled_value_currency'] ?? null,
'settled_fx_fetch_id' => $payload['settled_fx_fetch_id'] ?? null,
'daily_cost_amount' => $dailyCostAmount,
'daily_cost_currency' => $dailyCostCurrency,
'auto_renew' => $payload['auto_renew'] ?? 0,

View File

@@ -261,7 +261,8 @@ final class SchemaManager
}
if ($this->tableExists($this->prefix . 'purchased_miners') && (
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_value_amount') ||
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_value_currency')
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_value_currency') ||
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_fx_fetch_id')
)) {
$this->upgradePurchasedMinerSettlementColumns();
$applied[] = 'purchased_miner_settlement_columns';
@@ -410,7 +411,8 @@ final class SchemaManager
}
if ($this->tableExists($this->prefix . 'purchased_miners') && (
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_value_amount') ||
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_value_currency')
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_value_currency') ||
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_fx_fetch_id')
)) {
$this->upgradePurchasedMinerSettlementColumns();
$applied[] = 'purchased_miner_settlement_columns';
@@ -770,7 +772,8 @@ final class SchemaManager
}
if ($this->tableExists($this->prefix . 'purchased_miners') && (
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_value_amount') ||
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_value_currency')
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_value_currency') ||
!$this->columnExists($this->prefix . 'purchased_miners', 'settled_fx_fetch_id')
)) {
$upgrades[] = 'purchased_miner_settlement_columns';
}
@@ -1529,11 +1532,13 @@ final class SchemaManager
? [
'ALTER TABLE ' . $table . ' ADD COLUMN IF NOT EXISTS settled_value_amount NUMERIC(20,8)',
'ALTER TABLE ' . $table . ' ADD COLUMN IF NOT EXISTS settled_value_currency VARCHAR(10)',
'ALTER TABLE ' . $table . ' ADD COLUMN IF NOT EXISTS settled_fx_fetch_id BIGINT',
"UPDATE " . $table . " SET settled_value_amount = CASE WHEN reference_price_amount IS NOT NULL AND NULLIF(BTRIM(reference_price_currency), '') IS NOT NULL AND UPPER(reference_price_currency) <> UPPER(currency) THEN reference_price_amount ELSE total_cost_amount * 0.07 END, settled_value_currency = CASE WHEN reference_price_amount IS NOT NULL AND NULLIF(BTRIM(reference_price_currency), '') IS NOT NULL AND UPPER(reference_price_currency) <> UPPER(currency) THEN reference_price_currency ELSE 'EUR' END WHERE UPPER(currency) IN ('ADA','ARB','BNB','BTC','DAI','DOGE','DOT','ETH','LINK','LTC','SOL','USDC','USDT','XRP') AND settled_value_amount IS NULL",
]
: [
'ALTER TABLE `' . $table . '` ADD COLUMN settled_value_amount DECIMAL(20,8) NULL',
'ALTER TABLE `' . $table . '` ADD COLUMN settled_value_currency VARCHAR(10) NULL',
'ALTER TABLE `' . $table . '` ADD COLUMN settled_fx_fetch_id BIGINT UNSIGNED NULL',
"UPDATE `" . $table . "` SET settled_value_amount = CASE WHEN reference_price_amount IS NOT NULL AND NULLIF(TRIM(reference_price_currency), '') IS NOT NULL AND UPPER(reference_price_currency) <> UPPER(currency) THEN reference_price_amount ELSE total_cost_amount * 0.07 END, settled_value_currency = CASE WHEN reference_price_amount IS NOT NULL AND NULLIF(TRIM(reference_price_currency), '') IS NOT NULL AND UPPER(reference_price_currency) <> UPPER(currency) THEN reference_price_currency ELSE 'EUR' END WHERE UPPER(currency) IN ('ADA','ARB','BNB','BTC','DAI','DOGE','DOT','ETH','LINK','LTC','SOL','USDC','USDT','XRP') AND settled_value_amount IS NULL",
];