CRM/backend/app/Http/Controllers/Api/WorkspaceController.php

108 خطوط
5.4 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Call;
use App\Models\Company;
use App\Models\Contact;
use App\Models\DashboardPreference;
use App\Models\Lead;
use App\Models\NotificationPreference;
use App\Models\SavedView;
use App\Support\AccessControl;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class WorkspaceController extends Controller
{
public function search(Request $request): JsonResponse
{
abort_unless($request->user()->can('use_global_search'), 403);
$data = $request->validate(['q' => 'required|string|min:2|max:100']);
$q = $data['q'];
$user = $request->user();
$leads = Lead::query();
AccessControl::scopeLeads($leads, $user);
$companies = Company::query();
AccessControl::scopeCompanies($companies, $user);
$contacts = Contact::query();
AccessControl::scopeContacts($contacts, $user);
$calls = Call::with('lead:id,first_name,last_name,company');
AccessControl::scopeCalls($calls, $user);
return response()->json([
'leads' => $leads->where(fn (Builder $x) => $x->where('first_name', 'like', "%{$q}%")->orWhere('last_name', 'like', "%{$q}%")->orWhere('company', 'like', "%{$q}%")->orWhere('phone', 'like', "%{$q}%"))->limit(5)->get(['id', 'first_name', 'last_name', 'company', 'lead_score', 'score_level']),
'companies' => $companies->where('name', 'like', "%{$q}%")->limit(5)->get(['id', 'name', 'industry']),
'contacts' => $contacts->where('name', 'like', "%{$q}%")->limit(5)->get(['id', 'name', 'email']),
'calls' => $calls->where('notes', 'like', "%{$q}%")->limit(5)->latest()->get(['id', 'lead_id', 'result', 'created_at']),
]);
}
public function savedViews(Request $request): JsonResponse
{
abort_unless($request->user()->can('manage_saved_views'), 403);
$entity = $request->validate(['entity_type' => 'nullable|string|in:lead,deal,company,contact,call,task'])['entity_type'] ?? null;
$teamIds = AccessControl::teamIds($request->user());
$query = SavedView::where(fn (Builder $q) => $q->where('user_id', $request->user()->id)->orWhere('visibility', 'public')->orWhere(fn (Builder $team) => $team->where('visibility', 'team')->whereIn('team_id', $teamIds)));
if ($entity) {
$query->where('entity_type', $entity);
}
return response()->json($query->orderByDesc('is_default')->latest()->get());
}
public function storeSavedView(Request $request): JsonResponse
{
abort_unless($request->user()->can('manage_saved_views'), 403);
$data = $request->validate([
'entity_type' => 'required|in:lead,deal,company,contact,call,task', 'name' => 'required|string|max:100',
'visibility' => 'required|in:private,team,public', 'team_id' => 'nullable|exists:teams,id',
'filters' => 'required|array|max:30', 'columns' => 'nullable|array|max:30', 'sort' => 'nullable|array|max:5', 'is_default' => 'boolean',
]);
if ($data['visibility'] !== 'private') {
abort_unless($request->user()->can('share_team_views'), 403);
}
if (($data['visibility'] ?? '') === 'team') {
abort_unless(in_array((int) ($data['team_id'] ?? 0), AccessControl::teamIds($request->user()), true), 403);
}
if ($data['is_default'] ?? false) {
SavedView::where('user_id', $request->user()->id)->where('entity_type', $data['entity_type'])->update(['is_default' => false]);
}
return response()->json(SavedView::create($data + ['user_id' => $request->user()->id]), 201);
}
public function deleteSavedView(Request $request, SavedView $savedView): JsonResponse
{
abort_unless($savedView->user_id === $request->user()->id || $request->user()->hasRole('admin'), 403);
$savedView->delete();
return response()->json(['message' => 'نمای ذخیره‌شده حذف شد.']);
}
public function preferences(Request $request): JsonResponse
{
return response()->json([
'dashboard' => DashboardPreference::firstOrCreate(['user_id' => $request->user()->id]),
'notifications' => NotificationPreference::where('user_id', $request->user()->id)->get(),
]);
}
public function updatePreferences(Request $request): JsonResponse
{
$data = $request->validate([
'widget_order' => 'nullable|array|max:30', 'hidden_widgets' => 'nullable|array|max:30', 'default_filters' => 'nullable|array|max:20',
'notifications' => 'nullable|array|max:30', 'notifications.*.notification_type' => 'required|string|max:60',
'notifications.*.in_app_enabled' => 'boolean', 'notifications.*.is_muted' => 'boolean',
]);
$dashboard = DashboardPreference::updateOrCreate(['user_id' => $request->user()->id], collect($data)->only(['widget_order', 'hidden_widgets', 'default_filters'])->all());
foreach ($data['notifications'] ?? [] as $preference) {
NotificationPreference::updateOrCreate(['user_id' => $request->user()->id, 'notification_type' => $preference['notification_type']], $preference);
}
return response()->json(['dashboard' => $dashboard, 'notifications' => NotificationPreference::where('user_id', $request->user()->id)->get()]);
}
}