Restrict the Customers shown in the search page
This commit is contained in:
parent
b754fefe70
commit
5fad34c6b6
4 changed files with 197 additions and 3 deletions
|
@ -5,18 +5,22 @@
|
|||
*/
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use MMF\FreescoutRestrictedCustomers\Http\Controllers\ConversationsController;
|
||||
use MMF\FreescoutRestrictedCustomers\Http\Controllers\CrmController;
|
||||
use MMF\FreescoutRestrictedCustomers\Http\Controllers\CustomersController;
|
||||
|
||||
// FIXME: Routes are not correctly exposed to the main application,
|
||||
// routes/web.php and Modules/Crm/Http/routes.php must be manually edited.
|
||||
|
||||
// Customers
|
||||
Route::get('/customers/{id}/edit', CustomersController::class . '@update')->name('customers.update');
|
||||
Route::post('/customers/{id}/edit', CustomersController::class . '@updateSave');
|
||||
Route::get('/customers/{id}/', CustomersController::class . '@conversations')->name('customers.conversations');
|
||||
Route::get('/customers/ajax-search', ['uses' => CustomersController::class . '@ajaxSearch', 'laroute' => true])->name('customers.ajax_search');
|
||||
Route::post('/customers/ajax', ['uses' => CustomersController::class . '@ajax', 'laroute' => true])->name('customers.ajax');
|
||||
|
||||
// Conversations
|
||||
Route::get('/search', ConversationsController::class . '@search')->name('conversations.search');
|
||||
// Crm module
|
||||
Route::group([ 'roles' => ['user', 'admin'] ], function() {
|
||||
Route::get('/customers/new', CrmController::class . '@createCustomer')->name('freescout-restricted-customers.create_customer');
|
||||
// The Crm module initialization will crash if no route named "crm.create_customer" is set.
|
||||
|
@ -26,7 +30,6 @@ Route::group([ 'roles' => ['user', 'admin'] ], function() {
|
|||
Route::get('/customers/fields/ajax-search', ['uses' => CrmController::class . '@ajaxSearch', 'laroute' => true])->name('crm.ajax_search');
|
||||
Route::post('/crm/ajax', ['uses' => CrmController::class . '@ajax', 'laroute' => true])->name('crm.ajax');
|
||||
});
|
||||
|
||||
Route::group([ 'roles' => ['admin'] ], function() {
|
||||
Route::post('/customers/export', ['uses' => CrmController::class . '@export'])->name('crm.export');
|
||||
Route::post('/crm/ajax-admin', ['uses' => CrmController::class . '@ajaxAdmin', 'laroute' => true])->name('crm.ajax_admin');
|
||||
|
|
|
@ -64,4 +64,22 @@ class Customer extends BaseCustomer {
|
|||
|
||||
return parent::setData($data, $replace_data, $save);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only return a Customer instance if it is available to the current User.
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $columns
|
||||
* @return mixed|static
|
||||
*/
|
||||
public static function find($id, $columns = ['*']) {
|
||||
// Get the list of Mailboxes the current User has access to.
|
||||
$user = auth()->user();
|
||||
$mailboxes = $user->mailboxesIdsCanView();
|
||||
|
||||
$customer = self
|
||||
::where('id', '=', $id)
|
||||
->whereIn('mailbox_id', $mailboxes)
|
||||
->first($columns);
|
||||
}
|
||||
}
|
||||
|
|
173
src/Http/Controllers/ConversationsController.php
Normal file
173
src/Http/Controllers/ConversationsController.php
Normal file
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
/*
|
||||
SPDX-License-Identifier: AGPL
|
||||
SPDX-FileCopyrightText: © 2024 Millions Missing FRANCE <info@millionsmissing.fr>
|
||||
*/
|
||||
|
||||
namespace MMF\FreescoutRestrictedCustomers\Http\Controllers;
|
||||
|
||||
use App\Conversation;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\ConversationsController as BaseConversationsController;
|
||||
use MMF\FreescoutRestrictedCustomers\Customer;
|
||||
|
||||
class ConversationsController extends BaseConversationsController {
|
||||
/**
|
||||
* Search.
|
||||
*/
|
||||
public function search(Request $request) {
|
||||
$user = auth()->user();
|
||||
$conversations = [];
|
||||
$customers = [];
|
||||
|
||||
$mode = $this->getSearchMode($request);
|
||||
|
||||
// Search query
|
||||
$q = $this->getSearchQuery($request);
|
||||
|
||||
// Filters.
|
||||
$filters = $this->getSearchFilters($request);
|
||||
$filters_data = [];
|
||||
// Modify filters is needed.
|
||||
if (!empty($filters['customer'])) {
|
||||
// Get customer name.
|
||||
$filters_data['customer'] = Customer::find($filters['customer']);
|
||||
}
|
||||
//$filters = \Eventy::filter('search.filters', $filters, $filters_data, $mode, $q);
|
||||
|
||||
// Remember recent query.
|
||||
$recent_search_queries = session('recent_search_queries') ?? [];
|
||||
if ($q && !in_array($q, $recent_search_queries)) {
|
||||
array_unshift($recent_search_queries, $q);
|
||||
$recent_search_queries = array_slice($recent_search_queries, 0, 4);
|
||||
session()->put('recent_search_queries', $recent_search_queries);
|
||||
}
|
||||
|
||||
$conversations = [];
|
||||
if (\Eventy::filter('search.is_needed', true, 'conversations')) {
|
||||
$conversations = $this->searchQuery($user, $q, $filters);
|
||||
}
|
||||
|
||||
// Jump to the conversation if searching by conversation number.
|
||||
if (count($conversations) == 1
|
||||
&& $conversations[0]->number == $q
|
||||
&& empty($filters)
|
||||
&& !$request->x_embed
|
||||
) {
|
||||
return redirect()->away($conversations[0]->url($conversations[0]->folder_id));
|
||||
}
|
||||
|
||||
$customers = $this->searchCustomers($request, $user);
|
||||
|
||||
// Dummy folder
|
||||
$folder = $this->getSearchFolder($conversations);
|
||||
|
||||
// List of available filters.
|
||||
if ($mode == Conversation::SEARCH_MODE_CONV) {
|
||||
$filters_list = \Eventy::filter('search.filters_list', Conversation::$search_filters, $mode, $filters, $q);
|
||||
} else {
|
||||
$filters_list = \Eventy::filter('search.filters_list_customers', Customer::$search_filters, $mode, $filters, $q);
|
||||
}
|
||||
|
||||
$mailboxes = \Cache::remember('search_filter_mailboxes_'.$user->id, 5, function () use ($user) {
|
||||
return $user->mailboxesCanView();
|
||||
});
|
||||
$users = \Cache::remember('search_filter_users_'.$user->id, 5, function () use ($user, $mailboxes) {
|
||||
return \Eventy::filter('search.assignees', $user->whichUsersCanView($mailboxes), $user, $mailboxes);
|
||||
});
|
||||
$search_mailbox = null;
|
||||
if (isset($filters['mailbox'])) {
|
||||
$mailbox_id = (int)$filters['mailbox'];
|
||||
if ($mailbox_id && in_array($mailbox_id, $mailboxes->pluck('id')->toArray())) {
|
||||
foreach ($mailboxes as $mailbox_item) {
|
||||
if ($mailbox_item->id == $mailbox_id) {
|
||||
$search_mailbox = $mailbox_item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (count($mailboxes) == 1) {
|
||||
$search_mailbox = $mailboxes[0];
|
||||
}
|
||||
|
||||
return view('conversations/search', [
|
||||
'folder' => $folder,
|
||||
'q' => $request->q,
|
||||
'filters' => $filters,
|
||||
'filters_list' => $filters_list,
|
||||
'filters_data' => $filters_data,
|
||||
//'filters_list_all' => $filters_list_all,
|
||||
'mode' => $mode,
|
||||
'conversations' => $conversations,
|
||||
'customers' => $customers,
|
||||
'recent' => session('recent_search_queries'),
|
||||
'users' => $users,
|
||||
'mailboxes' => $mailboxes,
|
||||
'search_mailbox' => $search_mailbox,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search conversations.
|
||||
*/
|
||||
public function searchCustomers($request, $user) {
|
||||
// Get IDs of mailboxes to which user has access
|
||||
$mailbox_ids = $user->mailboxesIdsCanView();
|
||||
|
||||
// Filters
|
||||
$filters = $this->getSearchFilters($request);;
|
||||
|
||||
// Search query
|
||||
$q = $this->getSearchQuery($request);
|
||||
|
||||
// Like is case insensitive.
|
||||
$like = '%'.mb_strtolower($q).'%';
|
||||
|
||||
// We need to use aggregate function for email to avoid "Grouping error" error in PostgreSQL.
|
||||
$query_customers = Customer::select(['customers.*', \DB::raw('MAX(emails.email)')])
|
||||
->groupby('customers.id')
|
||||
->leftJoin('emails', function ($join) {
|
||||
$join->on('customers.id', '=', 'emails.customer_id');
|
||||
})
|
||||
->where(function ($query) use ($like, $q) {
|
||||
$like_op = 'like';
|
||||
if (\Helper::isPgSql()) {
|
||||
$like_op = 'ilike';
|
||||
}
|
||||
|
||||
$query
|
||||
->where('customers.first_name', $like_op, $like)
|
||||
->orwhere('customers.last_name', $like_op, $like)
|
||||
->orwhere('customers.company', $like_op, $like)
|
||||
->orwhere('customers.job_title', $like_op, $like)
|
||||
->orwhere('customers.websites', $like_op, $like)
|
||||
->orwhere('customers.social_profiles', $like_op, $like)
|
||||
->orwhere('customers.address', $like_op, $like)
|
||||
->orwhere('customers.city', $like_op, $like)
|
||||
->orwhere('customers.state', $like_op, $like)
|
||||
->orwhere('customers.zip', $like_op, $like)
|
||||
->orwhere('emails.email', $like_op, $like);
|
||||
|
||||
$phone_numeric = \Helper::phoneToNumeric($q);
|
||||
|
||||
if ($phone_numeric) {
|
||||
$query->orWhere('customers.phones', $like_op, '%"'.$phone_numeric.'"%');
|
||||
}
|
||||
|
||||
})
|
||||
// Restrict the query to the Customers the current User is allowed to access.
|
||||
->whereIn('customers.mailbox_id', $mailbox_ids);
|
||||
|
||||
if (!empty($filters['mailbox']) && in_array($filters['mailbox'], $mailbox_ids)) {
|
||||
$query_customers->join('conversations', function ($join) use ($filters) {
|
||||
$join->on('conversations.customer_id', '=', 'customers.id');
|
||||
//$join->on('conversations.mailbox_id', '=', $filters['mailbox']);
|
||||
});
|
||||
$query_customers->where('conversations.mailbox_id', '=', $filters['mailbox']);
|
||||
}
|
||||
|
||||
$query_customers = \Eventy::filter('search.customers.apply_filters', $query_customers, $filters, $q);
|
||||
|
||||
return $query_customers->paginate(50);
|
||||
}
|
||||
}
|
|
@ -363,7 +363,7 @@ class CustomersController extends BaseCustomersController {
|
|||
// Conversations navigation
|
||||
case 'customers_pagination':
|
||||
|
||||
$customers = app('App\Http\Controllers\ConversationsController')->searchCustomers($request, $user);
|
||||
$customers = app('MMF\FreescoutRestrictedCustomers\Http\Controllers\ConversationsController')->searchCustomers($request, $user);
|
||||
|
||||
$response['status'] = 'success';
|
||||
|
||||
|
|
Loading…
Reference in a new issue