<?php
 namespace App\Modules\Addon\MigrateWhmcs\Importers; use App\Models\ClientProduct; use Illuminate\Support\Facades\DB; class ServiceImporter extends AbstractWhmcsImporter { public function sourceType(): string { return 'service'; } protected function sourceTable(): string { return 'tblhosting'; } protected function importRow(object $row): ?int { $clientId = $this->ledger->map('client', $row->userid); if ($clientId === null) { $this->report->warn( $this->sourceType(), "Servis #{$row->id}: client (userid={$row->userid}) henüz import edilmemiş, atlandı." ); return null; } $map = DB::table('whmcs_product_map') ->where('whmcs_product_id', $row->packageid) ->first(); if ($map === null || $map->procp_product_id === null) { $this->report->warn( $this->sourceType(), "Servis #{$row->id}: WHMCS product (packageid={$row->packageid}) eşlenmemiş, atlandı." ); return null; } $product = ClientProduct::create([ 'client_id' => (int) $clientId, 'product_id' => (int) $map->procp_product_id, 'module' => $map->procp_module ?? null, 'domain' => $this->trimOrNull($row->domain), 'username' => $this->trimOrNull($row->username), 'password' => ($row->password === null || $row->password === '') ? null : $row->password, 'billingcycle' => $this->mapBillingCycle($row->billingcycle), 'recurring_amount' => $row->amount, 'status' => $this->mapStatus($row->domainstatus), 'create_date' => $this->normalizeDate($row->regdate), 'next_due_date' => $this->normalizeDate($row->nextduedate ?? null), 'dedicated_ip' => $this->trimOrNull($row->dedicatedip ?? null), 'notes' => $this->trimOrNull($row->notes ?? null), ]); return $product->id; } private function mapBillingCycle(?string $cycle): ?string { $key = strtolower(trim((string) $cycle)); return match ($key) { 'monthly' => 'monthly', 'quarterly' => 'quarterly', 'semi-annually', 'semiannually', 'semi_annually' => 'semi_annually', 'annually', 'yearly' => 'annually', 'biennially' => 'biennially', 'triennially' => 'triennially', default => null, }; } private function mapStatus(?string $status): string { return match (strtolower(trim((string) $status))) { 'active' => 'active', 'suspended' => 'suspended', 'terminated', 'cancelled', 'canceled', 'fraud', 'closed' => 'terminated', default => 'pending', }; } private function normalizeDate(?string $date): ?string { if ($date === null) { return null; } $date = trim($date); if ($date === '' || str_starts_with($date, '0000-00-00')) { return null; } return $date; } private function trimOrNull(?string $value): ?string { if ($value === null) { return null; } $value = trim($value); return $value === '' ? null : $value; } } 