From 75a6568d7a29be09911cdc2960979788968bc3ca Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Thu, 20 Aug 2026 21:59:02 +0200 Subject: [PATCH] asdsd --- custom/apps/mining-checker/assets/js/app.js | 69 ++++++++++++++----- .../src/Domain/AnalyticsService.php | 45 ++++++++---- 2 files changed, 84 insertions(+), 30 deletions(-) diff --git a/custom/apps/mining-checker/assets/js/app.js b/custom/apps/mining-checker/assets/js/app.js index 1c5d0b44..8e44a097 100644 --- a/custom/apps/mining-checker/assets/js/app.js +++ b/custom/apps/mining-checker/assets/js/app.js @@ -92,6 +92,15 @@ function setCookie(name, value, maxAgeSeconds) { document.cookie = `${name}=${encodeURIComponent(value)}; path=/; max-age=${maxAgeSeconds}; samesite=lax`; } + + const CRYPTO_RUNTIME_CONFIGS = { + 3: { discountPercent: 0, bonusPercent: 5 }, + 6: { discountPercent: 10, bonusPercent: 10 }, + 12: { discountPercent: 35, bonusPercent: 10 }, + 18: { discountPercent: 45, bonusPercent: 15 }, + 24: { discountPercent: 55, bonusPercent: 20 }, + 36: { discountPercent: 65, bonusPercent: 20 }, + }; const debugBus = desktopDebugBus || window.__nexusDebugBus || { enabled: initialDebugMode, listener: null, @@ -1306,10 +1315,34 @@ }; }) .sort((left, right) => left.__runtimeDelta - right.__runtimeDelta || left.__hashrateDelta - right.__hashrateDelta)[0] || null; - const preferredOfferRequiredCoins = preferredMinerOffer + const syntheticPreferredMinerOffer = (() => { + const baseUsdAmount = Number(currentSettings.crypto_base_price_amount); + const runtimeConfig = CRYPTO_RUNTIME_CONFIGS[targetOfferRuntimeMonths]; + if (!Number.isFinite(baseUsdAmount) || baseUsdAmount <= 0 || !runtimeConfig || targetOfferHashrateKh <= 0) { + return null; + } + + const speedFactor = targetOfferHashrateKh / 50; + const runtimeFactor = targetOfferRuntimeMonths / 3; + const discountFactor = Math.max(0, 1 - (Number(runtimeConfig.discountPercent) / 100)); + const usdAmount = baseUsdAmount * speedFactor * runtimeFactor * discountFactor; + const effectiveAmount = convertCurrencyValue(usdAmount, 'USD', currentMiningCurrency); + + return { + label: `Crypto Server · ${fmtNumber(targetOfferHashrateKh, 0)} kH/s · ${targetOfferRuntimeMonths} Monate`, + usd_display_price_amount: usdAmount, + usd_display_price_currency: 'USD', + effective_price_amount: effectiveAmount, + effective_price_currency: currentMiningCurrency, + runtime_months: targetOfferRuntimeMonths, + offer_hashrate_mh: targetOfferHashrateKh / 1000, + }; + })(); + const resolvedPreferredMinerOffer = preferredMinerOffer || syntheticPreferredMinerOffer; + const preferredOfferRequiredCoins = resolvedPreferredMinerOffer ? convertCurrencyValue( - preferredMinerOffer.effective_price_amount ?? preferredMinerOffer.crypto_display_price_amount, - preferredMinerOffer.effective_price_currency || preferredMinerOffer.crypto_display_price_currency || currentMiningCurrency, + resolvedPreferredMinerOffer.effective_price_amount ?? resolvedPreferredMinerOffer.crypto_display_price_amount ?? resolvedPreferredMinerOffer.usd_display_price_amount, + resolvedPreferredMinerOffer.effective_price_currency || resolvedPreferredMinerOffer.crypto_display_price_currency || resolvedPreferredMinerOffer.usd_display_price_currency || currentMiningCurrency, currentMiningCurrency ) : null; @@ -3272,6 +3305,21 @@ : null, ].filter(Boolean).join(' · ') || 'Kein umrechenbarer Kurs am letzten Punkt', }), + resolvedPreferredMinerOffer ? h(StatCard, { + key: 'preferred-offer-target', + label: `Zielminer ${fmtNumber(targetOfferHashrateKh, 0)} kH/s · ${targetOfferRuntimeMonths} Monate`, + value: preferredOfferRequiredCoins !== null ? `${fmtNumber(preferredOfferRequiredCoins, 4)} ${currentMiningCurrency}` : 'n/a', + sub: [ + resolvedPreferredMinerOffer.usd_display_price_amount !== null ? `≈ ${fmtMoney(resolvedPreferredMinerOffer.usd_display_price_amount, 'USD')}` : null, + preferredOfferRemainingDays !== null + ? `Rest ${fmtNumber(preferredOfferRemainingDays, 2)} Tage` + : 'Resttage n/a', + preferredOfferRemainingCoins !== null + ? `Rest-${currentMiningCurrency} ${fmtNumber(preferredOfferRemainingCoins, 4)}` + : null, + preferredOfferEta ? `ETA ${fmtDate(preferredOfferEta)}` : null, + ].filter(Boolean).join(' · '), + }) : null, h(StatCard, { key: 'profit', label: 'Theoretischer Tagesgewinn', @@ -3310,21 +3358,6 @@ yLabel: `Kurs ${reportCurrency}`, })), ]), - preferredMinerOffer ? h(StatCard, { - key: 'preferred-offer-target', - label: `Zielminer ${fmtNumber(targetOfferHashrateKh, 0)} kH/s · ${targetOfferRuntimeMonths} Monate`, - value: preferredOfferRequiredCoins !== null ? `${fmtNumber(preferredOfferRequiredCoins, 4)} ${currentMiningCurrency}` : 'n/a', - sub: [ - preferredMinerOffer.usd_display_price_amount !== null ? `≈ ${fmtMoney(preferredMinerOffer.usd_display_price_amount, 'USD')}` : null, - preferredOfferRemainingDays !== null - ? `Rest ${fmtNumber(preferredOfferRemainingDays, 2)} Tage` - : 'Resttage n/a', - preferredOfferRemainingCoins !== null - ? `Rest-${currentMiningCurrency} ${fmtNumber(preferredOfferRemainingCoins, 4)}` - : null, - preferredOfferEta ? `ETA ${fmtDate(preferredOfferEta)}` : null, - ].filter(Boolean).join(' · '), - }) : null, panel('Zielmonitor', `Rest-${currentCoinCurrency} und Resttage werden gegen den letzten verfuegbaren Kurs je Zielwaehrung berechnet.`, h('div', { className: 'mc-target-grid' }, currentTargets.map((target, index) => h('div', { diff --git a/custom/apps/mining-checker/src/Domain/AnalyticsService.php b/custom/apps/mining-checker/src/Domain/AnalyticsService.php index 362d8b9f..b4791739 100644 --- a/custom/apps/mining-checker/src/Domain/AnalyticsService.php +++ b/custom/apps/mining-checker/src/Domain/AnalyticsService.php @@ -417,14 +417,14 @@ final class AnalyticsService $latestWalletSnapshotTs = is_array($latestWalletSnapshot) ? $this->utcTimestamp((string) ($latestWalletSnapshot['measured_at'] ?? '')) : 0; - $latestLedgerActivityTs = $this->latestWalletLedgerActivityTimestamp($payouts, $walletWithdrawals, $purchasedMiners); - $useWalletSnapshot = is_array($latestWalletSnapshot) - && $latestWalletSnapshotTs > 0 - && $latestWalletSnapshotTs >= $latestLedgerActivityTs; + $useWalletSnapshot = is_array($latestWalletSnapshot) && $latestWalletSnapshotTs > 0; if ($useWalletSnapshot) { $snapshotBalances = $this->walletSnapshotBalances($latestWalletSnapshot); if ($snapshotBalances !== []) { - $walletBalances = $snapshotBalances; + $walletBalances = $this->mergeWalletBalances( + $snapshotBalances, + $this->walletBalances($payouts, $walletWithdrawals, $purchasedMiners, 0, $latestWalletSnapshotTs) + ); } } $latestAsset = strtoupper(trim((string) ($latest['coin_currency'] ?? $settings['crypto_currency'] ?? 'DOGE'))); @@ -437,18 +437,14 @@ final class AnalyticsService $walletBalanceCurrentAssetDirect > 0 ? $walletBalanceCurrentAssetDirect : ( - $useWalletSnapshot - ? $this->walletSnapshotValue($latestWalletSnapshot, $latestAsset, $latest) - : $this->walletBalanceValue($walletBalances, $latestAsset, $latest) + $this->walletBalanceValue($walletBalances, $latestAsset, $latest) ) ) : null; $holdingsCurrentAsset = ($walletBalanceCurrentAssetEquivalent !== null ? $walletBalanceCurrentAssetEquivalent : 0.0) + $adjustedVisibleCoins; $walletValue = $latestCurrency !== '' ? ( - $useWalletSnapshot - ? $this->walletSnapshotValue($latestWalletSnapshot, $latestCurrency, $latest) - : $this->walletBalanceValue($walletBalances, $latestCurrency, $latest) + $this->walletBalanceValue($walletBalances, $latestCurrency, $latest) ) : null; $effectivePricePerCoin = is_numeric($latest['effective_price_per_coin'] ?? null) ? (float) $latest['effective_price_per_coin'] : null; @@ -1585,7 +1581,7 @@ final class AnalyticsService return $endIndex - $startIndex + 1; } - private function walletBalances(array $payouts, array $walletWithdrawals, array $purchasedMiners, int $measurementTs): array + private function walletBalances(array $payouts, array $walletWithdrawals, array $purchasedMiners, int $measurementTs, int $afterTs = 0): array { $balances = []; @@ -1594,6 +1590,9 @@ final class AnalyticsService if ($measurementTs > 0 && $payoutTs > $measurementTs) { continue; } + if ($afterTs > 0 && $payoutTs <= $afterTs) { + continue; + } $currency = strtoupper(trim((string) ($payout['payout_currency'] ?? ''))); $amount = is_numeric($payout['coins_amount'] ?? null) ? (float) $payout['coins_amount'] : null; @@ -1609,6 +1608,9 @@ final class AnalyticsService if ($measurementTs > 0 && $purchaseTs > $measurementTs) { continue; } + if ($afterTs > 0 && $purchaseTs <= $afterTs) { + continue; + } if ($this->entryFundingSource($miner) !== 'reinvest') { continue; } @@ -1627,6 +1629,9 @@ final class AnalyticsService if ($measurementTs > 0 && $withdrawalTs > $measurementTs) { continue; } + if ($afterTs > 0 && $withdrawalTs <= $afterTs) { + continue; + } $currency = strtoupper(trim((string) ($withdrawal['withdrawal_currency'] ?? ''))); $amount = is_numeric($withdrawal['coins_amount'] ?? null) ? (float) $withdrawal['coins_amount'] : null; @@ -1641,6 +1646,22 @@ final class AnalyticsService return array_map(fn (float $value): float => round($value, 8), $balances); } + private function mergeWalletBalances(array $baseBalances, array $deltaBalances): array + { + $merged = $baseBalances; + foreach ($deltaBalances as $currency => $amount) { + $normalizedCurrency = strtoupper(trim((string) $currency)); + if ($normalizedCurrency === '' || !is_numeric($amount)) { + continue; + } + + $merged[$normalizedCurrency] = round((float) ($merged[$normalizedCurrency] ?? 0.0) + (float) $amount, 8); + } + + ksort($merged); + return $merged; + } + private function latestWalletSnapshot(array $walletSnapshots): ?array { foreach ($walletSnapshots as $snapshot) {