calculation
This commit is contained in:
@@ -355,26 +355,32 @@ final class AnalyticsService
|
||||
|
||||
$price = $latestPriceByCurrency[$currency] ?? $this->convertLatestPrice($latestPriceByCurrency, $currency, $latest);
|
||||
$requiredDoge = ($price && $targetAmount !== null) ? $targetAmount / $price : null;
|
||||
$remainingDoge = $requiredDoge !== null ? $requiredDoge - (float) ($latest['coins_total_effective'] ?? $latest['coins_total']) : null;
|
||||
$remainingDays = (
|
||||
$remainingDoge !== null &&
|
||||
$remainingDogeAtUpload = $requiredDoge !== null ? $requiredDoge - (float) ($latest['coins_total_effective'] ?? $latest['coins_total']) : null;
|
||||
$remainingDaysAtUpload = (
|
||||
$remainingDogeAtUpload !== null &&
|
||||
$latest['doge_per_day_interval'] !== null &&
|
||||
(float) $latest['doge_per_day_interval'] > 0
|
||||
) ? $remainingDoge / (float) $latest['doge_per_day_interval'] : null;
|
||||
) ? $remainingDogeAtUpload / (float) $latest['doge_per_day_interval'] : null;
|
||||
$targetEtaAt = null;
|
||||
if ($remainingDays !== null) {
|
||||
if ($remainingDays <= 0) {
|
||||
if ($remainingDaysAtUpload !== null) {
|
||||
if ($remainingDaysAtUpload <= 0) {
|
||||
$targetEtaAt = (string) ($latest['measured_at'] ?? '');
|
||||
} elseif (!empty($latest['measured_at'])) {
|
||||
try {
|
||||
$targetEtaAt = $this->formatUtcTimestamp(
|
||||
$this->utcTimestamp((string) $latest['measured_at']) + (int) round($remainingDays * 86400)
|
||||
$this->utcTimestamp((string) $latest['measured_at']) + (int) round($remainingDaysAtUpload * 86400)
|
||||
);
|
||||
} catch (\Throwable) {
|
||||
$targetEtaAt = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
$remainingDays = $targetEtaAt !== null
|
||||
? max(0.0, ($this->utcTimestamp($targetEtaAt) - time()) / 86400)
|
||||
: null;
|
||||
$remainingDoge = ($remainingDays !== null && $latest['doge_per_day_interval'] !== null)
|
||||
? max(0.0, $remainingDays * (float) $latest['doge_per_day_interval'])
|
||||
: $remainingDogeAtUpload;
|
||||
|
||||
$targetSummary[] = array_merge($target, [
|
||||
'effective_target_amount_fiat' => $this->roundOrNull($targetAmount, 2),
|
||||
@@ -384,9 +390,11 @@ final class AnalyticsService
|
||||
'latest_price_for_currency' => $price,
|
||||
'required_doge' => $this->roundOrNull($requiredDoge, 6),
|
||||
'remaining_doge' => $this->roundOrNull($remainingDoge, 6),
|
||||
'remaining_doge_at_upload' => $this->roundOrNull($remainingDogeAtUpload, 6),
|
||||
'remaining_days_at_upload' => $this->roundOrNull($remainingDaysAtUpload, 4),
|
||||
'remaining_days' => $this->roundOrNull($remainingDays, 4),
|
||||
'target_eta_at' => $targetEtaAt,
|
||||
'status' => $remainingDoge !== null && $remainingDoge <= 0 ? 'reached' : 'open',
|
||||
'status' => $remainingDays !== null && $remainingDays <= 0 ? 'reached' : 'open',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -452,6 +460,12 @@ final class AnalyticsService
|
||||
$totalHoldingsValue = ($walletValue !== null || $currentVisibleValue !== null)
|
||||
? (float) ($walletValue ?? 0.0) + (float) ($currentVisibleValue ?? 0.0)
|
||||
: null;
|
||||
$settledCryptoSpendValue = $latestCurrency !== ''
|
||||
? $this->settledCryptoSpendValue($purchasedMiners, $latestCurrency, $latest)
|
||||
: null;
|
||||
$earnedValue = ($totalHoldingsValue !== null || $settledCryptoSpendValue !== null)
|
||||
? (float) ($totalHoldingsValue ?? 0.0) + (float) ($settledCryptoSpendValue ?? 0.0)
|
||||
: null;
|
||||
$currentDailyRevenue = is_numeric($latest['theoretical_daily_revenue'] ?? null) ? (float) $latest['theoretical_daily_revenue'] : null;
|
||||
$breakEvenRemainingAmount = ($cashInvestedCapital !== null && $totalHoldingsValue !== null)
|
||||
? max(0.0, $cashInvestedCapital - $totalHoldingsValue)
|
||||
@@ -493,6 +507,8 @@ final class AnalyticsService
|
||||
'wallet_value' => $this->roundOrNull($walletValue, 8),
|
||||
'wallet_snapshot_measured_at' => $useWalletSnapshot ? (string) ($latestWalletSnapshot['measured_at'] ?? '') : null,
|
||||
'total_holdings_value' => $this->roundOrNull($totalHoldingsValue, 8),
|
||||
'settled_crypto_spend_value' => $this->roundOrNull($settledCryptoSpendValue, 8),
|
||||
'earned_value' => $this->roundOrNull($earnedValue, 8),
|
||||
'break_even_remaining_amount' => $this->roundOrNull($breakEvenRemainingAmount, 8),
|
||||
'break_even_days_overall' => $this->roundOrNull($breakEvenDaysOverall, 4),
|
||||
'break_even_eta_at' => $breakEvenProjection['eta'] ?? null,
|
||||
@@ -1646,6 +1662,33 @@ final class AnalyticsService
|
||||
return array_map(fn (float $value): float => round($value, 8), $balances);
|
||||
}
|
||||
|
||||
private function settledCryptoSpendValue(array $purchasedMiners, string $targetCurrency, ?array $fxContext = null): ?float
|
||||
{
|
||||
$total = 0.0;
|
||||
$matched = false;
|
||||
foreach ($purchasedMiners as $miner) {
|
||||
if ($this->entryFundingSource($miner) !== 'reinvest') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$amount = is_numeric($miner['settled_value_amount'] ?? null) ? (float) $miner['settled_value_amount'] : null;
|
||||
$currency = strtoupper(trim((string) ($miner['settled_value_currency'] ?? '')));
|
||||
if ($amount === null || $currency === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$converted = $this->convertAmount($amount, $currency, $targetCurrency, $fxContext);
|
||||
if ($converted === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$matched = true;
|
||||
$total += $converted;
|
||||
}
|
||||
|
||||
return $matched ? $total : null;
|
||||
}
|
||||
|
||||
private function mergeWalletBalances(array $baseBalances, array $deltaBalances): array
|
||||
{
|
||||
$merged = $baseBalances;
|
||||
@@ -1765,6 +1808,13 @@ final class AnalyticsService
|
||||
$balances[$normalizedCode] = round((float) $balance, 8);
|
||||
}
|
||||
|
||||
// A wallet screenshot's primary balance is authoritative even when OCR did not
|
||||
// expose a complete per-asset balance list.
|
||||
$walletCurrency = strtoupper(trim((string) ($snapshot['wallet_currency'] ?? '')));
|
||||
if ($walletCurrency !== '' && is_numeric($snapshot['wallet_balance'] ?? null)) {
|
||||
$balances[$walletCurrency] = round((float) $snapshot['wallet_balance'], 8);
|
||||
}
|
||||
|
||||
ksort($balances);
|
||||
return $balances;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user