adsd
This commit is contained in:
@@ -24,6 +24,10 @@ final class Router
|
||||
private const LONG_REQUEST_BUDGET_SECONDS = 8.0;
|
||||
private const OVERVIEW_WINDOW_DAYS = 15;
|
||||
private const FX_FETCH_MAX_AGE_HOURS = 3.0;
|
||||
private const BASE_OFFER_SPEEDS = [
|
||||
'fiat' => ['value' => 50.0, 'unit' => 'kH/s'],
|
||||
'crypto' => ['value' => 75.0, 'unit' => 'kH/s'],
|
||||
];
|
||||
|
||||
private string $moduleBasePath;
|
||||
private ModuleConfig $config;
|
||||
@@ -1679,14 +1683,18 @@ final class Router
|
||||
private function saveCostPlan(string $projectKey, array $input): array
|
||||
{
|
||||
$projectTimezone = $this->projectTimezone($projectKey);
|
||||
$miningSpeedValue = $this->optionalDecimal($input['mining_speed_value'] ?? null);
|
||||
$miningSpeedUnit = $this->optionalSpeedUnit($input['mining_speed_unit'] ?? null);
|
||||
$bonusPercent = $this->optionalDecimal($input['bonus_percent'] ?? null);
|
||||
$payload = [
|
||||
'label' => $this->requiredString($input['label'] ?? null, 'label', 120),
|
||||
'purchased_at' => $this->requiredDateTime($input['starts_at'] ?? null, 'starts_at', $projectTimezone),
|
||||
'runtime_months' => $this->requiredPositiveInt($input['runtime_months'] ?? null, 'runtime_months'),
|
||||
'mining_speed_value' => $this->optionalDecimal($input['mining_speed_value'] ?? null),
|
||||
'mining_speed_unit' => $this->optionalSpeedUnit($input['mining_speed_unit'] ?? null),
|
||||
'bonus_speed_value' => $this->optionalDecimal($input['bonus_speed_value'] ?? null),
|
||||
'bonus_speed_unit' => $this->optionalSpeedUnit($input['bonus_speed_unit'] ?? null),
|
||||
'mining_speed_value' => $miningSpeedValue,
|
||||
'mining_speed_unit' => $miningSpeedUnit,
|
||||
'bonus_speed_value' => $this->bonusSpeedFromPercent($miningSpeedValue, $miningSpeedUnit, $bonusPercent),
|
||||
'bonus_speed_unit' => $bonusPercent !== null ? $miningSpeedUnit : null,
|
||||
'bonus_percent' => $bonusPercent,
|
||||
'auto_renew' => !empty($input['auto_renew']) ? 1 : 0,
|
||||
'base_price_amount' => $this->requiredDecimal($input['base_price_amount'] ?? ($input['total_cost_amount'] ?? null), 'base_price_amount'),
|
||||
'payment_type' => $this->enumValue($input['payment_type'] ?? 'fiat', ['fiat', 'crypto'], 'payment_type'),
|
||||
@@ -1698,8 +1706,11 @@ final class Router
|
||||
throw new ApiException('Mining-Geschwindigkeit und Einheit muessen gemeinsam gesetzt oder beide leer sein.', 422);
|
||||
}
|
||||
|
||||
if (($payload['bonus_speed_value'] === null) xor ($payload['bonus_speed_unit'] === null)) {
|
||||
throw new ApiException('Bonus-Geschwindigkeit und Einheit muessen gemeinsam gesetzt oder beide leer sein.', 422);
|
||||
if ($bonusPercent !== null && ($miningSpeedValue === null || $miningSpeedUnit === null)) {
|
||||
throw new ApiException('Bonus-Prozent setzt eine Mining-Geschwindigkeit voraus.', 422);
|
||||
}
|
||||
if ($bonusPercent !== null && $bonusPercent < 0) {
|
||||
throw new ApiException('Bonus-Prozent darf nicht negativ sein.', 422);
|
||||
}
|
||||
|
||||
$settings = $this->settings($projectKey);
|
||||
@@ -1787,22 +1798,31 @@ final class Router
|
||||
|
||||
private function saveMinerOffer(string $projectKey, array $input): array
|
||||
{
|
||||
$paymentType = $this->enumValue($input['payment_type'] ?? 'fiat', ['fiat', 'crypto'], 'payment_type');
|
||||
$baseSpeed = self::BASE_OFFER_SPEEDS[$paymentType] ?? self::BASE_OFFER_SPEEDS['fiat'];
|
||||
$bonusPercent = $this->optionalDecimal($input['bonus_percent'] ?? null);
|
||||
$basePriceCurrency = $this->requiredCurrency($input['base_price_currency'] ?? ($input['reference_price_currency'] ?? $input['price_currency'] ?? null), 'base_price_currency');
|
||||
$payload = [
|
||||
'label' => $this->requiredString($input['label'] ?? null, 'label', 120),
|
||||
'runtime_months' => $this->optionalPositiveInt($input['runtime_months'] ?? null),
|
||||
'mining_speed_value' => $this->optionalDecimal($input['mining_speed_value'] ?? null),
|
||||
'mining_speed_unit' => $this->optionalSpeedUnit($input['mining_speed_unit'] ?? null),
|
||||
'bonus_speed_value' => $this->optionalDecimal($input['bonus_speed_value'] ?? null),
|
||||
'bonus_speed_unit' => $this->optionalSpeedUnit($input['bonus_speed_unit'] ?? null),
|
||||
'mining_speed_value' => $baseSpeed['value'],
|
||||
'mining_speed_unit' => $baseSpeed['unit'],
|
||||
'bonus_speed_value' => $this->bonusSpeedFromPercent((float) $baseSpeed['value'], (string) $baseSpeed['unit'], $bonusPercent),
|
||||
'bonus_speed_unit' => $bonusPercent !== null ? (string) $baseSpeed['unit'] : null,
|
||||
'bonus_percent' => $bonusPercent,
|
||||
'base_price_amount' => $this->requiredDecimal($input['base_price_amount'] ?? ($input['reference_price_amount'] ?? $input['price_amount'] ?? null), 'base_price_amount'),
|
||||
'base_price_currency' => $this->requiredCurrency($input['base_price_currency'] ?? ($input['reference_price_currency'] ?? $input['price_currency'] ?? null), 'base_price_currency'),
|
||||
'payment_type' => $this->enumValue($input['payment_type'] ?? 'fiat', ['fiat', 'crypto'], 'payment_type'),
|
||||
'base_price_currency' => $basePriceCurrency,
|
||||
'payment_type' => $paymentType,
|
||||
'auto_renew' => !empty($input['auto_renew']) ? 1 : 0,
|
||||
'note' => $this->optionalString($input['note'] ?? null, 1000),
|
||||
'is_active' => !empty($input['is_active']) ? 1 : 0,
|
||||
];
|
||||
|
||||
$this->assertCurrencyType($payload['base_price_currency'], false, 'base_price_currency');
|
||||
if ($bonusPercent !== null && $bonusPercent < 0) {
|
||||
throw new ApiException('Bonus-Prozent darf nicht negativ sein.', 422);
|
||||
}
|
||||
|
||||
$this->assertCurrencyType($payload['base_price_currency'], $paymentType === 'crypto', 'base_price_currency');
|
||||
|
||||
return $this->repository()->saveMinerOffer($projectKey, $payload);
|
||||
}
|
||||
@@ -1817,14 +1837,31 @@ final class Router
|
||||
$settings = $this->settings($projectKey);
|
||||
$cryptoCurrency = $this->requiredCurrency($settings['crypto_currency'] ?? 'DOGE', 'crypto_currency');
|
||||
$isAutoRenew = array_key_exists('auto_renew', $input) ? !empty($input['auto_renew']) : !empty($offer['auto_renew']);
|
||||
$selectedSpeedValue = $this->optionalDecimal($input['mining_speed_value'] ?? null);
|
||||
$selectedSpeedUnit = $this->optionalSpeedUnit($input['mining_speed_unit'] ?? null);
|
||||
if (($selectedSpeedValue === null) xor ($selectedSpeedUnit === null)) {
|
||||
throw new ApiException('Mining-Geschwindigkeit und Einheit muessen gemeinsam gesetzt oder beide leer sein.', 422);
|
||||
}
|
||||
|
||||
$resolvedSpeedValue = $selectedSpeedValue ?? $this->optionalDecimal($offer['mining_speed_value'] ?? null);
|
||||
$resolvedSpeedUnit = $selectedSpeedUnit ?? $this->optionalSpeedUnit($offer['mining_speed_unit'] ?? null);
|
||||
$resolvedBonusPercent = $this->offerBonusPercent($offer);
|
||||
$resolvedBonusValue = $this->bonusSpeedFromPercent($resolvedSpeedValue, $resolvedSpeedUnit, $resolvedBonusPercent);
|
||||
$resolvedBonusUnit = $resolvedBonusValue !== null ? $resolvedSpeedUnit : null;
|
||||
|
||||
$purchaseCurrency = $this->optionalCurrency($input['currency'] ?? null) ?? (string) ($offer['effective_price_currency'] ?? $offer['price_currency'] ?? $offer['base_price_currency'] ?? '');
|
||||
if (!$isAutoRenew) {
|
||||
$purchaseCurrency = $cryptoCurrency;
|
||||
}
|
||||
$purchaseCost = $this->optionalDecimal($input['total_cost_amount'] ?? null);
|
||||
if ($purchaseCost === null || !$isAutoRenew) {
|
||||
if ($purchaseCost === null) {
|
||||
$purchaseCost = $this->resolveOfferPurchaseCost(array_merge($offer, [
|
||||
'mining_speed_value' => $resolvedSpeedValue,
|
||||
'mining_speed_unit' => $resolvedSpeedUnit,
|
||||
'bonus_speed_value' => $resolvedBonusValue,
|
||||
'bonus_speed_unit' => $resolvedBonusUnit,
|
||||
'base_price_amount' => $this->optionalDecimal($input['reference_price_amount'] ?? null) ?? ($offer['base_price_amount'] ?? null),
|
||||
'base_price_currency' => $this->optionalCurrency($input['reference_price_currency'] ?? null) ?? ($offer['base_price_currency'] ?? null),
|
||||
'price_currency' => $purchaseCurrency !== '' ? $purchaseCurrency : ($offer['price_currency'] ?? ''),
|
||||
]));
|
||||
}
|
||||
@@ -1836,12 +1873,12 @@ final class Router
|
||||
|
||||
return $this->repository()->purchaseMiner($projectKey, $offerId, [
|
||||
'purchased_at' => $purchasedAt,
|
||||
'label' => $offer['label'],
|
||||
'label' => $this->optionalString($input['label'] ?? ($offer['label'] ?? null), 120) ?? $offer['label'],
|
||||
'runtime_months' => $offer['runtime_months'] ?? null,
|
||||
'mining_speed_value' => $offer['mining_speed_value'] ?? null,
|
||||
'mining_speed_unit' => $offer['mining_speed_unit'] ?? null,
|
||||
'bonus_speed_value' => $offer['bonus_speed_value'] ?? null,
|
||||
'bonus_speed_unit' => $offer['bonus_speed_unit'] ?? null,
|
||||
'mining_speed_value' => $resolvedSpeedValue,
|
||||
'mining_speed_unit' => $resolvedSpeedUnit,
|
||||
'bonus_speed_value' => $resolvedBonusValue,
|
||||
'bonus_speed_unit' => $resolvedBonusUnit,
|
||||
'total_cost_amount' => $purchaseCost,
|
||||
'currency' => $purchaseCurrency !== '' ? $purchaseCurrency : $offer['price_currency'],
|
||||
'usd_reference_amount' => $offer['usd_reference_amount'] ?? null,
|
||||
@@ -2440,6 +2477,39 @@ final class Router
|
||||
return (float) ($baseAmount ?? $offer['price_amount'] ?? 0);
|
||||
}
|
||||
|
||||
private function bonusSpeedFromPercent(?float $speedValue, ?string $speedUnit, ?float $bonusPercent): ?float
|
||||
{
|
||||
if ($speedValue === null || $speedUnit === null || $bonusPercent === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return round($speedValue * ($bonusPercent / 100), 4);
|
||||
}
|
||||
|
||||
private function offerBonusPercent(array $offer): ?float
|
||||
{
|
||||
$speedValue = $this->optionalDecimal($offer['mining_speed_value'] ?? null);
|
||||
$speedUnit = $this->optionalSpeedUnit($offer['mining_speed_unit'] ?? null);
|
||||
$bonusValue = $this->optionalDecimal($offer['bonus_speed_value'] ?? null);
|
||||
$bonusUnit = $this->optionalSpeedUnit($offer['bonus_speed_unit'] ?? null);
|
||||
if ($speedValue === null || $speedUnit === null || $bonusValue === null || $bonusUnit === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$speedMh = $this->hashrateToMh($speedValue, $speedUnit);
|
||||
$bonusMh = $this->hashrateToMh($bonusValue, $bonusUnit);
|
||||
if ($speedMh <= 0 || $bonusMh <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ($bonusMh / $speedMh) * 100;
|
||||
}
|
||||
|
||||
private function hashrateToMh(float $value, string $unit): float
|
||||
{
|
||||
return $unit === 'kH/s' ? $value / 1000 : $value;
|
||||
}
|
||||
|
||||
private function pdo(): PDO
|
||||
{
|
||||
if ($this->pdo === null) {
|
||||
|
||||
Reference in New Issue
Block a user