netgescon-day0/app/Support/StabileContext.php

207 lines
6.0 KiB
PHP

<?php
namespace App\Support;
use App\Models\Stabile;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class StabileContext
{
public const SESSION_KEY = 'netgescon.stabile_attivo_id';
/**
* @return array<int, string>
*/
public static function legacyCodeCandidates(?Stabile $stabile): array
{
if (! $stabile instanceof Stabile) {
return [];
}
$rawCandidates = [
trim((string) ($stabile->codice_stabile ?? '')),
trim((string) ($stabile->old_id ?? '')),
trim((string) ($stabile->cod_stabile ?? '')),
];
$candidates = [];
foreach ($rawCandidates as $candidate) {
if ($candidate === '') {
continue;
}
$candidates[] = $candidate;
$noZero = ltrim($candidate, '0');
if ($noZero !== '' && $noZero !== $candidate) {
$candidates[] = $noZero;
}
}
return array_values(array_unique($candidates));
}
public static function preferredLegacyCode(?Stabile $stabile): ?string
{
$candidates = self::legacyCodeCandidates($stabile);
return $candidates[0] ?? null;
}
public static function setFromStabile(Stabile $stabile, ?User $user = null): bool
{
$user = $user ?? Auth::user();
if ($user instanceof User) {
return self::setActiveStabileId($user, (int) $stabile->id);
}
session([self::SESSION_KEY => (int) $stabile->id]);
return true;
}
public static function resolveActiveStabileId(User $user): ?int
{
$allowed = self::accessibleStabili($user)->pluck('id')->map(fn($v) => (int) $v)->values();
if ($allowed->isEmpty()) {
session()->forget(self::SESSION_KEY);
return null;
}
$sessionId = session(self::SESSION_KEY);
if (is_numeric($sessionId)) {
$sessionId = (int) $sessionId;
if ($allowed->contains($sessionId)) {
return $sessionId;
}
}
// Persistenza: prova a ripristinare l'ultimo stabile usato dall'utente.
$persistedId = self::getPersistedStabileId($user);
if ($persistedId && $allowed->contains($persistedId)) {
session([self::SESSION_KEY => $persistedId]);
return $persistedId;
}
$default = (int) config('netgescon.defaults.default_stabile_id', 0);
if ($default > 0 && $allowed->contains($default)) {
session([self::SESSION_KEY => $default]);
return $default;
}
$first = (int) $allowed->first();
session([self::SESSION_KEY => $first]);
return $first;
}
private static function getPersistedStabileId(User $user): ?int
{
if (! Schema::hasColumn('users', 'last_stabile_id')) {
return null;
}
$candidate = $user->getAttribute('last_stabile_id');
if (! is_numeric($candidate)) {
$candidate = DB::table('users')->where('id', (int) $user->id)->value('last_stabile_id');
}
return is_numeric($candidate) ? (int) $candidate : null;
}
/**
* @return Collection<int, Stabile>
*/
public static function accessibleStabili(User $user): Collection
{
// Super-admin / admin: tutto
if ($user->hasAnyRole(['super-admin', 'admin'])) {
return Stabile::query()->attivi()->orderBy('codice_stabile')->get();
}
// Amministratore: per amministratore_id
if ($user->hasRole('amministratore') && $user->amministratore) {
$owned = Stabile::query()
->attivi()
->byAmministratore($user->amministratore->id)
->get();
// Supporta anche assegnazioni esplicite (stesso pivot dei collaboratori).
$assigned = $user->stabiliAssegnati()->where('stabili.attivo', true)->get();
return $owned
->merge($assigned)
->unique('id')
->sortBy(fn(Stabile $s) => (string) $s->codice_stabile)
->values();
}
// Collaboratore: via pivot
if ($user->hasRole('collaboratore')) {
return $user->stabiliAssegnati()->where('attivo', true)->orderBy('codice_stabile')->get();
}
// Condomino / fornitore: per ora nessun accesso “stabili gestiti”
return collect();
}
public static function getActiveStabileId(?User $user = null): ?int
{
if ($user) {
return self::resolveActiveStabileId($user);
}
$sessionId = session(self::SESSION_KEY);
if (is_numeric($sessionId)) {
return (int) $sessionId;
}
$default = (int) config('netgescon.defaults.default_stabile_id', 0);
if ($default > 0) {
return $default;
}
if ($user) {
return self::accessibleStabili($user)->first()?->id;
}
return null;
}
public static function getActiveStabile(?User $user = null): ?Stabile
{
$id = self::getActiveStabileId($user);
if (! $id) {
return null;
}
if ($user) {
return self::accessibleStabili($user)->firstWhere('id', $id);
}
return Stabile::query()->find($id);
}
public static function setActiveStabileId(User $user, int $stabileId): bool
{
$allowed = self::accessibleStabili($user)->pluck('id')->map(fn($v) => (int) $v)->all();
if (! in_array($stabileId, $allowed, true)) {
return false;
}
session([self::SESSION_KEY => $stabileId]);
if (Schema::hasColumn('users', 'last_stabile_id')) {
try {
DB::table('users')->where('id', (int) $user->id)->update(['last_stabile_id' => $stabileId]);
} catch (\Throwable) {
// best-effort: non bloccare la sessione
}
}
return true;
}
}