true, 'log_id' => int] or ['skipped' => 'reason']. */ public function maybeQueue(Activity $activity, bool $sendFlag = true, array $options = []): array { $decision = $activity->decision; if (! $sendFlag || ! $decision || ! $decision->auto_mail || ! $decision->email_template_id) { return ['skipped' => 'disabled']; } /** @var EmailTemplate|null $template */ $template = EmailTemplate::query()->find($decision->email_template_id); if (! $template || ! $template->active) { return ['skipped' => 'no-template']; } // Resolve context $clientCase = $activity->clientCase; /** @var ClientCase|null $clientCase */ $contract = $activity->contract; /** @var Contract|null $contract */ $client = $clientCase?->client; /** @var Client|null $client */ $person = $clientCase?->person; /** @var \App\Models\Person\Person|null $person */ // Validate required entity types from template $required = (array) ($template->entity_types ?? []); if (in_array('client', $required, true) && ! $client) { return ['skipped' => 'missing-client']; } if (in_array('client_case', $required, true) && ! $clientCase) { return ['skipped' => 'missing-client-case']; } if (in_array('contract', $required, true) && ! $contract) { return ['skipped' => 'missing-contract']; } if (in_array('person', $required, true) && ! $person) { return ['skipped' => 'missing-person']; } // Resolve eligible recipients: client's person emails with receive_auto_mails = true $recipients = []; if ($client && $client->person) { $recipients = Email::query() ->where('person_id', $client->person->id) ->where('is_active', true) ->where('receive_auto_mails', true) ->pluck('value') ->map(fn ($v) => strtolower(trim((string) $v))) ->filter(fn ($v) => filter_var($v, FILTER_VALIDATE_EMAIL)) ->unique() ->values() ->all(); } if (empty($recipients)) { return ['skipped' => 'no-recipients']; } // Ensure related names are available without extra queries $activity->loadMissing(['action', 'decision']); // Render content $rendered = $this->renderer->render([ 'subject' => (string) $template->subject_template, 'html' => (string) $template->html_template, 'text' => (string) $template->text_template, ], [ 'client' => $client, 'client_case' => $clientCase, 'contract' => $contract, 'person' => $person, 'activity' => $activity, 'extra' => [], ]); // Create the log and body $log = new EmailLog; $log->fill([ 'uuid' => (string) \Str::uuid(), 'template_id' => $template->id, 'mail_profile_id' => optional(MailProfile::query()->where('active', true)->orderBy('priority')->orderBy('id')->first())->id, 'user_id' => auth()->id(), 'to_email' => (string) ($recipients[0] ?? ''), 'to_recipients' => $recipients, 'subject' => (string) ($rendered['subject'] ?? $template->subject_template ?? ''), 'body_html_hash' => $rendered['html'] ? hash('sha256', $rendered['html']) : null, 'body_text_preview' => isset($rendered['text']) ? mb_strimwidth((string) $rendered['text'], 0, 4096) : null, 'embed_mode' => 'base64', 'status' => EmailLogStatus::Queued, 'queued_at' => now(), 'client_id' => $client?->id, 'client_case_id' => $clientCase?->id, 'contract_id' => $contract?->id, ]); // If multiple recipients, keep to_email null to avoid implying a single primary recipient if (count($recipients) > 1) { $log->to_email = null; } // Resolve and attach selected documents as attachments metadata (id, name, path, mime, size) $attachmentIds = collect($options['attachment_ids'] ?? [])->filter()->map(fn ($v) => (int) $v)->values(); if ($attachmentIds->isNotEmpty()) { $docs = \App\Models\Document::query() ->whereIn('id', $attachmentIds) ->get(['id', 'disk', 'path', 'original_name', 'name', 'mime_type', 'size']); $log->attachments = $docs->map(function ($d) { return [ 'id' => $d->id, 'disk' => $d->disk ?: 'public', 'path' => $d->path, 'name' => $d->original_name ?: ($d->name ?: basename($d->path)), 'mime' => $d->mime_type ?: 'application/octet-stream', 'size' => $d->size, ]; })->values()->all(); } $log->save(); $log->body()->create([ 'body_html' => (string) ($rendered['html'] ?? ''), 'body_text' => (string) ($rendered['text'] ?? ''), 'inline_css' => true, ]); dispatch(new SendEmailTemplateJob($log->id)); return ['queued' => true, 'log_id' => $log->id]; } }