87 خطوط
3.6 KiB
PHP
87 خطوط
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\ActivityLog;
|
|
use App\Models\CallLog;
|
|
use App\Models\Company;
|
|
use App\Models\Deal;
|
|
use App\Models\FollowUp;
|
|
use App\Models\Lead;
|
|
use App\Models\Note;
|
|
use App\Support\EntityResolver;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class TimelineController extends Controller
|
|
{
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'entity_type' => 'required|in:lead,company,deal',
|
|
'entity_id' => 'required|integer',
|
|
]);
|
|
|
|
EntityResolver::authorize($validated['entity_type'], $validated['entity_id']);
|
|
|
|
[$class, $id] = [$this->classFor($validated['entity_type']), $validated['entity_id']];
|
|
$items = collect();
|
|
|
|
ActivityLog::with('user:id,name')->where('subject_type', $class)->where('subject_id', $id)->latest()->limit(100)->get()
|
|
->each(fn ($log) => $items->push($this->item($log->created_at, $this->label($log->action), $log->description, $log->user?->name, $log->action)));
|
|
|
|
Note::with('user:id,name')->where('notable_type', $class)->where('notable_id', $id)->latest()->limit(100)->get()
|
|
->each(fn ($note) => $items->push($this->item($note->created_at, 'یادداشت ثبت شد', $note->content, $note->user?->name, 'note_created')));
|
|
|
|
if ($class === Lead::class) {
|
|
CallLog::with('user:id,name')->where('lead_id', $id)->latest('called_at')->limit(100)->get()
|
|
->each(fn ($call) => $items->push($this->item($call->called_at, 'تماس ثبت شد', trim(($call->result ? "نتیجه: {$call->result}. " : '').($call->notes ?? '')), $call->user?->name, 'call')));
|
|
|
|
FollowUp::with('user:id,name')->where('lead_id', $id)->latest('scheduled_at')->limit(100)->get()
|
|
->each(fn ($followUp) => $items->push($this->item($followUp->created_at, 'پیگیری ایجاد شد', 'زمان پیگیری: '.optional($followUp->scheduled_at)->toDateTimeString(), $followUp->user?->name, 'follow_up_created')));
|
|
}
|
|
|
|
return response()->json([
|
|
'data' => $items->sortByDesc('created_at')->values()->take(150)->all(),
|
|
]);
|
|
}
|
|
|
|
private function classFor(string $type): string
|
|
{
|
|
return match ($type) {
|
|
'lead' => Lead::class,
|
|
'company' => Company::class,
|
|
'deal' => Deal::class,
|
|
};
|
|
}
|
|
|
|
private function item($date, string $title, ?string $description, ?string $user, string $type): array
|
|
{
|
|
return [
|
|
'type' => $type,
|
|
'title' => $title,
|
|
'description' => $description,
|
|
'user' => $user ?: 'سیستم',
|
|
'created_at' => optional($date)->toDateTimeString(),
|
|
];
|
|
}
|
|
|
|
private function label(string $action): string
|
|
{
|
|
return [
|
|
'call_result_registered' => 'نتیجه تماس ثبت شد',
|
|
'lead_stage_changed' => 'مرحله تغییر کرد',
|
|
'lead_assigned' => 'مالک تغییر کرد',
|
|
'lead_owner_changed' => 'مالک تغییر کرد',
|
|
'company_created' => 'شرکت ایجاد شد',
|
|
'company_updated' => 'شرکت ویرایش شد',
|
|
'company_merged' => 'شرکت ادغام شد',
|
|
'deal_created' => 'فرصت فروش ایجاد شد',
|
|
'deal_updated' => 'فرصت فروش ویرایش شد',
|
|
'attachment_uploaded' => 'فایل بارگذاری شد',
|
|
'attachment_downloaded' => 'فایل دریافت شد',
|
|
][$action] ?? 'رویداد ثبت شد';
|
|
}
|
|
}
|