Mager updated

This commit is contained in:
Simon Pocrnjič
2025-09-27 17:45:55 +02:00
parent d17e34941b
commit 7227c888d4
74 changed files with 6339 additions and 342 deletions
@@ -4,6 +4,9 @@
use App\Models\ClientCase;
use App\Models\Contract;
use App\Models\Document;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Storage;
use Exception;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
@@ -162,6 +165,119 @@ public function deleteContract(ClientCase $clientCase, String $uuid, Request $re
return to_route('clientCase.show', $clientCase);
}
public function storeDocument(ClientCase $clientCase, Request $request)
{
$validated = $request->validate([
'file' => 'required|file|max:25600|mimes:doc,docx,pdf,txt,csv,xls,xlsx,jpeg,png', // 25MB and allowed types
'name' => 'nullable|string|max:255',
'description' => 'nullable|string',
'is_public' => 'sometimes|boolean',
]);
$file = $validated['file'];
$disk = 'public';
$directory = 'cases/' . $clientCase->uuid . '/documents';
$path = $file->store($directory, $disk);
$doc = new Document([
'name' => $validated['name'] ?? pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME),
'description' => $validated['description'] ?? null,
'user_id' => optional($request->user())->id,
'disk' => $disk,
'path' => $path,
'file_name' => basename($path),
'original_name' => $file->getClientOriginalName(),
'extension' => $file->getClientOriginalExtension(),
'mime_type' => $file->getMimeType(),
'size' => $file->getSize(),
'checksum' => null,
'is_public' => (bool)($validated['is_public'] ?? false),
]);
$clientCase->documents()->save($doc);
// Generate preview immediately for Office docs to avoid first-view delay
$ext = strtolower($doc->extension ?? pathinfo($doc->original_name ?? $doc->file_name, PATHINFO_EXTENSION));
if (in_array($ext, ['doc','docx'])) {
\App\Jobs\GenerateDocumentPreview::dispatch($doc->id);
}
return back()->with('success', 'Document uploaded.');
}
public function viewDocument(ClientCase $clientCase, Document $document, Request $request)
{
// Ensure the document belongs to this client case
if ($document->documentable_type !== ClientCase::class || $document->documentable_id !== $clientCase->id) {
abort(404);
}
// Optional: add authz checks here (e.g., policies)
$disk = $document->disk ?: 'public';
// If a preview exists (e.g., PDF generated for doc/docx), stream that
$previewDisk = config('files.preview_disk', 'public');
if ($document->preview_path && Storage::disk($previewDisk)->exists($document->preview_path)) {
$stream = Storage::disk($previewDisk)->readStream($document->preview_path);
if ($stream === false) abort(404);
return response()->stream(function () use ($stream) { fpassthru($stream); }, 200, [
'Content-Type' => $document->preview_mime ?: 'application/pdf',
'Content-Disposition' => 'inline; filename="' . addslashes(($document->original_name ?: $document->file_name) . '.pdf') . '"',
'Cache-Control' => 'private, max-age=0, no-cache',
'Pragma' => 'no-cache',
]);
}
// If it's a DOC/DOCX and no preview yet, queue generation and show 202 Accepted
$ext = strtolower(pathinfo($document->original_name ?: $document->file_name, PATHINFO_EXTENSION));
if (in_array($ext, ['doc','docx'])) {
\App\Jobs\GenerateDocumentPreview::dispatch($document->id);
return response('Preview is being generated. Please try again shortly.', 202);
}
if (!Storage::disk($disk)->exists($document->path)) {
abort(404);
}
$stream = Storage::disk($disk)->readStream($document->path);
if ($stream === false) {
abort(404);
}
return response()->stream(function () use ($stream) {
fpassthru($stream);
}, 200, [
'Content-Type' => $document->mime_type ?: 'application/octet-stream',
'Content-Disposition' => 'inline; filename="' . addslashes($document->original_name ?: $document->file_name) . '"',
'Cache-Control' => 'private, max-age=0, no-cache',
'Pragma' => 'no-cache',
]);
}
public function downloadDocument(ClientCase $clientCase, Document $document, Request $request)
{
if ($document->documentable_type !== ClientCase::class || $document->documentable_id !== $clientCase->id) {
abort(404);
}
$disk = $document->disk ?: 'public';
if (!Storage::disk($disk)->exists($document->path)) {
abort(404);
}
$name = $document->original_name ?: $document->file_name;
$stream = Storage::disk($disk)->readStream($document->path);
if ($stream === false) {
abort(404);
}
return response()->stream(function () use ($stream) {
fpassthru($stream);
}, 200, [
'Content-Type' => $document->mime_type ?: 'application/octet-stream',
'Content-Disposition' => 'attachment; filename="' . addslashes($name) . '"',
'Cache-Control' => 'private, max-age=0, no-cache',
'Pragma' => 'no-cache',
]);
}
/**
* Display the specified resource.
*/
@@ -185,6 +301,7 @@ public function show(ClientCase $clientCase)
'activities' => $case->activities()->with(['action', 'decision'])
->orderByDesc('created_at')
->paginate(20, ['*'], 'activities'),
'documents' => $case->documents()->orderByDesc('created_at')->get(),
'contract_types' => \App\Models\ContractType::whereNull('deleted_at')->get(),
'actions' => \App\Models\Action::with('decisions')->get(),
'types' => $types