netgescon-day0/app/Services/Cti/PbxRoutingService.php

234 lines
9.1 KiB
PHP

<?php
namespace App\Services\Cti;
use App\Models\Amministratore;
use App\Models\User;
use App\Support\StabileContext;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Schema;
class PbxRoutingService
{
public function normalizeExtension(?string $extension): string
{
$digits = preg_replace('/\D+/', '', (string) $extension);
return is_string($digits) ? $digits : '';
}
/**
* @return array{extension:string,user_id:int|null,stabile_id:int|null,user:?User,amministratore_id:int|null,studio_role:?string,studio_mode:?string}
*/
public function resolveByExtension(?string $extension): array
{
$normalized = $this->normalizeExtension($extension);
if ($normalized === '' || ! Schema::hasColumn('users', 'pbx_extension')) {
return [
'extension' => $normalized,
'user_id' => null,
'stabile_id' => null,
'user' => null,
'amministratore_id' => null,
'studio_role' => null,
'studio_mode' => null,
];
}
$studioContext = $this->findStudioContextByExtension($normalized);
$user = User::query()->where('pbx_extension', $normalized)->first();
if (! $user) {
return [
'extension' => $normalized,
'user_id' => null,
'stabile_id' => null,
'user' => null,
'amministratore_id' => $studioContext['amministratore_id'],
'studio_role' => $studioContext['studio_role'],
'studio_mode' => $studioContext['studio_mode'],
];
}
$stabileId = null;
if (method_exists($user, 'stabiliAssegnati')) {
$stabileId = $user->stabiliAssegnati()->value('stabili.id');
}
return [
'extension' => $normalized,
'user_id' => (int) $user->id,
'stabile_id' => $stabileId ? (int) $stabileId : null,
'user' => $user,
'amministratore_id' => $studioContext['amministratore_id'] ?? $this->resolveAmministratoreIdForUser($user),
'studio_role' => $studioContext['studio_role'],
'studio_mode' => $studioContext['studio_mode'],
];
}
/**
* @return array<int,string>
*/
public function getWatchedExtensionsForUser(User $user): array
{
$extensions = [];
$userExtension = $this->normalizeExtension((string) ($user->pbx_extension ?? ''));
if ($userExtension !== '') {
$extensions[] = $userExtension;
}
$amministratore = $this->resolveAmministratoreForUser($user);
if ($amministratore) {
$extensions = array_merge($extensions, $this->getStudioExtensionsForAmministratore($amministratore));
}
return array_values(array_unique(array_filter($extensions, fn($extension): bool => is_string($extension) && $extension !== '')));
}
/**
* @return array<int,string>
*/
public function getStudioExtensionsForAmministratore(Amministratore $amministratore): array
{
$pbx = (array) (($amministratore->impostazioni ?? [])['pbx'] ?? []);
$centralino = (array) (($amministratore->impostazioni ?? [])['centralino'] ?? []);
$extensions = [
$this->normalizeExtension((string) Arr::get($centralino, 'interno_centralino', '')),
$this->normalizeExtension((string) Arr::get($centralino, 'interno_operatore', '')),
$this->normalizeExtension((string) Arr::get($centralino, 'interno_amministratore', '')),
$this->normalizeExtension((string) Arr::get($centralino, 'interno_gruppo_giorno', '')),
$this->normalizeExtension((string) Arr::get($centralino, 'interno_gruppo_notte', '')),
];
$watchExtensions = preg_split('/\s*,\s*/', (string) ($pbx['watch_extensions'] ?? ''), -1, PREG_SPLIT_NO_EMPTY) ?: [];
foreach ($watchExtensions as $extension) {
$extensions[] = $this->normalizeExtension((string) $extension);
}
foreach ((array) ($pbx['response_groups'] ?? []) as $group) {
if (! is_array($group)) {
continue;
}
$extensions[] = $this->normalizeExtension((string) ($group['extension'] ?? ''));
$extensions[] = $this->normalizeExtension((string) ($group['target_extension'] ?? ''));
}
foreach ((array) ($pbx['incoming_lines'] ?? []) as $line) {
if (! is_array($line)) {
continue;
}
$extensions[] = $this->normalizeExtension((string) ($line['route_group'] ?? ''));
$extensions[] = $this->normalizeExtension((string) ($line['target_extension'] ?? ''));
}
return array_values(array_unique(array_filter($extensions, fn($extension): bool => $extension !== '')));
}
/**
* @return array{amministratore_id:int|null,studio_role:?string,studio_mode:?string}
*/
public function findStudioContextByExtension(?string $extension): array
{
$normalized = $this->normalizeExtension($extension);
if ($normalized === '') {
return [
'amministratore_id' => null,
'studio_role' => null,
'studio_mode' => null,
];
}
foreach (Amministratore::query()->get(['id', 'impostazioni']) as $amministratore) {
$pbx = (array) (($amministratore->impostazioni ?? [])['pbx'] ?? []);
$centralino = (array) (($amministratore->impostazioni ?? [])['centralino'] ?? []);
$map = [
'interno_centralino' => ['studio_role' => 'centralino', 'studio_mode' => null],
'interno_operatore' => ['studio_role' => 'operatore', 'studio_mode' => null],
'interno_amministratore' => ['studio_role' => 'amministratore', 'studio_mode' => null],
'interno_gruppo_giorno' => ['studio_role' => 'gruppo', 'studio_mode' => 'giorno'],
'interno_gruppo_notte' => ['studio_role' => 'gruppo', 'studio_mode' => 'notte'],
];
foreach ($map as $key => $context) {
if ($this->normalizeExtension((string) Arr::get($centralino, $key, '')) !== $normalized) {
continue;
}
return [
'amministratore_id' => (int) $amministratore->id,
'studio_role' => $context['studio_role'],
'studio_mode' => $context['studio_mode'],
];
}
foreach ((array) ($pbx['response_groups'] ?? []) as $group) {
if (! is_array($group)) {
continue;
}
if ($this->normalizeExtension((string) ($group['extension'] ?? '')) !== $normalized) {
continue;
}
return [
'amministratore_id' => (int) $amministratore->id,
'studio_role' => 'gruppo',
'studio_mode' => filled($group['mode'] ?? null) ? (string) $group['mode'] : null,
];
}
foreach ((array) ($pbx['incoming_lines'] ?? []) as $line) {
if (! is_array($line)) {
continue;
}
$routeExtension = $this->normalizeExtension((string) (($line['route_group'] ?? '') !== '' ? $line['route_group'] : ($line['target_extension'] ?? '')));
if ($routeExtension !== $normalized) {
continue;
}
return [
'amministratore_id' => (int) $amministratore->id,
'studio_role' => 'linea',
'studio_mode' => filled($line['label'] ?? null) ? (string) $line['label'] : null,
];
}
}
return [
'amministratore_id' => null,
'studio_role' => null,
'studio_mode' => null,
];
}
private function resolveAmministratoreForUser(User $user): ?Amministratore
{
if ($user->amministratore instanceof Amministratore) {
return $user->amministratore;
}
$activeStabile = StabileContext::getActiveStabile($user);
if ($activeStabile?->amministratore instanceof Amministratore) {
return $activeStabile->amministratore;
}
$amministratoreId = null;
if (method_exists($user, 'stabiliAssegnati')) {
$amministratoreId = $user->stabiliAssegnati()->value('stabili.amministratore_id');
}
return $amministratoreId ? Amministratore::query()->find((int) $amministratoreId) : null;
}
private function resolveAmministratoreIdForUser(User $user): ?int
{
$amministratore = $this->resolveAmministratoreForUser($user);
return $amministratore ? (int) $amministratore->id : null;
}
}