Files
services_core/app/Services/Nas/CustomerAccountReconciliationService.php
T
2026-08-07 09:16:13 +07:00

41 lines
2.8 KiB
PHP

<?php
namespace App\Services\Nas;
use App\Models\CustomerNasAccount;
use App\Models\NasPackageProfile;
class CustomerAccountReconciliationService
{
public function __construct(protected RouterOsApiService $routerOs) {}
public function reconcile(CustomerNasAccount $account): void
{
$account->load(['mikrotik','packageProfile']);
if ($account->mikrotik->connection_type !== 'api') return;
$state = $this->routerOs->inspectAccount($account->mikrotik,$account->service_type,$account->username);
$active = $state['active'];
$uptime = max(
$this->durationSeconds($active['uptime'] ?? ''),
$this->durationSeconds($state['account']['uptime'] ?? '')
);
$bytes = max(
(int) ($active['bytes-in'] ?? 0) + (int) ($active['bytes-out'] ?? 0),
(int) ($state['account']['bytes-in'] ?? 0) + (int) ($state['account']['bytes-out'] ?? 0)
);
$updates=['remote_state'=>$state,'used_uptime_seconds'=>$uptime,'used_bytes'=>$bytes,'last_reconciled_at'=>now(),'last_sync_error'=>null];
if ($active && ! $account->first_login_at) {
$updates['first_login_at']=now();
if ($account->packageProfile->validity_start === 'first_login') { $updates['validity_started_at']=now(); $updates['expires_at']=$this->expiry($account->packageProfile); }
}
$expires=$updates['expires_at'] ?? $account->expires_at;
$expiresWithGrace = $expires?->copy()->addMinutes((int) $account->packageProfile->grace_period_minutes);
$limitReached=($expiresWithGrace && now()->gte($expiresWithGrace)) || ($account->packageProfile->uptime_limit_seconds && $uptime >= $account->packageProfile->uptime_limit_seconds) || ($account->packageProfile->data_limit_bytes && $bytes >= $account->packageProfile->data_limit_bytes);
if ($limitReached && $account->status === 'active') {
$this->routerOs->setEnabled($account->mikrotik,$account->service_type,$account->username,false);
$this->routerOs->disconnectAccount($account->mikrotik,$account->service_type,$account->username);
$updates['status']='expired';
}
$account->update($updates);
}
private function durationSeconds(string $value): int { preg_match_all('/(\d+)(w|d|h|m|s)/',$value,$m,PREG_SET_ORDER); $map=['w'=>604800,'d'=>86400,'h'=>3600,'m'=>60,'s'=>1]; return array_sum(array_map(fn($x)=>(int)$x[1]*$map[$x[2]],$m)); }
private function expiry(NasPackageProfile $p) { if(!$p->validity_value||!$p->validity_unit)return null; return match($p->validity_unit){'minutes'=>now()->addMinutes($p->validity_value),'hours'=>now()->addHours($p->validity_value),'days'=>now()->addDays($p->validity_value),'months'=>now()->addMonths($p->validity_value),default=>null}; }
}