데이터 사용량 월별 보정 기준을 보강함
This commit is contained in:
+61
-7
@@ -28,6 +28,7 @@ const RECEIVE_GAP_LIMIT_SEC = 60;
|
||||
// carrier_total_bytes / meter_adjusted_bytes 로 보정 배율을 역산해 통신사 과금 단위 계측값에 적용한다.
|
||||
const DATA_CURRENT_BILLING_USAGE_BYTES = [
|
||||
'2026-06' => ['total_bytes' => 120064512, 'meter_adjusted_bytes' => 129148416, 'included_bytes' => 104857600, 'coupon_registered_at' => null],
|
||||
'2026-07' => ['total_bytes' => 6549504, 'meter_adjusted_bytes' => 7169536, 'included_bytes' => 104857600, 'coupon_registered_at' => null],
|
||||
];
|
||||
|
||||
function car_db(): PDO
|
||||
@@ -245,13 +246,14 @@ function monthly_data_usage(PDO $pdo): array
|
||||
}
|
||||
$measuredSeconds = max(1, $now->getTimestamp() - $projectionStart);
|
||||
$currentBilling = current_billing_usage($monthStart->format('Y-m'));
|
||||
$billingScale = billing_meter_scale($currentBilling);
|
||||
$billingScaleInfo = billing_meter_scale_info($monthStart->format('Y-m'), $currentBilling);
|
||||
$billingScale = $billingScaleInfo['scale'];
|
||||
$billingCurrentBytes = (int)round($carrierAdjustedTotalBytes * $billingScale);
|
||||
$projectedBytes = (int)round($carrierAdjustedTotalBytes / $measuredSeconds * $monthSeconds);
|
||||
$billingProjectedBytes = $carrierAdjustedTotalBytes > 0
|
||||
? max((int)round($projectedBytes * $billingScale), $billingCurrentBytes)
|
||||
: 0;
|
||||
$calibration = billing_calibration($currentBilling, $billingScale);
|
||||
$calibration = billing_calibration($currentBilling, $billingScaleInfo);
|
||||
if ($billingProjectedBytes <= 0) {
|
||||
$billingProjectedBytes = $calibration['projected_total_bytes'];
|
||||
}
|
||||
@@ -315,6 +317,8 @@ function monthly_data_usage(PDO $pdo): array
|
||||
'projected_service_fee_krw' => floor_krw_10($fixedFeeKrw + $projectedOverFeeKrw),
|
||||
'billing_estimated_current_bytes' => $billingCurrentBytes,
|
||||
'billing_meter_scale' => round($billingScale, 6),
|
||||
'billing_meter_scale_source' => $billingScaleInfo['source'],
|
||||
'billing_meter_scale_source_month' => $billingScaleInfo['source_month'],
|
||||
'billing_remaining_bytes' => max(DATA_MONTHLY_INCLUDED_BYTES - $billingCurrentBytes, 0),
|
||||
'billing_over_bytes' => $billingCurrentOverBytes,
|
||||
'billing_over_fee_raw_krw' => round($billingCurrentOverFeeKrw, 2),
|
||||
@@ -551,17 +555,67 @@ function billing_meter_scale(?array $currentBilling): float
|
||||
return (int)($currentBilling['total_bytes'] ?? 0) / $meterAdjustedBytes;
|
||||
}
|
||||
|
||||
function billing_calibration(?array $currentBilling, float $billingScale): array
|
||||
function billing_meter_scale_info(string $month, ?array $currentBilling): array
|
||||
{
|
||||
$currentScale = billing_meter_scale($currentBilling);
|
||||
if ($currentBilling && $currentScale > 0) {
|
||||
return [
|
||||
'scale' => $currentScale,
|
||||
'source' => 'current_month_anchor',
|
||||
'source_month' => $month,
|
||||
'source_billing' => $currentBilling,
|
||||
];
|
||||
}
|
||||
|
||||
$fallbackMonth = null;
|
||||
$fallbackBilling = null;
|
||||
foreach (DATA_CURRENT_BILLING_USAGE_BYTES as $billingMonth => $row) {
|
||||
if ($billingMonth >= $month || ($row['meter_adjusted_bytes'] ?? 0) <= 0) {
|
||||
continue;
|
||||
}
|
||||
if ($fallbackMonth === null || $billingMonth > $fallbackMonth) {
|
||||
$fallbackMonth = $billingMonth;
|
||||
$fallbackBilling = current_billing_usage($billingMonth);
|
||||
}
|
||||
}
|
||||
|
||||
$fallbackScale = billing_meter_scale($fallbackBilling);
|
||||
if ($fallbackBilling && $fallbackScale > 0) {
|
||||
return [
|
||||
'scale' => $fallbackScale,
|
||||
'source' => 'previous_month_anchor',
|
||||
'source_month' => $fallbackMonth,
|
||||
'source_billing' => $fallbackBilling,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'scale' => 1.0,
|
||||
'source' => 'meter_adjusted_usage',
|
||||
'source_month' => null,
|
||||
'source_billing' => null,
|
||||
];
|
||||
}
|
||||
|
||||
function billing_calibration(?array $currentBilling, array $billingScaleInfo): array
|
||||
{
|
||||
$estimatedCurrentBytes = $currentBilling ? (int)$currentBilling['total_bytes'] : 0;
|
||||
$source = $currentBilling ? 'carrier_scaled_meter_usage' : 'meter_adjusted_usage';
|
||||
$billingScale = (float)($billingScaleInfo['scale'] ?? 1.0);
|
||||
$source = $billingScaleInfo['source'] ?? 'meter_adjusted_usage';
|
||||
$sourceBilling = $billingScaleInfo['source_billing'] ?? null;
|
||||
$note = match ($source) {
|
||||
'current_month_anchor' => 'T world 현재월 사용량으로 0.5KB 올림 TCP 세션 누적값의 보정 배율을 역산합니다. TCP payload 계측값도 별도로 유지합니다.',
|
||||
'previous_month_anchor' => '현재월 T world 기준점이 아직 없어서 가장 최근 월 보정 배율을 임시로 사용합니다. 현재월 기준점이 기록되면 그 배율로 다시 계산합니다.',
|
||||
default => '통신사형 사용량은 과금 대상 TCP 세션을 0.5KB 단위로 올림 처리합니다. 순수 연결 실패와 긴 수신 공백은 제외합니다.',
|
||||
};
|
||||
|
||||
return [
|
||||
'mode' => $source,
|
||||
'note' => $currentBilling
|
||||
? 'Carrier portal current usage is used to reverse-calculate a billing scale for 0.5KB rounded TCP session usage. Payload metered usage remains available separately.'
|
||||
: 'Carrier-like usage rounds each billable TCP session to the 0.5KB billing unit. Pure connect failures and longer receive gaps are excluded.',
|
||||
'note' => $note,
|
||||
'current_billing' => $currentBilling,
|
||||
'scale_source_billing' => $sourceBilling,
|
||||
'billing_meter_scale_source' => $source,
|
||||
'billing_meter_scale_source_month' => $billingScaleInfo['source_month'] ?? null,
|
||||
'billing_meter_scale' => round($billingScale, 6),
|
||||
'projected_total_bytes' => 0,
|
||||
'projected_total_mb' => 0.0,
|
||||
|
||||
Reference in New Issue
Block a user