adasd
This commit is contained in:
@@ -700,7 +700,7 @@ final class AnalyticsService
|
||||
continue;
|
||||
}
|
||||
|
||||
$convertedDailyCost = $this->entryDailyCostInCurrency($entry, $runtimeMonths, $currency, $fxContext);
|
||||
$convertedDailyCost = $this->entryDailyCostInCurrency($entry, $runtimeMonths, $currency, $fxContext, $startField);
|
||||
if ($convertedDailyCost === null) {
|
||||
continue;
|
||||
}
|
||||
@@ -712,9 +712,9 @@ final class AnalyticsService
|
||||
return $matched ? $dailyTotal : null;
|
||||
}
|
||||
|
||||
private function entryDailyCostInCurrency(array $entry, int $runtimeMonths, string $targetCurrency, ?array $fxContext = null): ?float
|
||||
private function entryDailyCostInCurrency(array $entry, int $runtimeMonths, string $targetCurrency, ?array $fxContext = null, string $startField = 'starts_at'): ?float
|
||||
{
|
||||
$runtimeDays = $runtimeMonths * 30.4375;
|
||||
$runtimeDays = $this->entryRuntimeDays($entry, $startField);
|
||||
if ($runtimeDays <= 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -762,20 +762,16 @@ final class AnalyticsService
|
||||
return null;
|
||||
}
|
||||
|
||||
$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 === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dailyAmount = $storedDailyCost;
|
||||
if ($dailyAmount === null || $dailyAmount <= 0) {
|
||||
$amount = is_numeric($entry['total_cost_amount'] ?? null) ? (float) $entry['total_cost_amount'] : null;
|
||||
if ($amount === null || $amount <= 0) {
|
||||
return null;
|
||||
}
|
||||
$dailyAmount = $amount / $runtimeDays;
|
||||
$amount = is_numeric($entry['total_cost_amount'] ?? null) ? (float) $entry['total_cost_amount'] : null;
|
||||
if ($amount === null || $amount <= 0) {
|
||||
return null;
|
||||
}
|
||||
$dailyAmount = $amount / $runtimeDays;
|
||||
|
||||
return $this->convertAmount($dailyAmount, $entryCurrency, $targetCurrency, $fxContext);
|
||||
}
|
||||
@@ -1094,8 +1090,10 @@ final class AnalyticsService
|
||||
return false;
|
||||
}
|
||||
|
||||
$runtimeDays = $runtimeMonths * 30.4375;
|
||||
$endTs = (int) round($startTs + ($runtimeDays * 86400));
|
||||
$endTs = $this->entryCoverageEndTimestamp($entry, $startField);
|
||||
if ($endTs === null) {
|
||||
return true;
|
||||
}
|
||||
return $this->entryAutoRenewEnabled($entry) || $checkTs <= $endTs;
|
||||
}
|
||||
|
||||
@@ -1586,7 +1584,10 @@ final class AnalyticsService
|
||||
|
||||
$runtimeMonths = (int) ($plan['runtime_months'] ?? 0);
|
||||
if ($runtimeMonths > 0 && is_numeric($plan['total_cost_amount'] ?? null)) {
|
||||
$runtimeDays = $runtimeMonths * 30.4375;
|
||||
$runtimeDays = $this->entryRuntimeDays($plan);
|
||||
if ($runtimeDays <= 0) {
|
||||
continue;
|
||||
}
|
||||
$dailyCost = $this->convertAmount((float) $plan['total_cost_amount'] / $runtimeDays, (string) ($plan['currency'] ?? ''), $currency, $latest);
|
||||
if ($dailyCost !== null) {
|
||||
$cost += $dailyCost * $coveredDays;
|
||||
@@ -1610,7 +1611,10 @@ final class AnalyticsService
|
||||
|
||||
$runtimeMonths = (int) ($miner['runtime_months'] ?? 0);
|
||||
if ($runtimeMonths > 0 && is_numeric($miner['total_cost_amount'] ?? null)) {
|
||||
$runtimeDays = $runtimeMonths * 30.4375;
|
||||
$runtimeDays = $this->entryRuntimeDays($miner, 'purchased_at');
|
||||
if ($runtimeDays <= 0) {
|
||||
continue;
|
||||
}
|
||||
$dailyCost = $this->convertAmount((float) $miner['total_cost_amount'] / $runtimeDays, (string) ($miner['currency'] ?? ''), $currency, $latest);
|
||||
if ($dailyCost !== null) {
|
||||
$cost += $dailyCost * $coveredDays;
|
||||
@@ -1649,8 +1653,10 @@ final class AnalyticsService
|
||||
return $days - $startIndex;
|
||||
}
|
||||
|
||||
$runtimeDays = $runtimeMonths * 30.4375;
|
||||
$endTs = (int) round($startTs + ($runtimeDays * 86400));
|
||||
$endTs = $this->entryCoverageEndTimestamp($entry, $startField);
|
||||
if ($endTs === null) {
|
||||
return $days - $startIndex;
|
||||
}
|
||||
$endIndex = (int) floor(($endTs - $baseTs) / 86400);
|
||||
$endIndex = min($days - 1, $endIndex);
|
||||
if ($endIndex < $startIndex) {
|
||||
@@ -2178,8 +2184,31 @@ final class AnalyticsService
|
||||
return null;
|
||||
}
|
||||
|
||||
$runtimeDays = $runtimeMonths * 30.4375;
|
||||
return (int) round($startTs + ($runtimeDays * 86400));
|
||||
return $this->calendarMonthEndTimestamp($startTs, $runtimeMonths);
|
||||
}
|
||||
|
||||
private function entryRuntimeDays(array $entry, string $startField = 'starts_at'): float
|
||||
{
|
||||
$startTs = $this->utcTimestamp((string) ($entry[$startField] ?? ''));
|
||||
$runtimeMonths = (int) ($entry['runtime_months'] ?? 0);
|
||||
if ($startTs <= 0 || $runtimeMonths <= 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$endTs = $this->calendarMonthEndTimestamp($startTs, $runtimeMonths);
|
||||
return $endTs > $startTs ? ($endTs - $startTs) / 86400 : 0.0;
|
||||
}
|
||||
|
||||
private function calendarMonthEndTimestamp(int $startTs, int $runtimeMonths): int
|
||||
{
|
||||
$utc = new \DateTimeZone('UTC');
|
||||
$start = (new \DateTimeImmutable('@' . $startTs))->setTimezone($utc);
|
||||
$monthIndex = (((int) $start->format('Y')) * 12) + ((int) $start->format('n')) - 1 + $runtimeMonths;
|
||||
$year = intdiv($monthIndex, 12);
|
||||
$month = ($monthIndex % 12) + 1;
|
||||
$day = min((int) $start->format('j'), cal_days_in_month(CAL_GREGORIAN, $month, $year));
|
||||
|
||||
return $start->setDate($year, $month, $day)->getTimestamp();
|
||||
}
|
||||
|
||||
private function utcTimestamp(?string $value): int
|
||||
|
||||
@@ -1060,7 +1060,7 @@ final class MiningRepository
|
||||
'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_amount' => $payload['daily_cost_amount'] ?? $this->deriveDailyCostAmount($payload['total_cost_amount'] ?? null, $payload['runtime_months'] ?? null, $payload['purchased_at'] ?? null),
|
||||
'daily_cost_currency' => $payload['daily_cost_currency'] ?? ($payload['currency'] ?? null),
|
||||
'auto_renew' => $payload['auto_renew'] ?? 0,
|
||||
'note' => $payload['note'] ?? null,
|
||||
@@ -1615,7 +1615,7 @@ 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);
|
||||
$dailyCostAmount = $payload['daily_cost_amount'] ?? $this->deriveDailyCostAmount($payload['total_cost_amount'] ?? null, $payload['runtime_months'] ?? null, $payload['starts_at'] ?? null);
|
||||
$dailyCostCurrency = $payload['daily_cost_currency'] ?? ($payload['currency'] ?? null);
|
||||
|
||||
return [
|
||||
@@ -1661,7 +1661,7 @@ 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);
|
||||
$dailyCostAmount = $payload['daily_cost_amount'] ?? $this->deriveDailyCostAmount($payload['total_cost_amount'] ?? null, $payload['runtime_months'] ?? null, $payload['purchased_at'] ?? null);
|
||||
$dailyCostCurrency = $payload['daily_cost_currency'] ?? ($payload['currency'] ?? null);
|
||||
|
||||
return [
|
||||
@@ -1691,18 +1691,29 @@ final class MiningRepository
|
||||
];
|
||||
}
|
||||
|
||||
private function deriveDailyCostAmount(mixed $totalCostAmount, mixed $runtimeMonths): ?float
|
||||
private function deriveDailyCostAmount(mixed $totalCostAmount, mixed $runtimeMonths, mixed $startsAt): ?float
|
||||
{
|
||||
if (!is_numeric($totalCostAmount) || !is_numeric($runtimeMonths)) {
|
||||
if (!is_numeric($totalCostAmount) || !is_numeric($runtimeMonths) || !is_string($startsAt) || trim($startsAt) === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$months = (float) $runtimeMonths;
|
||||
$months = (int) $runtimeMonths;
|
||||
if ($months <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$runtimeDays = $months * 30.4375;
|
||||
try {
|
||||
$utc = new \DateTimeZone('UTC');
|
||||
$start = new \DateTimeImmutable($startsAt, $utc);
|
||||
$monthIndex = (((int) $start->format('Y')) * 12) + ((int) $start->format('n')) - 1 + $months;
|
||||
$year = intdiv($monthIndex, 12);
|
||||
$month = ($monthIndex % 12) + 1;
|
||||
$day = min((int) $start->format('j'), cal_days_in_month(CAL_GREGORIAN, $month, $year));
|
||||
$end = $start->setDate($year, $month, $day);
|
||||
$runtimeDays = ($end->getTimestamp() - $start->getTimestamp()) / 86400;
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
if ($runtimeDays <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1590,13 +1590,11 @@ final class SchemaManager
|
||||
? [
|
||||
'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',
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user