129 خطوط
4.9 KiB
PHP
129 خطوط
4.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\StoreCallNoteRequest;
|
|
use App\Http\Requests\UpdateNoteRequest;
|
|
use App\Http\Resources\NoteResource;
|
|
use App\Http\Responses\ApiResponse;
|
|
use App\Models\Call;
|
|
use App\Models\Note;
|
|
use App\Services\ActivityLogger;
|
|
use App\Support\EntityResolver;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Gate;
|
|
|
|
class NoteController extends Controller
|
|
{
|
|
public function callIndex(Call $call): JsonResponse
|
|
{
|
|
Gate::authorize('view', $call);
|
|
$query = $call->notesHistory()->with('user:id,name');
|
|
if (! auth()->user()->hasRole('admin')) {
|
|
$query->where(fn ($visibility) => $visibility
|
|
->where('visibility', '<>', 'private')
|
|
->orWhere('user_id', auth()->id()));
|
|
}
|
|
|
|
$notes = $query->orderByDesc('is_pinned')->latest()->get();
|
|
|
|
return ApiResponse::success($notes->map(fn (Note $note) => $this->resource($note))->all());
|
|
}
|
|
|
|
public function callStore(StoreCallNoteRequest $request, Call $call): JsonResponse
|
|
{
|
|
Gate::authorize('create', [Note::class, $call]);
|
|
$note = DB::transaction(function () use ($request, $call): Note {
|
|
$note = $call->notesHistory()->create([
|
|
'user_id' => $request->user()->id,
|
|
'content' => $request->validated('content'),
|
|
'type' => $request->validated('type', 'general'),
|
|
'visibility' => $request->validated('visibility', 'team'),
|
|
]);
|
|
ActivityLogger::log('call_note_created', "Call note {$note->id} created", $note, null, $note->only(['type', 'visibility', 'is_pinned']));
|
|
|
|
return $note;
|
|
});
|
|
|
|
return ApiResponse::success($this->resource($note->load('user:id,name')), 201, 'یادداشت تماس ثبت شد.');
|
|
}
|
|
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'entity_type' => 'required|in:lead,company,deal',
|
|
'entity_id' => 'required|integer',
|
|
'content' => 'required|string|max:5000',
|
|
]);
|
|
$model = EntityResolver::authorize($validated['entity_type'], $validated['entity_id'], 'update');
|
|
$note = DB::transaction(function () use ($model, $validated): Note {
|
|
$note = $model->notes()->create([
|
|
'user_id' => auth()->id(),
|
|
'content' => $validated['content'],
|
|
'type' => 'general',
|
|
'visibility' => 'team',
|
|
]);
|
|
ActivityLogger::log('note_created', 'یادداشت جدید ثبت شد', $note, null, $note->only(['type', 'visibility']));
|
|
|
|
return $note;
|
|
});
|
|
|
|
return ApiResponse::success($this->resource($note->load('user:id,name')), 201, 'یادداشت ثبت شد.');
|
|
}
|
|
|
|
public function update(UpdateNoteRequest $request, Note $note): JsonResponse
|
|
{
|
|
Gate::authorize('update', $note);
|
|
$updated = DB::transaction(function () use ($request, $note): Note {
|
|
$before = $note->only(['type', 'visibility', 'is_pinned']);
|
|
$note->fill($request->validated());
|
|
$note->edited_at = now();
|
|
$note->save();
|
|
ActivityLogger::log('call_note_edited', "Note {$note->id} edited", $note, $before, $note->only(['type', 'visibility', 'is_pinned']));
|
|
|
|
return $note;
|
|
});
|
|
|
|
return ApiResponse::success($this->resource($updated->load('user:id,name')), message: 'یادداشت ویرایش شد.');
|
|
}
|
|
|
|
public function destroy(Note $note): JsonResponse
|
|
{
|
|
Gate::authorize('delete', $note);
|
|
DB::transaction(function () use ($note): void {
|
|
$before = $note->only(['type', 'visibility', 'is_pinned']);
|
|
$note->delete();
|
|
ActivityLogger::log('call_note_deleted', "Note {$note->id} deleted", $note, $before, ['deleted' => true]);
|
|
});
|
|
|
|
return ApiResponse::success(null, message: 'یادداشت حذف شد.');
|
|
}
|
|
|
|
public function pin(Note $note): JsonResponse
|
|
{
|
|
return $this->setPinned($note, true);
|
|
}
|
|
|
|
public function unpin(Note $note): JsonResponse
|
|
{
|
|
return $this->setPinned($note, false);
|
|
}
|
|
|
|
private function setPinned(Note $note, bool $pinned): JsonResponse
|
|
{
|
|
Gate::authorize('pin', $note);
|
|
$note->update(['is_pinned' => $pinned]);
|
|
ActivityLogger::log($pinned ? 'call_note_pinned' : 'call_note_unpinned', "Note {$note->id} pin changed", $note, ['is_pinned' => ! $pinned], ['is_pinned' => $pinned]);
|
|
|
|
return ApiResponse::success($this->resource($note->load('user:id,name')), message: $pinned ? 'یادداشت سنجاق شد.' : 'سنجاق یادداشت برداشته شد.');
|
|
}
|
|
|
|
private function resource(Note $note): array
|
|
{
|
|
return (new NoteResource($note))->resolve(request());
|
|
}
|
|
}
|