ysdsad
This commit is contained in:
@@ -594,6 +594,8 @@ final class Router
|
||||
'auto_renew' => !empty($plan['auto_renew']) ? 1 : 0,
|
||||
'total_cost_amount' => $plan['total_cost_amount'],
|
||||
'currency' => $plan['currency'],
|
||||
'daily_cost_amount' => $plan['daily_cost_amount'] ?? null,
|
||||
'daily_cost_currency' => $plan['daily_cost_currency'] ?? null,
|
||||
'note' => $plan['note'] ?? null,
|
||||
'is_active' => !empty($plan['is_active']) ? 1 : 0,
|
||||
]);
|
||||
@@ -731,6 +733,8 @@ final class Router
|
||||
'usd_reference_amount' => $miner['usd_reference_amount'] ?? null,
|
||||
'reference_price_amount' => $miner['reference_price_amount'] ?? null,
|
||||
'reference_price_currency' => $miner['reference_price_currency'] ?? null,
|
||||
'daily_cost_amount' => $miner['daily_cost_amount'] ?? null,
|
||||
'daily_cost_currency' => $miner['daily_cost_currency'] ?? null,
|
||||
'auto_renew' => !empty($miner['auto_renew']) ? 1 : 0,
|
||||
'note' => $miner['note'] ?? null,
|
||||
'is_active' => !empty($miner['is_active']) ? 1 : 0,
|
||||
|
||||
@@ -209,7 +209,7 @@ final class AnalyticsService
|
||||
}
|
||||
}
|
||||
|
||||
$effectiveDailyCost = $includeFullDetail ? $this->effectiveDailyCost($costPlans, $measuredTs, $priceCurrency, $row) : null;
|
||||
$effectiveDailyCost = $includeFullDetail ? $this->effectiveDailyCost($costPlans, $measuredTs, $priceCurrency, $row, $purchasedMiners) : null;
|
||||
$currentValue = ($includeFullDetail && $price !== null) ? $visibleCoinsTotal * $price : null;
|
||||
$currentValueEffective = ($includeFullDetail && $price !== null) ? $effectiveCoinsTotal * $price : null;
|
||||
$theoreticalDailyRevenue = ($includeFullDetail && $price !== null && $perDayInterval !== null) ? $perDayInterval * $price : null;
|
||||
@@ -636,7 +636,7 @@ final class AnalyticsService
|
||||
return $value === null ? null : round($value, $precision);
|
||||
}
|
||||
|
||||
private function effectiveDailyCost(array $costPlans, int $measurementTs, ?string $currency, ?array $fxContext = null): ?float
|
||||
private function effectiveDailyCost(array $costPlans, int $measurementTs, ?string $currency, ?array $fxContext = null, array $purchasedMiners = []): ?float
|
||||
{
|
||||
if ($currency === null) {
|
||||
return null;
|
||||
@@ -644,31 +644,56 @@ final class AnalyticsService
|
||||
|
||||
$dailyTotal = 0.0;
|
||||
$matched = false;
|
||||
|
||||
$entries = [];
|
||||
foreach ($costPlans as $plan) {
|
||||
if (empty($plan['is_active'])) {
|
||||
$entries[] = [
|
||||
'entry' => $plan,
|
||||
'start_field' => 'starts_at',
|
||||
];
|
||||
}
|
||||
foreach ($purchasedMiners as $miner) {
|
||||
$entries[] = [
|
||||
'entry' => $miner,
|
||||
'start_field' => 'purchased_at',
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($entries as $wrappedEntry) {
|
||||
$entry = is_array($wrappedEntry['entry'] ?? null) ? $wrappedEntry['entry'] : [];
|
||||
$startField = (string) ($wrappedEntry['start_field'] ?? 'starts_at');
|
||||
if (empty($entry['is_active'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$startTs = $this->utcTimestamp((string) ($plan['starts_at'] ?? ''));
|
||||
$runtimeMonths = (int) ($plan['runtime_months'] ?? 0);
|
||||
$startTs = $this->utcTimestamp((string) ($entry[$startField] ?? ''));
|
||||
$runtimeMonths = (int) ($entry['runtime_months'] ?? 0);
|
||||
if ($startTs <= 0 || $runtimeMonths <= 0 || $measurementTs < $startTs) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$runtimeDays = $runtimeMonths * 30.4375;
|
||||
$endTs = (int) round($startTs + ($runtimeDays * 86400));
|
||||
$isCovered = !empty($plan['auto_renew']) || $measurementTs <= $endTs;
|
||||
if (!$isCovered) {
|
||||
if (!$this->entryIsCovered($entry, $measurementTs, $startField)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$planDailyCost = (float) $plan['total_cost_amount'] / $runtimeDays;
|
||||
$convertedDailyCost = $this->convertAmount(
|
||||
$planDailyCost,
|
||||
(string) ($plan['currency'] ?? ''),
|
||||
$currency,
|
||||
$fxContext
|
||||
);
|
||||
$storedDailyCost = is_numeric($entry['daily_cost_amount'] ?? null) ? (float) $entry['daily_cost_amount'] : null;
|
||||
$entryCurrency = strtoupper(trim((string) ($entry['daily_cost_currency'] ?? $entry['currency'] ?? '')));
|
||||
if ($entryCurrency === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$planDailyCost = $storedDailyCost;
|
||||
if ($planDailyCost === null || $planDailyCost <= 0) {
|
||||
$amount = is_numeric($entry['total_cost_amount'] ?? null) ? (float) $entry['total_cost_amount'] : null;
|
||||
if ($amount === null || $amount <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$runtimeDays = $runtimeMonths * 30.4375;
|
||||
$planDailyCost = $amount / $runtimeDays;
|
||||
}
|
||||
|
||||
$convertedDailyCost = $this->convertAmount($planDailyCost, $entryCurrency, $currency, $fxContext);
|
||||
if ($convertedDailyCost === null) {
|
||||
continue;
|
||||
}
|
||||
@@ -996,7 +1021,7 @@ final class AnalyticsService
|
||||
|
||||
$runtimeDays = $runtimeMonths * 30.4375;
|
||||
$endTs = (int) round($startTs + ($runtimeDays * 86400));
|
||||
return !empty($entry['auto_renew']) || $checkTs <= $endTs;
|
||||
return $this->entryAutoRenewEnabled($entry) || $checkTs <= $endTs;
|
||||
}
|
||||
|
||||
private function normalizeHashrateMh(mixed $value, mixed $unit): float
|
||||
@@ -1018,6 +1043,29 @@ final class AnalyticsService
|
||||
return array_map(fn (mixed $entry): mixed => is_array($entry) ? $this->normalizeLegacyHashrateEntry($entry) : $entry, $entries);
|
||||
}
|
||||
|
||||
private function entryAutoRenewEnabled(array $entry): bool
|
||||
{
|
||||
if ($this->entryIsCryptoPaid($entry)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !empty($entry['auto_renew']);
|
||||
}
|
||||
|
||||
private function entryIsCryptoPaid(array $entry): bool
|
||||
{
|
||||
$paymentType = strtolower(trim((string) ($entry['payment_type'] ?? '')));
|
||||
if ($paymentType === 'crypto') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$currency = strtoupper(trim((string) ($entry['currency'] ?? '')));
|
||||
return in_array($currency, [
|
||||
'ADA', 'ARB', 'AVAX', 'BNB', 'BTC', 'CTC', 'DAI', 'DOGE', 'DOT', 'ETH',
|
||||
'HSH', 'LINK', 'LTC', 'MATIC', 'SOL', 'TRX', 'USDC', 'USDT', 'XMR', 'XRP',
|
||||
], true);
|
||||
}
|
||||
|
||||
private function normalizeLegacyHashrateEntry(array $entry): array
|
||||
{
|
||||
$label = trim((string) ($entry['label'] ?? ''));
|
||||
@@ -1522,7 +1570,7 @@ final class AnalyticsService
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!empty($entry['auto_renew']) || $runtimeMonths <= 0) {
|
||||
if ($this->entryAutoRenewEnabled($entry) || $runtimeMonths <= 0) {
|
||||
return $days - $startIndex;
|
||||
}
|
||||
|
||||
@@ -1807,7 +1855,7 @@ final class AnalyticsService
|
||||
|
||||
private function entryFundingSource(array $entry): string
|
||||
{
|
||||
return !empty($entry['auto_renew']) ? 'cash' : 'reinvest';
|
||||
return $this->entryIsCryptoPaid($entry) ? 'reinvest' : 'cash';
|
||||
}
|
||||
|
||||
private function investmentBasisAmount(array $entry): ?float
|
||||
@@ -1933,7 +1981,7 @@ final class AnalyticsService
|
||||
|
||||
private function entryCoverageEndTimestamp(array $entry, string $startField = 'starts_at'): ?int
|
||||
{
|
||||
if (!empty($entry['auto_renew'])) {
|
||||
if ($this->entryAutoRenewEnabled($entry)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -239,10 +239,12 @@ final class MiningRepository
|
||||
$stmt = $this->pdo->prepare(
|
||||
'INSERT INTO ' . $this->table('cost_plans') . ' (
|
||||
project_key, owner_sub, label, starts_at, runtime_months, mining_speed_value, mining_speed_unit,
|
||||
bonus_speed_value, bonus_speed_unit, auto_renew, base_price_amount, payment_type, total_cost_amount, currency, note, is_active
|
||||
bonus_speed_value, bonus_speed_unit, auto_renew, base_price_amount, payment_type, total_cost_amount, currency,
|
||||
daily_cost_amount, daily_cost_currency, note, is_active
|
||||
) VALUES (
|
||||
:project_key, :owner_sub, :label, :starts_at, :runtime_months, :mining_speed_value, :mining_speed_unit,
|
||||
:bonus_speed_value, :bonus_speed_unit, :auto_renew, :base_price_amount, :payment_type, :total_cost_amount, :currency, :note, :is_active
|
||||
:bonus_speed_value, :bonus_speed_unit, :auto_renew, :base_price_amount, :payment_type, :total_cost_amount, :currency,
|
||||
:daily_cost_amount, :daily_cost_currency, :note, :is_active
|
||||
)
|
||||
RETURNING *'
|
||||
);
|
||||
@@ -253,10 +255,12 @@ final class MiningRepository
|
||||
$stmt = $this->pdo->prepare(
|
||||
'INSERT INTO ' . $this->table('cost_plans') . ' (
|
||||
project_key, owner_sub, label, starts_at, runtime_months, mining_speed_value, mining_speed_unit,
|
||||
bonus_speed_value, bonus_speed_unit, auto_renew, base_price_amount, payment_type, total_cost_amount, currency, note, is_active
|
||||
bonus_speed_value, bonus_speed_unit, auto_renew, base_price_amount, payment_type, total_cost_amount, currency,
|
||||
daily_cost_amount, daily_cost_currency, note, is_active
|
||||
) VALUES (
|
||||
:project_key, :owner_sub, :label, :starts_at, :runtime_months, :mining_speed_value, :mining_speed_unit,
|
||||
:bonus_speed_value, :bonus_speed_unit, :auto_renew, :base_price_amount, :payment_type, :total_cost_amount, :currency, :note, :is_active
|
||||
:bonus_speed_value, :bonus_speed_unit, :auto_renew, :base_price_amount, :payment_type, :total_cost_amount, :currency,
|
||||
:daily_cost_amount, :daily_cost_currency, :note, :is_active
|
||||
)'
|
||||
);
|
||||
$stmt->execute($this->normalizeInsertPayload($projectKey, $payload));
|
||||
@@ -1001,11 +1005,13 @@ 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, auto_renew, note, is_active
|
||||
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency,
|
||||
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, :auto_renew, :note, :is_active
|
||||
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency,
|
||||
:daily_cost_amount, :daily_cost_currency, :auto_renew, :note, :is_active
|
||||
)
|
||||
RETURNING *'
|
||||
);
|
||||
@@ -1017,11 +1023,13 @@ 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, auto_renew, note, is_active
|
||||
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency,
|
||||
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, :auto_renew, :note, :is_active
|
||||
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency,
|
||||
:daily_cost_amount, :daily_cost_currency, :auto_renew, :note, :is_active
|
||||
)'
|
||||
);
|
||||
$stmt->execute($this->normalizePurchasedPayload($projectKey, $offerId, $payload));
|
||||
@@ -1049,6 +1057,8 @@ final class MiningRepository
|
||||
'usd_reference_amount' => $payload['usd_reference_amount'] ?? null,
|
||||
'reference_price_amount' => $payload['reference_price_amount'] ?? null,
|
||||
'reference_price_currency' => $payload['reference_price_currency'] ?? 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,
|
||||
'note' => $payload['note'] ?? null,
|
||||
'is_active' => $payload['is_active'] ?? 1,
|
||||
@@ -1059,11 +1069,13 @@ 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, auto_renew, note, is_active
|
||||
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency,
|
||||
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, :auto_renew, :note, :is_active
|
||||
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency,
|
||||
:daily_cost_amount, :daily_cost_currency, :auto_renew, :note, :is_active
|
||||
)
|
||||
RETURNING *'
|
||||
);
|
||||
@@ -1075,11 +1087,13 @@ 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, auto_renew, note, is_active
|
||||
total_cost_amount, currency, usd_reference_amount, reference_price_amount, reference_price_currency,
|
||||
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, :auto_renew, :note, :is_active
|
||||
:total_cost_amount, :currency, :usd_reference_amount, :reference_price_amount, :reference_price_currency,
|
||||
:daily_cost_amount, :daily_cost_currency, :auto_renew, :note, :is_active
|
||||
)'
|
||||
);
|
||||
$stmt->execute($params);
|
||||
@@ -1567,6 +1581,9 @@ final class MiningRepository
|
||||
|
||||
private function normalizeInsertPayload(string $projectKey, array $payload): array
|
||||
{
|
||||
$dailyCostAmount = $payload['daily_cost_amount'] ?? $this->deriveDailyCostAmount($payload['total_cost_amount'] ?? null, $payload['runtime_months'] ?? null);
|
||||
$dailyCostCurrency = $payload['daily_cost_currency'] ?? ($payload['currency'] ?? null);
|
||||
|
||||
return [
|
||||
'project_key' => $projectKey,
|
||||
'owner_sub' => $this->ownerSub,
|
||||
@@ -1582,6 +1599,8 @@ final class MiningRepository
|
||||
'payment_type' => $payload['payment_type'] ?? 'fiat',
|
||||
'total_cost_amount' => $payload['total_cost_amount'],
|
||||
'currency' => $payload['currency'],
|
||||
'daily_cost_amount' => $dailyCostAmount,
|
||||
'daily_cost_currency' => $dailyCostCurrency,
|
||||
'note' => $payload['note'],
|
||||
'is_active' => $payload['is_active'],
|
||||
];
|
||||
@@ -1608,6 +1627,9 @@ final class MiningRepository
|
||||
|
||||
private function normalizePurchasedPayload(string $projectKey, ?int $offerId, array $payload): array
|
||||
{
|
||||
$dailyCostAmount = $payload['daily_cost_amount'] ?? $this->deriveDailyCostAmount($payload['total_cost_amount'] ?? null, $payload['runtime_months'] ?? null);
|
||||
$dailyCostCurrency = $payload['daily_cost_currency'] ?? ($payload['currency'] ?? null);
|
||||
|
||||
return [
|
||||
'project_key' => $projectKey,
|
||||
'owner_sub' => $this->ownerSub,
|
||||
@@ -1624,12 +1646,33 @@ final class MiningRepository
|
||||
'usd_reference_amount' => $payload['usd_reference_amount'],
|
||||
'reference_price_amount' => $payload['reference_price_amount'] ?? null,
|
||||
'reference_price_currency' => $payload['reference_price_currency'] ?? null,
|
||||
'daily_cost_amount' => $dailyCostAmount,
|
||||
'daily_cost_currency' => $dailyCostCurrency,
|
||||
'auto_renew' => $payload['auto_renew'] ?? 0,
|
||||
'note' => $payload['note'],
|
||||
'is_active' => $payload['is_active'],
|
||||
];
|
||||
}
|
||||
|
||||
private function deriveDailyCostAmount(mixed $totalCostAmount, mixed $runtimeMonths): ?float
|
||||
{
|
||||
if (!is_numeric($totalCostAmount) || !is_numeric($runtimeMonths)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$months = (float) $runtimeMonths;
|
||||
if ($months <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$runtimeDays = $months * 30.4375;
|
||||
if ($runtimeDays <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return round(((float) $totalCostAmount) / $runtimeDays, 10);
|
||||
}
|
||||
|
||||
private function normalizeRows(array $rows): array
|
||||
{
|
||||
return array_map(fn (array $row): array => $this->normalizeRow($row), $rows);
|
||||
|
||||
@@ -178,6 +178,19 @@ final class SchemaManager
|
||||
$applied[] = 'cost_plan_columns';
|
||||
}
|
||||
}
|
||||
if (
|
||||
($this->tableExists($this->prefix . 'cost_plans') && (
|
||||
!$this->columnExists($this->prefix . 'cost_plans', 'daily_cost_amount') ||
|
||||
!$this->columnExists($this->prefix . 'cost_plans', 'daily_cost_currency')
|
||||
)) ||
|
||||
($this->tableExists($this->prefix . 'purchased_miners') && (
|
||||
!$this->columnExists($this->prefix . 'purchased_miners', 'daily_cost_amount') ||
|
||||
!$this->columnExists($this->prefix . 'purchased_miners', 'daily_cost_currency')
|
||||
))
|
||||
) {
|
||||
$this->upgradeServerDailyCostColumns();
|
||||
$applied[] = 'server_daily_cost_columns';
|
||||
}
|
||||
|
||||
$settingsColumns = $this->existingColumns($this->prefix . 'settings', ['preferred_currencies', 'report_currency', 'crypto_currency', 'display_timezone', 'fx_max_age_hours', 'module_theme_mode', 'module_theme_accent']);
|
||||
if (!in_array('preferred_currencies', $settingsColumns, true) || !in_array('report_currency', $settingsColumns, true) || !in_array('crypto_currency', $settingsColumns, true) || !in_array('display_timezone', $settingsColumns, true) || !in_array('fx_max_age_hours', $settingsColumns, true) || !in_array('module_theme_mode', $settingsColumns, true) || !in_array('module_theme_accent', $settingsColumns, true)) {
|
||||
@@ -665,6 +678,19 @@ final class SchemaManager
|
||||
}
|
||||
}
|
||||
|
||||
foreach ([$this->prefix . 'cost_plans', $this->prefix . 'purchased_miners'] as $serverTable) {
|
||||
if (
|
||||
in_array($serverTable, $presentTables, true) &&
|
||||
(
|
||||
!$this->columnExists($serverTable, 'daily_cost_amount') ||
|
||||
!$this->columnExists($serverTable, 'daily_cost_currency')
|
||||
)
|
||||
) {
|
||||
$upgrades[] = 'server_daily_cost_columns';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->tableExists($this->prefix . 'settings')) {
|
||||
$requiredSettingsColumns = ['preferred_currencies', 'report_currency', 'crypto_currency', 'display_timezone', 'fx_max_age_hours', 'module_theme_mode', 'module_theme_accent'];
|
||||
$existingSettingsColumns = $this->existingColumns($this->prefix . 'settings', $requiredSettingsColumns);
|
||||
@@ -1252,6 +1278,8 @@ final class SchemaManager
|
||||
usd_reference_amount NUMERIC(20,8),
|
||||
reference_price_amount NUMERIC(20,8),
|
||||
reference_price_currency VARCHAR(10),
|
||||
daily_cost_amount NUMERIC(20,10),
|
||||
daily_cost_currency VARCHAR(10),
|
||||
auto_renew BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
note TEXT,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
@@ -1278,6 +1306,8 @@ final class SchemaManager
|
||||
usd_reference_amount DECIMAL(20,8) NULL,
|
||||
reference_price_amount DECIMAL(20,8) NULL,
|
||||
reference_price_currency VARCHAR(10) NULL,
|
||||
daily_cost_amount DECIMAL(20,10) NULL,
|
||||
daily_cost_currency VARCHAR(10) NULL,
|
||||
auto_renew TINYINT(1) NOT NULL DEFAULT 0,
|
||||
note TEXT,
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
@@ -1451,6 +1481,40 @@ final class SchemaManager
|
||||
}
|
||||
}
|
||||
|
||||
private function upgradeServerDailyCostColumns(): void
|
||||
{
|
||||
foreach ([$this->prefix . 'cost_plans', $this->prefix . 'purchased_miners'] as $table) {
|
||||
if (!$this->tableExists($table)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$statements = $this->driver === 'pgsql'
|
||||
? [
|
||||
'ALTER TABLE ' . $table . ' ADD COLUMN IF NOT EXISTS daily_cost_amount NUMERIC(20,10)',
|
||||
'ALTER TABLE ' . $table . ' ADD COLUMN IF NOT EXISTS daily_cost_currency VARCHAR(10)',
|
||||
'UPDATE ' . $table . ' SET daily_cost_amount = ROUND((total_cost_amount / NULLIF(runtime_months * 30.4375, 0))::numeric, 10) WHERE daily_cost_amount IS NULL AND total_cost_amount IS NOT NULL AND runtime_months IS NOT NULL AND runtime_months > 0',
|
||||
'UPDATE ' . $table . ' SET daily_cost_currency = COALESCE(daily_cost_currency, currency) WHERE currency IS NOT NULL',
|
||||
]
|
||||
: [
|
||||
'ALTER TABLE `' . $table . '` ADD COLUMN daily_cost_amount DECIMAL(20,10) NULL',
|
||||
'ALTER TABLE `' . $table . '` ADD COLUMN daily_cost_currency VARCHAR(10) NULL',
|
||||
'UPDATE `' . $table . '` SET daily_cost_amount = ROUND(total_cost_amount / NULLIF(runtime_months * 30.4375, 0), 10) WHERE daily_cost_amount IS NULL AND total_cost_amount IS NOT NULL AND runtime_months IS NOT NULL AND runtime_months > 0',
|
||||
'UPDATE `' . $table . '` SET daily_cost_currency = COALESCE(daily_cost_currency, currency) WHERE currency IS NOT NULL',
|
||||
];
|
||||
|
||||
foreach ($statements as $statement) {
|
||||
try {
|
||||
$this->executeUpgradeStatements([$statement], 'Schema-Upgrade fuer Server-Tageskosten fehlgeschlagen.');
|
||||
} catch (\Throwable $exception) {
|
||||
if ($this->driver === 'mysql' && str_contains(strtolower($exception->getMessage()), 'duplicate column')) {
|
||||
continue;
|
||||
}
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function upgradeTargetOfferColumn(): void
|
||||
{
|
||||
$table = $this->prefix . 'targets';
|
||||
|
||||
Reference in New Issue
Block a user