70 lines
3.4 KiB
PHP
70 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Supplier;
|
|
use App\Models\SupplierDocument;
|
|
use App\Services\RequisitionWorkflow;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Gate;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Validation\Rule;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
use Throwable;
|
|
|
|
class SupplierDocumentController extends Controller
|
|
{
|
|
public function store(Request $request, Supplier $supplier, RequisitionWorkflow $workflow): RedirectResponse
|
|
{
|
|
Gate::authorize('update', $supplier);
|
|
$data = $request->validate([
|
|
'document_type' => ['required', Rule::in(['license', 'tax', 'conflict', 'other'])],
|
|
'file' => ['required', 'file', 'mimes:pdf,jpg,jpeg,png', 'extensions:pdf,jpg,jpeg,png', 'min:1', 'max:2048'],
|
|
]);
|
|
$file = $request->file('file');
|
|
abort_unless($file instanceof UploadedFile, 422);
|
|
$path = $file->store($supplier->tenant_id.'/'.$supplier->id, 'supplier_documents');
|
|
abort_if($path === false, 500);
|
|
try {
|
|
DB::transaction(function () use ($request, $supplier, $workflow, $data, $file, $path) {
|
|
$supplier = Supplier::query()->lockForUpdate()->findOrFail($supplier->id);
|
|
$before = $supplier->toArray();
|
|
$name = Str::substr(Str::replaceMatches('/[^\pL\pN ._()-]/u', '_', basename(str_replace('\\', '/', $file->getClientOriginalName()))), 0, 180);
|
|
$document = $supplier->documents()->create([
|
|
'tenant_id' => $supplier->tenant_id, 'uploaded_by' => $request->user()->id,
|
|
'document_type' => $data['document_type'], 'original_name' => $name,
|
|
'path' => $path, 'mime_type' => $file->getMimeType(), 'size' => $file->getSize(),
|
|
'sha256' => hash_file('sha256', $file->getPathname()),
|
|
]);
|
|
$supplier->update(['status' => 'pending', 'reviewed_by' => null, 'review_comment' => null, 'last_changed_by' => $request->user()->id, 'version' => $supplier->version + 1]);
|
|
$workflow->audit($request->user(), 'supplier.document_uploaded', null, $before, ['supplier' => $supplier->toArray(), 'document' => $document->toArray()]);
|
|
});
|
|
} catch (Throwable $exception) {
|
|
Storage::disk('supplier_documents')->delete($path);
|
|
throw $exception;
|
|
}
|
|
|
|
return back();
|
|
}
|
|
|
|
public function download(Request $request, Supplier $supplier, SupplierDocument $document, RequisitionWorkflow $workflow): StreamedResponse
|
|
{
|
|
Gate::authorize('viewDocuments', $supplier);
|
|
abort_unless($document->supplier_id === $supplier->id, 404);
|
|
$disk = Storage::disk('supplier_documents');
|
|
abort_unless($disk->exists($document->path), 404);
|
|
$workflow->audit($request->user(), 'supplier.document_downloaded', null, null, ['supplier_id' => $supplier->id, 'document_id' => $document->id, 'name' => $document->original_name]);
|
|
|
|
return $disk->download($document->path, $document->original_name, [
|
|
'Content-Type' => 'application/octet-stream',
|
|
'X-Content-Type-Options' => 'nosniff',
|
|
'Cache-Control' => 'private, no-store',
|
|
'Content-Security-Policy' => "default-src 'none'; sandbox",
|
|
]);
|
|
}
|
|
}
|