<?php
 namespace App\Services\Consent; use App\Enums\ConsentChannel; use App\Enums\ConsentSource; use App\Jobs\SyncConsentToIysJob; use App\Models\Client; use App\Models\ClientConsent; use App\Models\Log; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class MarketingConsentService { public function grant(Client $client, ConsentChannel $channel, ConsentSource $source, ?Request $request = null): ClientConsent { return $this->record($client, $channel, $source, true, $request); } public function withdraw(Client $client, ConsentChannel $channel, ConsentSource $source, ?Request $request = null): ClientConsent { return $this->record($client, $channel, $source, false, $request); } public function isGranted(Client $client, ConsentChannel $channel): bool { $latest = $client->consents() ->where('channel', $channel->value) ->orderByDesc('created_at') ->orderByDesc('id') ->first(); return (bool) $latest?->granted; } public function history(Client $client, ?ConsentChannel $channel = null): \Illuminate\Database\Eloquent\Collection { $q = $client->consents() ->orderByDesc('created_at') ->orderByDesc('id'); if ($channel) { $q->where('channel', $channel->value); } return $q->get(); } protected function record(Client $client, ConsentChannel $channel, ConsentSource $source, bool $granted, ?Request $request): ClientConsent { return DB::transaction(function () use ($client, $channel, $source, $granted, $request) { $row = ClientConsent::create([ 'client_id' => $client->id, 'channel' => $channel->value, 'granted' => $granted, 'granted_at' => $granted ? now() : null, 'withdrawn_at' => $granted ? null : now(), 'ip_address' => $request?->ip(), 'user_agent' => $request?->userAgent(), 'source' => $source->value, 'locale' => app()->getLocale(), ]); Log::create([ 'observer' => 'MarketingConsentService', 'module' => 'consent', 'method' => $granted ? 'grant' : 'withdraw', 'type' => $granted ? Log::TYPE_CONSENT_GRANTED : Log::TYPE_CONSENT_WITHDRAWN, 'client_id' => $client->id, 'ip_address' => $request?->ip() ?? '0.0.0.0', 'user_agent' => $request?->userAgent(), 'description' => "Consent {$channel->value} ".($granted ? 'granted' : 'withdrawn')." via {$source->value}", ]); if (array_key_exists($channel->value, config('iys.channel_map', []))) { DB::afterCommit(fn () => SyncConsentToIysJob::dispatch($client->id, $channel->value)); } return $row; }); } } 