'array', 'responsabile_ids' => 'array', ]; protected $appends = ['email_primaria', 'telefono_primario']; public function tenant(): BelongsTo { return $this->belongsTo(Tenant::class); } public function parent(): BelongsTo { return $this->belongsTo(Gruppo::class, 'parent_id'); } public function children(): HasMany { return $this->hasMany(Gruppo::class, 'parent_id'); } public function diocesi(): BelongsToMany { return $this->belongsToMany(Diocesi::class, 'diocesi_gruppo'); } public function gruppoContatti(): HasMany { return $this->hasMany(GruppoContatto::class, 'gruppo_id'); } public function individui(): BelongsToMany { return $this->belongsToMany(Individuo::class, 'gruppo_individuo') ->withPivot('ruolo_ids', 'ruolo_nel_gruppo', 'data_adesione') ->withTimestamps(); } public function avatar(): HasOne { return $this->hasOne(Documento::class, 'visibilita_target_id') ->where('tipologia', 'avatar') ->where('visibilita_target_type', self::class); } public function getAvatarUrlAttribute(): ?string { if ($this->avatar && $this->avatar->file_path) { return url('/gruppi/' . $this->id . '/avatar-file'); } return null; } public function getEmailPrimariaAttribute(): ?string { return $this->gruppoContatti()->where('tipo', 'email')->where('is_primary', true)->first()?->valore ?? $this->gruppoContatti()->where('tipo', 'email')->first()?->valore; } public function getTelefonoPrimarioAttribute(): ?string { return $this->gruppoContatti()->whereIn('tipo', ['telefono', 'cellulare'])->where('is_primary', true)->first()?->valore ?? $this->gruppoContatti()->whereIn('tipo', ['telefono', 'cellulare'])->first()?->valore; } public function getResponsabili() { if (empty($this->responsabile_ids)) { return collect(); } $ids = is_array($this->responsabile_ids) ? $this->responsabile_ids : json_decode($this->responsabile_ids, true); if (empty($ids)) { return collect(); } return Individuo::whereIn('id', $ids)->get(); } public function getResponsabiliIds(): array { if (empty($this->responsabile_ids)) { return []; } return is_array($this->responsabile_ids) ? $this->responsabile_ids : json_decode($this->responsabile_ids, true) ?? []; } public function eventi(): BelongsToMany { return $this->belongsToMany(Evento::class, 'eventi_gruppi')->withTimestamps(); } public function documenti(): HasMany { return $this->hasMany(Documento::class, 'visibilita_target_id') ->where('visibilita_target_type', self::class); } public function getAncestors(): array { $ancestors = []; $current = $this->parent; while ($current) { $ancestors[] = $current; $current = $current->parent; } return $ancestors; } public function getDescendants(): array { $descendants = []; foreach ($this->children as $child) { $descendants[] = $child; $descendants = array_merge($descendants, $child->getDescendants()); } return $descendants; } public function getFullPathAttribute(): string { $path = [$this->nome]; foreach (array_reverse($this->getAncestors()) as $ancestor) { $path[] = $ancestor->nome; } return implode(' > ', array_reverse($path)); } }