> */ public array $rows = []; /** @var array> */ public array $fornitoreOptions = []; public static function canAccess(): bool { $user = Auth::user(); return $user instanceof User && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'fornitore']); } public function mount(): void { [$fornitore] = $this->resolveOperatoreContext(allowAdminWithoutSupplier: true); if (! $fornitore instanceof Fornitore) { $this->missingAdminContext = true; return; } $this->fornitore = $fornitore; $this->refreshFornitoreOptions(); $this->refreshRows(); } public function updatedCollaboratoreTipo(): void { if ($this->collaboratoreTipo !== FornitoreDipendente::TIPO_FORNITORE_ESTERNO) { $this->fornitoreEsternoId = null; $this->fornitoreSearch = ''; $this->createUserAccess = false; } $this->refreshFornitoreOptions(); } public function updatedFornitoreSearch(): void { $this->refreshFornitoreOptions(); } public function createCollaboratore(): void { if (! $this->fornitore instanceof Fornitore) { return; } $validated = $this->validate([ 'collaboratoreTipo' => ['required', 'string', 'in:' . implode(',', [FornitoreDipendente::TIPO_INTERNO, FornitoreDipendente::TIPO_FORNITORE_ESTERNO])], 'nome' => ['nullable', 'string', 'max:100'], 'cognome' => ['nullable', 'string', 'max:100'], 'email' => ['nullable', 'email', 'max:255'], 'telefono' => ['nullable', 'string', 'max:50'], 'note' => ['nullable', 'string', 'max:2000'], 'createUserAccess' => ['nullable', 'boolean'], 'accessPassword' => ['nullable', 'string', 'min:8', 'max:100'], 'fornitoreEsternoId' => ['nullable', 'integer'], ]); $tipo = (string) $validated['collaboratoreTipo']; if ($tipo === FornitoreDipendente::TIPO_INTERNO && trim((string) ($validated['nome'] ?? '')) === '') { Notification::make()->title('Inserisci il nome del collaboratore')->warning()->send(); return; } $fornitoreEsterno = null; if ($tipo === FornitoreDipendente::TIPO_FORNITORE_ESTERNO) { $fornitoreEsterno = $this->resolveFornitoreEsterno((int) ($validated['fornitoreEsternoId'] ?? 0)); if (! $fornitoreEsterno instanceof Fornitore) { Notification::make()->title('Seleziona un altro fornitore come collaboratore')->warning()->send(); return; } if ((int) $fornitoreEsterno->id === (int) $this->fornitore->id) { Notification::make()->title('Il fornitore principale non puo essere aggiunto come subfornitore')->warning()->send(); return; } } $email = $tipo === FornitoreDipendente::TIPO_FORNITORE_ESTERNO ? trim((string) ($fornitoreEsterno?->email ?? '')) : trim((string) ($validated['email'] ?? '')); if ($email !== '') { $existsQuery = FornitoreDipendente::query() ->where('fornitore_id', (int) $this->fornitore->id) ->whereRaw('LOWER(email) = ?', [mb_strtolower($email)]); if ($tipo === FornitoreDipendente::TIPO_FORNITORE_ESTERNO && $fornitoreEsterno instanceof Fornitore) { $existsQuery->orWhere('fornitore_esterno_id', (int) $fornitoreEsterno->id); } $exists = $existsQuery->exists(); if ($exists) { Notification::make()->title('Esiste gia un collaboratore con questa email')->warning()->send(); return; } } $dipendente = new FornitoreDipendente(); $dipendente->fornitore_id = (int) $this->fornitore->id; $dipendente->fornitore_esterno_id = $fornitoreEsterno?->id; $dipendente->rubrica_id = $fornitoreEsterno?->rubrica_id; $dipendente->tipo_collaboratore = $tipo; $dipendente->nome = $tipo === FornitoreDipendente::TIPO_FORNITORE_ESTERNO ? (string) ($fornitoreEsterno?->ragione_sociale ?: $fornitoreEsterno?->nome ?: 'Subfornitore') : trim((string) $validated['nome']); $dipendente->cognome = $tipo === FornitoreDipendente::TIPO_FORNITORE_ESTERNO ? null : (trim((string) ($validated['cognome'] ?? '')) ?: null); $dipendente->email = $email !== '' ? $email : null; $dipendente->telefono = $tipo === FornitoreDipendente::TIPO_FORNITORE_ESTERNO ? (trim((string) ($fornitoreEsterno?->telefono ?: $fornitoreEsterno?->cellulare ?: '')) ?: null) : (trim((string) ($validated['telefono'] ?? '')) ?: null); $dipendente->note = trim((string) ($validated['note'] ?? '')) ?: null; $dipendente->attivo = true; $dipendente->created_by_user_id = Auth::id(); $dipendente->updated_by_user_id = Auth::id(); $createdPassword = null; $plainPassword = trim((string) ($validated['accessPassword'] ?? '')); if ($tipo === FornitoreDipendente::TIPO_FORNITORE_ESTERNO && $fornitoreEsterno instanceof Fornitore) { $linkedUser = User::query()->whereRaw('LOWER(email) = ?', [mb_strtolower((string) ($fornitoreEsterno->email ?? ''))])->first(); if ($linkedUser instanceof User) { $dipendente->user_id = (int) $linkedUser->id; } } if ($tipo === FornitoreDipendente::TIPO_INTERNO && (bool) ($validated['createUserAccess'] ?? false) && $email !== '') { $user = User::query()->whereRaw('LOWER(email) = ?', [mb_strtolower($email)])->first(); if (! $user instanceof User) { $createdPassword = $plainPassword !== '' ? $plainPassword : Str::random(12); $user = User::query()->create([ 'name' => trim($dipendente->nome . ' ' . ($dipendente->cognome ?? '')), 'email' => $email, 'password' => Hash::make($createdPassword), 'email_verified_at' => now(), 'is_active' => true, ]); } elseif ($plainPassword !== '') { $user->password = Hash::make($plainPassword); $user->save(); $createdPassword = $plainPassword; } $user->assignRole('fornitore'); $dipendente->user_id = (int) $user->id; } $dipendente->save(); $this->resetForm(); $this->refreshRows(); $notification = Notification::make()->title('Collaboratore salvato')->success(); if ($createdPassword !== null && $email !== '') { $this->lastGeneratedPassword = $createdPassword; $notification->body('Accesso creato per ' . $email . '. Password temporanea: ' . $createdPassword); } $notification->send(); } public function abilitaAccesso(int $dipendenteId): void { if (! $this->fornitore instanceof Fornitore) { return; } $dipendente = FornitoreDipendente::query() ->where('fornitore_id', (int) $this->fornitore->id) ->find($dipendenteId); if (! $dipendente instanceof FornitoreDipendente) { Notification::make()->title('Collaboratore non trovato')->danger()->send(); return; } if ((string) $dipendente->tipo_collaboratore === FornitoreDipendente::TIPO_FORNITORE_ESTERNO) { Notification::make()->title('Per un altro fornitore si usa il suo accesso gia esistente')->warning()->send(); return; } $email = trim((string) ($dipendente->email ?? '')); if ($email === '') { Notification::make()->title('Email collaboratore mancante')->warning()->send(); return; } $targetUser = User::query()->whereRaw('LOWER(email) = ?', [mb_strtolower($email)])->first(); $created = false; if (! $targetUser instanceof User) { $newPassword = Str::random(12); $targetUser = User::query()->create([ 'name' => trim((string) ($dipendente->nome_completo ?: 'Utente fornitore')), 'email' => $email, 'password' => Hash::make($newPassword), 'email_verified_at' => now(), 'is_active' => true, ]); $this->lastGeneratedPassword = $newPassword; $created = true; } $targetUser->assignRole('fornitore'); $dipendente->user_id = (int) $targetUser->id; $dipendente->attivo = true; $dipendente->updated_by_user_id = Auth::id(); $dipendente->save(); $this->refreshRows(); Notification::make() ->title('Accesso collaboratore abilitato') ->body($created ? 'Nuova password temporanea: ' . ($this->lastGeneratedPassword ?? '(non disponibile)') : 'Accesso collegato ad utente esistente.') ->success() ->send(); } public function resetPasswordDipendenteUser(int $userId): void { if (! $this->fornitore instanceof Fornitore) { return; } $dipendente = FornitoreDipendente::query() ->where('fornitore_id', (int) $this->fornitore->id) ->where('user_id', $userId) ->first(); if (! $dipendente instanceof FornitoreDipendente) { Notification::make()->title('Utente non collegato a questo fornitore')->danger()->send(); return; } $target = User::query()->find($userId); if (! $target instanceof User) { Notification::make()->title('Utente non trovato')->danger()->send(); return; } $newPassword = Str::random(12); $target->password = Hash::make($newPassword); $target->save(); $this->lastGeneratedPassword = $newPassword; Notification::make() ->title('Password collaboratore resettata') ->body('Nuova password temporanea: ' . $newPassword) ->success() ->send(); } public function toggleDipendenteAttivo(int $dipendenteId): void { if (! $this->fornitore instanceof Fornitore) { return; } $dipendente = FornitoreDipendente::query() ->where('fornitore_id', (int) $this->fornitore->id) ->find($dipendenteId); if (! $dipendente instanceof FornitoreDipendente) { Notification::make()->title('Collaboratore non trovato')->danger()->send(); return; } $dipendente->attivo = ! (bool) $dipendente->attivo; $dipendente->updated_by_user_id = Auth::id(); $dipendente->save(); $this->refreshRows(); Notification::make()->title('Stato collaboratore aggiornato')->success()->send(); } public function getTicketsUrl(): string { if ($this->fornitore instanceof Fornitore) { return TicketOperativi::getUrl(['fornitore' => (int) $this->fornitore->id], panel: 'admin-filament'); } return TicketOperativi::getUrl(panel: 'admin-filament'); } public function getContabilitaUrl(): string { if ($this->fornitore instanceof Fornitore) { return Contabilita::getUrl(['fornitore' => (int) $this->fornitore->id], panel: 'admin-filament'); } return Contabilita::getUrl(panel: 'admin-filament'); } protected function refreshRows(): void { if (! $this->fornitore instanceof Fornitore) { $this->rows = []; return; } $this->rows = FornitoreDipendente::query() ->with(['user', 'fornitoreEsterno']) ->where('fornitore_id', (int) $this->fornitore->id) ->orderBy('attivo', 'desc') ->orderBy('tipo_collaboratore') ->orderBy('cognome') ->orderBy('nome') ->get() ->map(fn(FornitoreDipendente $dipendente) => [ 'id' => (int) $dipendente->id, 'nome' => (string) $dipendente->nome_completo, 'email' => (string) ($dipendente->email ?? ''), 'telefono' => (string) ($dipendente->telefono ?? ''), 'note' => (string) ($dipendente->note ?? ''), 'attivo' => (bool) $dipendente->attivo, 'user_id' => $dipendente->user_id ? (int) $dipendente->user_id : null, 'tipo' => (string) $dipendente->tipo_collaboratore, 'tipo_label' => (string) $dipendente->tipo_label, 'fornitore_esterno_nome' => (string) ($dipendente->fornitoreEsterno?->ragione_sociale ?: trim((string) (($dipendente->fornitoreEsterno?->nome ?? '') . ' ' . ($dipendente->fornitoreEsterno?->cognome ?? '')))), ]) ->all(); } protected function refreshFornitoreOptions(): void { if (! $this->fornitore instanceof Fornitore || $this->collaboratoreTipo !== FornitoreDipendente::TIPO_FORNITORE_ESTERNO) { $this->fornitoreOptions = []; return; } $search = trim($this->fornitoreSearch); $this->fornitoreOptions = Fornitore::query() ->whereKeyNot((int) $this->fornitore->id) ->when( $search !== '', function (Builder $query) use ($search): void { $query->where(function (Builder $builder) use ($search): void { $builder->where('ragione_sociale', 'like', '%' . $search . '%') ->orWhere('nome', 'like', '%' . $search . '%') ->orWhere('cognome', 'like', '%' . $search . '%') ->orWhere('email', 'like', '%' . $search . '%') ->orWhere('telefono', 'like', '%' . $search . '%') ->orWhere('cellulare', 'like', '%' . $search . '%') ->orWhere('tags', 'like', '%' . $search . '%'); }); } ) ->orderByRaw('CASE WHEN amministratore_id = ? THEN 0 ELSE 1 END', [(int) ($this->fornitore->amministratore_id ?? 0)]) ->orderByRaw('COALESCE(ragione_sociale, nome, cognome)') ->limit(20) ->get(['id', 'ragione_sociale', 'nome', 'cognome', 'email', 'telefono', 'cellulare', 'tags']) ->map(fn(Fornitore $fornitore) => [ 'id' => (int) $fornitore->id, 'label' => $this->getFornitoreLabel($fornitore), 'meta' => trim(collect([ $fornitore->email, $fornitore->telefono ?: $fornitore->cellulare, $fornitore->tags, ])->filter()->implode(' ยท ')), ]) ->all(); } protected function resolveFornitoreEsterno(int $fornitoreId): ?Fornitore { if ($fornitoreId <= 0) { return null; } return Fornitore::query()->find($fornitoreId); } protected function resetForm(): void { $this->nome = ''; $this->cognome = ''; $this->email = ''; $this->telefono = ''; $this->collaboratoreTipo = FornitoreDipendente::TIPO_INTERNO; $this->fornitoreSearch = ''; $this->fornitoreEsternoId = null; $this->note = ''; $this->createUserAccess = false; $this->accessPassword = ''; $this->refreshFornitoreOptions(); } }