126 lines
4.2 KiB
PHP
126 lines
4.2 KiB
PHP
<?php
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Fornitore;
|
|
use App\Models\FornitoreDipendente;
|
|
use App\Models\TicketAttachment;
|
|
use App\Models\User;
|
|
use App\Support\StabileContext;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
|
|
class TicketAttachmentViewController extends Controller
|
|
{
|
|
public function show(TicketAttachment $attachment): BinaryFileResponse
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
abort(403);
|
|
}
|
|
|
|
if (! $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore', 'fornitore'])) {
|
|
abort(403);
|
|
}
|
|
|
|
$ticket = $attachment->ticket;
|
|
if (! $ticket) {
|
|
abort(404);
|
|
}
|
|
|
|
if ($user->hasRole('fornitore')) {
|
|
$this->authorizeSupplierAttachment($user, $attachment);
|
|
} else {
|
|
$stabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $stabileId || (int) $ticket->stabile_id !== (int) $stabileId) {
|
|
abort(403);
|
|
}
|
|
}
|
|
|
|
$disk = Storage::disk('public');
|
|
$path = (string) $attachment->file_path;
|
|
if (! $disk->exists($path)) {
|
|
abort(404);
|
|
}
|
|
|
|
$absolutePath = $disk->path($path);
|
|
$mime = $attachment->resolvedMimeType();
|
|
|
|
return response()->file($absolutePath, [
|
|
'Content-Type' => $mime,
|
|
'Cache-Control' => 'private, max-age=300',
|
|
'Content-Disposition' => 'inline; filename="' . addslashes((string) ($attachment->original_file_name ?: basename($path))) . '"',
|
|
]);
|
|
}
|
|
|
|
protected function authorizeSupplierAttachment(User $user, TicketAttachment $attachment): void
|
|
{
|
|
$fornitoreIds = [];
|
|
$currentSupplier = $this->resolveCurrentUserSupplier($user);
|
|
|
|
if ($currentSupplier instanceof Fornitore) {
|
|
$fornitoreIds[] = (int) $currentSupplier->id;
|
|
}
|
|
|
|
$dipendente = $this->resolveCollaboratoreForUser($user, $currentSupplier?->id);
|
|
if ($dipendente instanceof FornitoreDipendente) {
|
|
$fornitoreIds[] = (int) $dipendente->fornitore_id;
|
|
|
|
if ((int) ($dipendente->fornitore_esterno_id ?? 0) > 0) {
|
|
$fornitoreIds[] = (int) $dipendente->fornitore_esterno_id;
|
|
}
|
|
}
|
|
|
|
$fornitoreIds = array_values(array_unique(array_filter($fornitoreIds)));
|
|
abort_if($fornitoreIds === [], 403);
|
|
|
|
$ticket = $attachment->ticket;
|
|
abort_unless($ticket, 404);
|
|
|
|
if (in_array((int) ($ticket->assegnato_a_fornitore_id ?? 0), $fornitoreIds, true)) {
|
|
return;
|
|
}
|
|
|
|
$hasIntervento = $ticket->interventi()
|
|
->whereIn('fornitore_id', $fornitoreIds)
|
|
->exists();
|
|
|
|
abort_unless($hasIntervento, 403);
|
|
}
|
|
|
|
protected function resolveCurrentUserSupplier(User $user): ?Fornitore
|
|
{
|
|
$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(User $user, ?int $currentSupplierId = null): ?FornitoreDipendente
|
|
{
|
|
return FornitoreDipendente::query()
|
|
->where('attivo', true)
|
|
->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')
|
|
->first();
|
|
}
|
|
}
|