Files
portal-api/app/Services/ServiceExpiryReconciler.php

64 lines
1.9 KiB
PHP

<?php
namespace App\Services;
use App\Models\ModuleVmware;
use App\Models\Service;
use App\Support\ServiceExpirySync;
use Carbon\Carbon;
class ServiceExpiryReconciler
{
/**
* @return array{synced_vmware: int, backfilled_services: int, orphan_vms: int}
*/
public function run(bool $dryRun = false): array
{
$stats = ['synced_vmware' => 0, 'backfilled_services' => 0, 'orphan_vms' => $this->orphanVmCount()];
Service::query()
->with('vmware')
->whereNotNull('vm_id')
->whereNotIn('status', ['terminated', 'cancelled'])
->chunkById(200, function ($services) use (&$stats, $dryRun) {
foreach ($services as $service) {
$this->reconcile($service, $stats, $dryRun);
}
});
return $stats;
}
private function reconcile(Service $service, array &$stats, bool $dryRun): void
{
$vm = $service->vmware;
if (! $vm) {
return;
}
if ($service->expires_at) {
if ((int) $vm->next_due_date !== $service->expires_at->timestamp) {
$stats['synced_vmware']++;
$dryRun || ServiceExpirySync::toVmware($service);
}
return;
}
if ($vm->next_due_date) {
$stats['backfilled_services']++;
$dryRun || $service->update(['expires_at' => Carbon::createFromTimestamp((int) $vm->next_due_date, config('app.timezone'))]);
}
}
private function orphanVmCount(): int
{
return ModuleVmware::query()
->whereNotIn('id', Service::query()->whereNotNull('vm_id')->select('vm_id'))
->where(fn ($query) => $query
->whereNull('service_id')
->orWhereNotIn('service_id', Service::query()->select('id')))
->count();
}
}