is_system) { $this->dispatch('toast', type: 'error', text: 'System-Domain Limits können hier nicht geändert werden.'); $this->dispatch('closeModal'); return; } $this->domainId = $domainId; $this->max_aliases = (int)$d->max_aliases; $this->max_mailboxes = (int)$d->max_mailboxes; $this->default_quota_mb = (int)$d->default_quota_mb; $this->max_quota_per_mailbox_mb = $d->max_quota_per_mailbox_mb !== null ? (int)$d->max_quota_per_mailbox_mb : null; $this->total_quota_mb = (int)$d->total_quota_mb; $this->rate_limit_per_hour = $d->rate_limit_per_hour !== null ? (int)$d->rate_limit_per_hour : null; $this->rate_limit_override = (bool)$d->rate_limit_override; // Für Pool-Delta-Check merken $this->current_total_quota_mb = (int)$d->total_quota_mb; } protected function rules(): array { return [ 'max_aliases' => ['required', 'integer', 'min:0'], 'max_mailboxes' => ['required', 'integer', 'min:0'], 'default_quota_mb' => ['required', 'integer', 'min:0'], 'max_quota_per_mailbox_mb' => ['nullable', 'integer', 'min:1'], 'total_quota_mb' => ['required', 'integer', 'min:0'], // 0 = unbegrenzt 'rate_limit_per_hour' => ['nullable', 'integer', 'min:1'], // null = kein Limit 'rate_limit_override' => ['boolean'], ]; } public function save(MailStorage $pool): void { $this->validate(); // 1) Innere Konsistenz der neuen Limits if ($this->max_quota_per_mailbox_mb !== null && $this->default_quota_mb > $this->max_quota_per_mailbox_mb) { throw ValidationException::withMessages([ 'default_quota_mb' => 'Die Standard-Quota darf die maximale Mailbox-Quota nicht überschreiten.', ]); } if ($this->total_quota_mb > 0 && $this->default_quota_mb > $this->total_quota_mb) { throw ValidationException::withMessages([ 'default_quota_mb' => 'Die Standard-Quota darf die Domain-Gesamtquota nicht überschreiten.', ]); } // 2) Bestandsdaten laden (für Abwärts-Checks) $d = Domain::query() ->withCount(['mailUsers', 'mailAliases']) ->withSum('mailUsers as sum_user_quota_mb', 'quota_mb') ->withMax('mailUsers as max_user_quota_mb', 'quota_mb') ->withMax('mailUsers as max_user_rate', 'rate_limit_per_hour') ->findOrFail($this->domainId); $existingUsers = (int)$d->mail_users_count; $existingAliases = (int)$d->mail_aliases_count; $sumQuota = (int)($d->sum_user_quota_mb ?? 0); $maxUserQuota = (int)($d->max_user_quota_mb ?? 0); $maxUserRate = (int)($d->max_user_rate ?? 0); // 3) Abwärts-Checks if ($this->max_mailboxes < $existingUsers) { throw ValidationException::withMessages([ 'max_mailboxes' => "Es existieren bereits {$existingUsers} Mailboxen. " . "Der Wert darf nicht unter diese Anzahl gesenkt werden.", ]); } if ($this->max_aliases < $existingAliases) { throw ValidationException::withMessages([ 'max_aliases' => "Es existieren bereits {$existingAliases} Aliasse. " . "Der Wert darf nicht unter diese Anzahl gesenkt werden.", ]); } if ($this->max_quota_per_mailbox_mb !== null && $this->max_quota_per_mailbox_mb < $maxUserQuota) { throw ValidationException::withMessages([ 'max_quota_per_mailbox_mb' => "Mindestens ein Postfach hat {$maxUserQuota} MiB. " . "Das Limit darf nicht darunter liegen.", ]); } if ($this->total_quota_mb > 0 && $this->total_quota_mb < $sumQuota) { throw ValidationException::withMessages([ 'total_quota_mb' => "Bestehende Postfächer summieren sich auf {$sumQuota} MiB. " . "Das Domain-Gesamtlimit darf nicht darunter liegen.", ]); } if (!$this->rate_limit_override && $this->rate_limit_per_hour !== null && $maxUserRate > 0 && $this->rate_limit_per_hour < $maxUserRate) { throw ValidationException::withMessages([ 'rate_limit_per_hour' => "Mindestens ein Postfach hat ein höheres stündliches Limit ({$maxUserRate}). " . "Ohne Overrides darf der Domain-Wert nicht darunter liegen.", ]); } // 4) Pool-Check (nur bei Erhöhung der Domain-Gesamtquota) $delta = $this->total_quota_mb - $this->current_total_quota_mb; if ($delta > 0) { $remaining = (int)$pool->remainingPoolMb(); if ($delta > $remaining) { throw ValidationException::withMessages([ 'total_quota_mb' => 'Nicht genügend Speicher im Pool. Erhöhung um ' . number_format($delta) . ' MiB nicht möglich. Frei: ' . number_format($remaining) . ' MiB.', ]); } } // 5) Persist $d->max_aliases = $this->max_aliases; $d->max_mailboxes = $this->max_mailboxes; $d->default_quota_mb = $this->default_quota_mb; $d->max_quota_per_mailbox_mb = $this->max_quota_per_mailbox_mb; $d->total_quota_mb = $this->total_quota_mb; $d->rate_limit_per_hour = $this->rate_limit_per_hour; $d->rate_limit_override = $this->rate_limit_override; $d->save(); // 6) UI $this->dispatch('domain-updated'); $this->dispatch('closeModal'); $this->dispatch('toast', type: 'done', badge: 'Domain-Limits', title: 'Domain-Limits aktualisiert', text: 'Die Domain-Limits wurden erfolgreich aktualisiert.', duration: 6000, ); } public static function modalMaxWidth(): string { return '3xl'; } public function render() { return view('livewire.ui.domain.modal.domain-limits-modal'); } } // //namespace App\Livewire\Ui\Domain\Modal; // //use App\Models\Domain; //use App\Services\MailStorage; //use Illuminate\Validation\ValidationException; //use LivewireUI\Modal\ModalComponent; // // //class DomainLimitsModal extends ModalComponent //{ // public int $domainId; // public int $max_aliases; // public int $max_mailboxes; // public int $default_quota_mb; // public ?int $max_quota_per_mailbox_mb = null; // public int $total_quota_mb; // public ?int $rate_limit_per_hour = null; // public bool $rate_limit_override = false; // // public function mount(int $domainId, MailStorage $pool) // { // $d = Domain::findOrFail($domainId); // if ($d->is_system) { $this->dispatch('toast', type:'error', text:'System-Domain Limits können hier nicht geändert werden.'); $this->dispatch('closeModal'); return; } // // $this->domainId = $domainId; // $this->max_aliases = (int)$d->max_aliases; // $this->max_mailboxes = (int)$d->max_mailboxes; // $this->default_quota_mb = (int)$d->default_quota_mb; // $this->max_quota_per_mailbox_mb = $d->max_quota_per_mailbox_mb; // $this->total_quota_mb = (int)$d->total_quota_mb; // $this->rate_limit_per_hour = $d->rate_limit_per_hour; // $this->rate_limit_override = (bool)$d->rate_limit_override; // } // // public function save(MailStorage $pool) // { // $this->validate([ // 'max_aliases' => 'required|integer|min:0', // 'max_mailboxes' => 'required|integer|min:0', // 'default_quota_mb' => 'required|integer|min:0', // 'max_quota_per_mailbox_mb' => 'nullable|integer|min:0', // 'total_quota_mb' => 'required|integer|min:0', // 'rate_limit_per_hour' => 'nullable|integer|min:0', // 'rate_limit_override' => 'boolean', // ]); // // if ($this->max_quota_per_mailbox_mb !== null && // $this->default_quota_mb > $this->max_quota_per_mailbox_mb) { // throw ValidationException::withMessages([ // 'default_quota_mb' => 'Die Standard-Quota darf die maximale Mailbox-Quota nicht überschreiten.', // ]); // } // // $remaining = $pool->remainingPoolMb(); // if ($this->total_quota_mb > $remaining) { // throw ValidationException::withMessages([ // 'total_quota_mb' => 'Nicht genügend Speicher verfügbar. Maximal möglich: '.number_format($remaining).' MiB.', // ]); // } // // Domain::whereKey($this->domainId)->update([ // 'max_aliases' => $this->max_aliases, // 'max_mailboxes' => $this->max_mailboxes, // 'default_quota_mb' => $this->default_quota_mb, // 'max_quota_per_mailbox_mb' => $this->max_quota_per_mailbox_mb, // 'total_quota_mb' => $this->total_quota_mb, // 'rate_limit_per_hour' => $this->rate_limit_per_hour, // 'rate_limit_override' => $this->rate_limit_override, // ]); // // $this->dispatch('domain-updated'); // $this->dispatch('closeModal'); // $this->dispatch('toast', // type: 'done', // badge: 'Domain-Limits', // title: 'Domain-Limits aktualisiert', // text: 'Die Domain-Limits wurde erfolgreich aktualisiert. Alle Änderungen sind sofort aktiv.', // duration: 6000, // ); // } // // public function render() // { // return view('livewire.ui.domain.modal.domain-limits-modal'); // } //}