feat(portal): lead module, WHMCS sync report/contacts/mapping, service lifecycle email templates

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
baodev0
2026-10-21 16:55:19 +07:00
co-authored by Claude Sonnet 5.5
parent 3c7710f1de
commit a443ec3bf6
66 changed files with 2032 additions and 124 deletions
@@ -39,10 +39,29 @@ class ServiceClientService
'vps' => (int) $counts->get('vps', 0),
'server' => (int) $counts->get('server', 0),
'hosting' => (int) $counts->get('hosting', 0),
'domain' => (int) $counts->get('domain', 0),
'domain' => (int) $counts->get('domain', 0) + $this->countZonesWithoutService($customerId),
];
}
private function countZonesWithoutService(int $customerId): int
{
$serviceDomains = Service::query()
->where('customer_id', $customerId)
->where('type', 'domain')
->whereNotIn('status', ['cancelled', 'terminated'])
->pluck('server_name')
->map(fn ($name) => mb_strtolower(trim((string) $name)));
return DnsDomain::query()
->whereHas('customer', fn ($query) => $query->where('customers.id', $customerId))
->where('is_created', '!=', DnsDomain::STATUS_CANCELLED)
->pluck('domain_name')
->map(fn ($name) => mb_strtolower(trim((string) $name)))
->unique()
->diff($serviceDomains)
->count();
}
/**
* @param iterable<Service> $services
*/