222 lines
7.8 KiB
PHP
222 lines
7.8 KiB
PHP
<?php
|
|
namespace App\Filament\Pages\Fornitore\Concerns;
|
|
|
|
use App\Models\Fornitore;
|
|
use App\Models\FornitoreDipendente;
|
|
use App\Models\TicketIntervento;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
trait ResolvesOperatoreContext
|
|
{
|
|
/**
|
|
* @return array{0:?Fornitore,1:?FornitoreDipendente}
|
|
*/
|
|
protected function resolveOperatoreContext(?int $forcedFornitoreId = null, bool $allowAdminWithoutSupplier = false): array
|
|
{
|
|
$user = Auth::user();
|
|
|
|
if ($user && $user->hasAnyRole(['super-admin', 'admin', 'amministratore'])) {
|
|
$fornitoreId = $forcedFornitoreId ?: (int) request()->query('fornitore', 0);
|
|
|
|
if ($fornitoreId <= 0) {
|
|
$interventoRoute = request()->route('intervento');
|
|
if ($interventoRoute instanceof TicketIntervento) {
|
|
$fornitoreId = (int) ($interventoRoute->fornitore_id ?? 0);
|
|
}
|
|
}
|
|
|
|
if ($fornitoreId > 0) {
|
|
$fornitore = Fornitore::query()->find($fornitoreId);
|
|
abort_unless($fornitore instanceof Fornitore, 404);
|
|
|
|
return [$fornitore, null];
|
|
}
|
|
|
|
if ($allowAdminWithoutSupplier) {
|
|
return [null, null];
|
|
}
|
|
}
|
|
|
|
$requestedFornitoreId = $forcedFornitoreId ?: (int) request()->query('fornitore', 0);
|
|
$currentSupplier = $this->resolveCurrentUserSupplier($user);
|
|
|
|
if ($requestedFornitoreId > 0) {
|
|
$collaboratore = $this->resolveCollaboratoreForUser($requestedFornitoreId, $currentSupplier?->id);
|
|
if ($collaboratore instanceof FornitoreDipendente) {
|
|
$fornitore = Fornitore::query()->find($requestedFornitoreId);
|
|
abort_unless($fornitore instanceof Fornitore, 404);
|
|
|
|
$collaboratore->ultimo_accesso_at = now();
|
|
$collaboratore->save();
|
|
|
|
return [$fornitore, $collaboratore];
|
|
}
|
|
|
|
if ($currentSupplier instanceof Fornitore && (int) $currentSupplier->id === $requestedFornitoreId) {
|
|
return [$currentSupplier, null];
|
|
}
|
|
}
|
|
|
|
$dipendente = null;
|
|
$fornitore = $currentSupplier;
|
|
|
|
if (! $fornitore && $user) {
|
|
$dipendente = $this->resolveCollaboratoreForUser(null, null);
|
|
|
|
if ($dipendente instanceof FornitoreDipendente) {
|
|
$fornitore = Fornitore::query()->find((int) $dipendente->fornitore_id);
|
|
$dipendente->ultimo_accesso_at = now();
|
|
$dipendente->save();
|
|
}
|
|
}
|
|
|
|
abort_unless($fornitore instanceof Fornitore, 403, 'Profilo fornitore non collegato.');
|
|
|
|
return [$fornitore, $dipendente];
|
|
}
|
|
|
|
protected function resolveCurrentUserSupplier($user): ?Fornitore
|
|
{
|
|
if (! $user) {
|
|
return null;
|
|
}
|
|
|
|
$email = mb_strtolower(trim((string) $user->email));
|
|
if ($email === '') {
|
|
return null;
|
|
}
|
|
|
|
return Fornitore::query()
|
|
->whereRaw('LOWER(email) = ?', [$email])
|
|
->withCount(['ticketInterventi', 'dipendenti'])
|
|
->orderByDesc('ticket_interventi_count')
|
|
->orderByDesc('dipendenti_count')
|
|
->orderByDesc('id')
|
|
->first();
|
|
}
|
|
|
|
protected function resolveCollaboratoreForUser(?int $fornitoreId = null, ?int $currentSupplierId = null): ?FornitoreDipendente
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user) {
|
|
return null;
|
|
}
|
|
|
|
$query = FornitoreDipendente::query()
|
|
->where('attivo', true)
|
|
->when($fornitoreId, fn($builder) => $builder->where('fornitore_id', $fornitoreId))
|
|
->where(function ($builder) use ($user, $currentSupplierId): void {
|
|
$builder->where('user_id', (int) $user->id)
|
|
->orWhereRaw('LOWER(email) = ?', [mb_strtolower((string) $user->email)]);
|
|
|
|
if (($currentSupplierId ?? 0) > 0) {
|
|
$builder->orWhere('fornitore_esterno_id', (int) $currentSupplierId);
|
|
}
|
|
})
|
|
->orderByRaw('CASE WHEN user_id = ? THEN 0 ELSE 1 END', [(int) $user->id])
|
|
->orderByRaw('CASE WHEN fornitore_esterno_id IS NULL THEN 1 ELSE 0 END')
|
|
->orderByDesc('id');
|
|
|
|
return $query->first();
|
|
}
|
|
|
|
protected function authorizeIntervento(TicketIntervento $intervento, Fornitore $fornitore): void
|
|
{
|
|
abort_unless((int) $intervento->fornitore_id === (int) $fornitore->id, 403);
|
|
}
|
|
|
|
protected function authorizeDipendenteIntervento(TicketIntervento $intervento, ?FornitoreDipendente $dipendente): void
|
|
{
|
|
if (! $dipendente instanceof FornitoreDipendente) {
|
|
return;
|
|
}
|
|
|
|
$assignedDipendenteId = (int) ($intervento->eseguito_da_dipendente_id ?? 0);
|
|
abort_if($assignedDipendenteId > 0 && $assignedDipendenteId !== (int) $dipendente->id, 403, 'Intervento assegnato a un altro operatore del fornitore.');
|
|
}
|
|
|
|
/**
|
|
* @return array{ingresso:string,contatto:string,telefono:string,problema:string,apparato:string}
|
|
*/
|
|
protected function buildInterventoRow(TicketIntervento $intervento): array
|
|
{
|
|
$descrizione = (string) ($intervento->ticket->descrizione ?? '');
|
|
$caller = $this->extractCallerData($descrizione);
|
|
|
|
return [
|
|
'ingresso' => optional($intervento->created_at)->format('d/m/Y H:i') ?: '-',
|
|
'contatto' => $caller['contatto'],
|
|
'telefono' => $caller['telefono'],
|
|
'problema' => $caller['problema'] !== '' ? $caller['problema'] : ((string) ($intervento->ticket->titolo ?? '-')),
|
|
'apparato' => $this->extractApparato((string) ($intervento->rapporto_fornitore ?? '')),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array{contatto:string,telefono:string,problema:string}
|
|
*/
|
|
protected function extractCallerData(string $descrizione): array
|
|
{
|
|
$contatto = '-';
|
|
$telefono = '';
|
|
$problema = '';
|
|
|
|
$lines = preg_split('/\r\n|\r|\n/', $descrizione) ?: [];
|
|
foreach ($lines as $line) {
|
|
$trim = trim($line);
|
|
if ($problema === '' && $trim !== '') {
|
|
$problema = $trim;
|
|
}
|
|
|
|
if (str_starts_with($trim, 'Chiamante selezionato:')) {
|
|
$contatto = trim((string) str_replace('Chiamante selezionato:', '', $trim));
|
|
}
|
|
|
|
if (str_starts_with($trim, 'Telefono:')) {
|
|
$telefono = trim((string) str_replace('Telefono:', '', $trim));
|
|
}
|
|
}
|
|
|
|
return [
|
|
'contatto' => $contatto,
|
|
'telefono' => $telefono,
|
|
'problema' => $problema,
|
|
];
|
|
}
|
|
|
|
protected function extractApparato(string $rapporto): string
|
|
{
|
|
foreach ((preg_split('/\r\n|\r|\n/', $rapporto) ?: []) as $line) {
|
|
$trim = trim($line);
|
|
if (str_starts_with(mb_strtolower($trim), 'apparato:')) {
|
|
return trim((string) substr($trim, strlen('apparato:')));
|
|
}
|
|
}
|
|
|
|
return '-';
|
|
}
|
|
|
|
protected function buildApparatoSummary(string $marca, string $modello, string $seriale): string
|
|
{
|
|
$marca = trim($marca);
|
|
$modello = trim($modello);
|
|
$seriale = trim($seriale);
|
|
|
|
if ($marca === '' && $modello === '' && $seriale === '') {
|
|
return '';
|
|
}
|
|
|
|
return 'Apparato: '
|
|
. ($marca !== '' ? ('marca=' . $marca . ' ') : '')
|
|
. ($modello !== '' ? ('modello=' . $modello . ' ') : '')
|
|
. ($seriale !== '' ? ('seriale=' . $seriale) : '');
|
|
}
|
|
|
|
protected function getFornitoreLabel(Fornitore $fornitore): string
|
|
{
|
|
$label = trim((string) ($fornitore->ragione_sociale ?: trim(($fornitore->nome ?? '') . ' ' . ($fornitore->cognome ?? ''))));
|
|
|
|
return $label !== '' ? $label : ('Fornitore #' . (int) $fornitore->id);
|
|
}
|
|
}
|