Files
compras/app/Http/Controllers/ReceiptDocumentController.php
T
2026-11-03 11:51:44 +02:00

61 lines
2.5 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\GoodsReceipt;
use App\Models\ReceiptDocument;
use App\Models\User;
use App\Services\ReceiptDocuments;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;
class ReceiptDocumentController extends Controller
{
public function store(Request $request, GoodsReceipt $receipt, ReceiptDocuments $documents): RedirectResponse
{
$actor = $request->user('web');
abort_unless($actor instanceof User, 403);
Gate::authorize('view', $receipt);
abort_unless($documents->canRead($actor, $receipt), 403);
abort_unless($documents->canAdd($actor, $receipt), 403);
$file = $request->file('file');
abort_unless($file instanceof UploadedFile, 422);
$documents->add($actor, $receipt, $request->only(['operation_key', 'document_type']), $file);
return redirect('/recepcoes/'.$receipt->id.'#receipt-documents');
}
public function download(Request $request, GoodsReceipt $receipt, int $document, ReceiptDocuments $documents): StreamedResponse
{
$actor = $request->user('web');
abort_unless($actor instanceof User && $documents->canRead($actor, $receipt), 403);
Gate::authorize('view', $receipt);
abort_unless($documents->ready(), 503);
$file = ReceiptDocument::query()->where('goods_receipt_id', $receipt->id)->findOrFail($document);
$disk = Storage::disk('receipt_documents');
abort_unless($disk->exists($file->path), 404);
$stream = $disk->readStream($file->path);
abort_unless(is_resource($stream), 404);
$hash = hash_init('sha256');
hash_update_stream($hash, $stream);
if (! hash_equals($file->sha256, hash_final($hash))) {
fclose($stream);
abort(409, 'Documento indisponível para descarga. Solicite conferência ao responsável.');
}
rewind($stream);
return response()->streamDownload(function () use ($stream) {
try {
fpassthru($stream);
} finally {
fclose($stream);
}
}, $file->original_name, ['Content-Type' => 'application/octet-stream', 'X-Content-Type-Options' => 'nosniff',
'Cache-Control' => 'private, no-store', 'Content-Security-Policy' => "default-src 'none'; sandbox"]);
}
}