[
MAINHACK
]
Mail Test
BC
Config Scan
HOME
Create...
New File
New Folder
Viewing / Editing File: Clients.php
<?php /** -------------------------------------------------------------------------------- * This controller manages all the business logic for clients * * @package Grow CRM * @author NextLoop *----------------------------------------------------------------------------------*/ namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\Http\Requests\Clients\ClientStoreValidation; use App\Http\Responses\Clients\CommonResponse; use App\Http\Responses\Clients\CreateResponse; use App\Http\Responses\Clients\DestroyResponse; use App\Http\Responses\Clients\DetailsResponse; use App\Http\Responses\Clients\EditLogoResponse; use App\Http\Responses\Clients\EditResponse; use App\Http\Responses\Clients\IndexResponse; use App\Http\Responses\Clients\PinningResponse; use App\Http\Responses\Clients\ShowDynamicResponse; use App\Http\Responses\Clients\ShowResponse; use App\Http\Responses\Clients\StoreResponse; use App\Http\Responses\Clients\UpdateDetailsResponse; use App\Http\Responses\Clients\UpdateOwnerResponse; use App\Http\Responses\Clients\UpdateResponse; use App\Repositories\AttachmentRepository; use App\Repositories\CategoryRepository; use App\Repositories\ClientRepository; use App\Repositories\CustomFieldsRepository; use App\Repositories\DestroyRepository; use App\Repositories\PinnedRepository; use App\Repositories\TagRepository; use App\Repositories\UserRepository; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; use Validator; class Clients extends Controller { /** * The users repository instance. */ protected $userrepo; /** * The clients repository instance. */ protected $clientrepo; /** * The tags repository instance. */ protected $tagrepo; /** * The customrepo repository instance. */ protected $customrepo; public function __construct(UserRepository $userrepo, ClientRepository $clientrepo, TagRepository $tagrepo, CustomFieldsRepository $customrepo) { //parent parent::__construct(); //authenticated $this->middleware('auth'); $this->middleware('clientsMiddlewareIndex')->only([ 'index', 'update', 'store', ]); $this->middleware('clientsMiddlewareEdit')->only([ 'edit', 'update', 'updateDescription', 'changeAccountOwner', 'changeAccountOwnerUpdate', ]); $this->middleware('clientsMiddlewareCreate')->only([ 'create', 'store', ]); $this->middleware('clientsMiddlewareDestroy')->only(['destroy']); $this->middleware('clientsMiddlewareShow')->only([ 'show', 'details', 'updateDescription', 'emailCompose', 'emailSend', 'togglePinning', ]); //dependencies $this->userrepo = $userrepo; $this->clientrepo = $clientrepo; $this->tagrepo = $tagrepo; $this->customrepo = $customrepo; } /** * Display a listing of clients * @param object CategoryRepository category repository * @return blade view | ajax view */ public function index(CategoryRepository $categoryrepo) { //basic page settings $page = $this->pageSettings('clients'); //get clients $clients = $this->clientrepo->search(); //client categories $categories = $categoryrepo->get('client'); //get tags $tags = $this->tagrepo->getByType('client'); //reponse payload $payload = [ 'page' => $page, 'stats' => $this->statsWidget(), 'clients' => $clients, 'categories' => $categories, 'tags' => $tags, 'fields' => $this->getCustomFields(), ]; //show views return new IndexResponse($payload); } /** * Show the form for creating a new client * @return \Illuminate\Http\Response */ public function create(CategoryRepository $categoryrepo) { //page settings $page = $this->pageSettings('create'); //get tags $tags = $this->tagrepo->getByType('client'); //get custom fields //reponse payload $payload = [ 'page' => $page, 'tags' => $tags, 'categories' => $categoryrepo->get('client'), 'fields' => $this->getCustomFields(), ]; //show the form return new CreateResponse($payload); } /** * Store a newly created client in storage. * @return \Illuminate\Http\Response */ public function store(ClientStoreValidation $request) { //custom field validation if ($messages = $this->customFieldValidationFailed()) { abort(409, $messages); } //save the client first [API] if (!$client_id = $this->clientrepo->create([ 'send_email' => 'yes', 'return' => 'id', ])) { abort(409); } //get the client object (friendly for rendering in blade template) $clients = $this->clientrepo->search($client_id); //counting rows $rows = $this->clientrepo->search(); $count = $rows->total(); //reponse payload $payload = [ 'clients' => $clients, 'count' => $count, ]; //process reponse return new StoreResponse($payload); } /** * Display the specified client * @param int $id client id * @return \Illuminate\Http\Response */ public function show($id) { //get the client $clients = $this->clientrepo->search($id); //client $client = $clients->first(); //owner - primary contact $owner = \App\Models\User::Where('clientid', $id) ->Where('account_owner', 'yes') ->first(); //page settings $page = $this->pageSettings('client', $client); //get tags $tags_resource = $this->tagrepo->getByResource('client', $id); $tags_user = $this->tagrepo->getByType('client'); $tags = $tags_resource->merge($tags_user); $tags = $tags->unique('tag_title'); //set dynamic url for use in template switch (request()->segment(3)) { case 'files': case 'invoices': case 'expenses': case 'payments': case 'timesheets': case 'notes': case 'tickets': case 'contacts': case 'projects': $sections = request()->segment(3); $section = rtrim($sections, 's'); $page['dynamic_url'] = url($sections . '?source=ext&' . $section . 'resource_type=client&' . $section . 'resource_id=' . $client->client_id); break; default: $page['dynamic_url'] = url("timeline/client?request_source=client&source=ext&timelineclient_id=$id&page=1"); break; } //reponse payload $payload = [ 'page' => $page, 'client' => $client, 'tags' => $tags, 'owner' => $owner, 'fields' => $this->getCustomFields(), ]; //response return new ShowResponse($payload); } /** * Display the specified client. * @param int $id id of the client * @return \Illuminate\Http\Response */ public function showDynamic($id) { //get the client $clients = $this->clientrepo->search($id); //client $client = $clients->first(); //owner - primary contact $owner = \App\Models\User::Where('clientid', $id) ->Where('account_owner', 'yes') ->first(); //page settings $page = $this->pageSettings('client', $client); //set dynamic url for use in template switch (request()->segment(3)) { case 'invoices': case 'expenses': case 'estimates': case 'payments': case 'timesheets': case 'notes': case 'tickets': case 'contacts': case 'projects': $sections = request()->segment(3); $section = rtrim($sections, 's'); $page['dynamic_url'] = url($sections . '?source=ext&' . $section . 'resource_type=client&' . $section . 'resource_id=' . $client->client_id); break; case 'project-files': $page['dynamic_url'] = url('files?source=ext&fileresource_type=project&filter_file_clientid=' . $client->client_id); break; case 'client-files': $page['dynamic_url'] = url('files?source=ext&fileresource_type=client&fileresource_id=' . $client->client_id); break; case 'details': $page['dynamic_url'] = url('clients/' . $client->client_id . '/client-details'); break; default: $page['dynamic_url'] = url("timeline/client?request_source=client&source=ext&timelineclient_id=$id&page=1"); break; } //get tags $tags_resource = $this->tagrepo->getByResource('client', $id); $tags_user = $this->tagrepo->getByType('client'); $tags = $tags_resource->merge($tags_user); $tags = $tags->unique('tag_title'); //reponse payload $payload = [ 'page' => $page, 'client' => $client, 'owner' => $owner, 'tags' => $tags, ]; //response return new ShowDynamicResponse($payload); } /** * Show the form for editing the specified client. * @param int $id client id * @return \Illuminate\Http\Response */ public function edit(CategoryRepository $categoryrepo, $id) { //page settings $page = $this->pageSettings('edit'); //get the client if (!$client = $this->clientrepo->search($id)) { abort(409); } //get client tags and users tags $tags_resource = $this->tagrepo->getByResource('client', $id); $tags_user = $this->tagrepo->getByType('client'); $tags = $tags_resource->merge($tags_user); $tags = $tags->unique('tag_title'); //clients $client = $client->first(); //reponse payload $payload = [ 'page' => $page, 'client' => $client, 'categories' => $categoryrepo->get('client'), 'tags' => $tags, 'fields' => $this->getCustomFields($client), ]; //response return new EditResponse($payload); } /** * Update the specified client in storage. * @param int $id client id * @return \Illuminate\Http\Response */ public function update($id) { //validate the form $validator = Validator::make(request()->all(), [ 'client_company_name' => 'required', ]); //validation errors if ($validator->fails()) { $errors = $validator->errors(); $messages = ''; foreach ($errors->all() as $message) { $messages .= "<li>$message</li>"; } abort(409, $messages); } //custom field validation if ($messages = $this->customFieldValidationFailed()) { abort(409, $messages); } //update client if (!$this->clientrepo->update($id)) { abort(409); } //delete & update tags if (auth()->user()->is_team) { $this->tagrepo->delete('client', $id); $this->tagrepo->add('client', $id); } //if we are suspending the client - logout all users if (request('client_status') == 'suspended') { if ($users = \App\Models\User::Where('clientid', $id)->get()) { //each user - logout foreach ($users as $user) { \App\Models\Session::Where('user_id', $user->id)->delete(); } } } //client $clients = $this->clientrepo->search($id); //reponse payload $payload = [ 'clients' => $clients, ]; //generate a response return new UpdateResponse($payload); } /** * Remove the specified client from storage. * @param object DestroyRepository instance of the repository * @param int $id client id * @return \Illuminate\Http\Response */ public function destroy(DestroyRepository $destroyrepo, $id) { //delete client $destroyrepo->destroyClient($id); //reponse payload $payload = [ 'client_id' => $id, ]; //generate a response return new DestroyResponse($payload); } /** * get all custom fields for clients * - if they are being used in the 'edit' modal form, also get the current data * from the cliet record. Store this temporarily in '$field->customfields_name' * this will then be used to prefill data in the custom fields * @param model client model - only when showing the edit modal form * @return collection */ public function getCustomFields($obj = '') { //set typs request()->merge([ 'customfields_type' => 'clients', 'filter_show_standard_form_status' => 'enabled', 'filter_field_status' => 'enabled', 'sort_by' => 'customfields_position', ]); //show all fields config(['settings.custom_fields_display_limit' => 1000]); //get fields $fields = $this->customrepo->search(); //when in editing view - get current value that is stored for this custom field if ($obj instanceof \App\Models\Client) { foreach ($fields as $field) { $field->current_value = $obj[$field->customfields_name]; } } return $fields; } /** * Returns false when all is ok * @return \Illuminate\Http\Response */ public function customFieldValidationFailed() { //custom field validation $fields = \App\Models\CustomField::Where('customfields_type', 'clients')->get(); $errors = ''; foreach ($fields as $field) { if ($field->customfields_status == 'enabled' && $field->customfields_standard_form_status == 'enabled' && $field->customfields_required == 'yes') { if (request($field->customfields_name) == '') { $errors .= '<li>' . $field->customfields_title . ' - ' . __('lang.is_required') . '</li>'; } } } //return if ($errors != '') { return $errors; } else { return false; } } /** * Return ajax details for project * @return \Illuminate\Http\Response */ public function profile() { //get client details $client = [ 'client_id' => random_int(1, 999), 'description' => 'hello world', ]; //set the view $html = view('pages/client/components/tabs/profile', compact('client'))->render(); //[action options] replace|append|prepend $ajax['dom_html'][] = [ 'selector' => '#embed-content-container', 'action' => 'replace', 'value' => $html, ]; //ajax response & view return response()->json($ajax); } /** * Show the form for editing the specified clients logo * @return \Illuminate\Http\Response */ public function logo() { //is this client or admin if (auth()->user()->type == 'client') { $client_id = auth()->user()->clientid; } else { $client_id = request('client_id'); } //reponse payload $payload = [ 'client_id' => $client_id, ]; //response return new EditLogoResponse($payload); } /** * Update the specified client logo in storage. * @param int $id client id * @return \Illuminate\Http\Response */ public function updateLogo(AttachmentRepository $attachmentrepo) { //validate input $data = [ 'directory' => request('logo_directory'), 'filename' => request('logo_filename'), ]; //process and save to db if (!$attachmentrepo->processClientLogo($data)) { abort(409); } //sanity check if (auth()->user()->type == 'client') { $clientid = auth()->user()->clientid; } else { $clientid = request('client_id'); } //update avatar if (!$this->clientrepo->updateLogo(request('client_id'))) { abort(409); } //reponse payload $payload = [ 'type' => 'upload-logo', 'client_id' => $clientid, ]; //generate a response return new CommonResponse($payload); } /** * Return ajax details for client * @param int $id client id * @return \Illuminate\Http\Response */ public function details($id) { //get the client $clients = $this->clientrepo->search($id); //get tags $tags = $this->tagrepo->getByResource('client', $id); //not found if (!$client = $clients->first()) { abort(409, __('lang.client_not_found')); } //reponse payload $payload = [ 'page' => $this->pageSettings('client', $client), 'client' => $client, 'tags' => $tags, ]; //response return new DetailsResponse($payload); } /** * update client description and also the tags * @return \Illuminate\Http\Response */ public function updateDescription() { //get the client $client = \App\Models\client::Where('client_id', request()->route('client'))->first(); //update description $client->client_description = request('description'); //save $client->save(); //delete & update tags $this->tagrepo->delete('client', $client->client_id); $this->tagrepo->add('client', $client->client_id); //get tags $tags = $this->tagrepo->getByResource('client', $client->client_id); //reponse payload $payload = [ 'page' => $this->pageSettings('client', $client), 'client' => $client, 'tags' => $tags, ]; //response return new UpdateDetailsResponse($payload); } /** * show the form to edit a resource * * @return \Illuminate\Http\Response */ public function changeAccountOwner($id) { //get the foo if (!$users = \App\Models\User::Where('clientid', $id)->orderBy('first_name', 'DESC')->get()) { abort(409); } //reponse payload $payload = [ 'response' => 'show-form', 'page' => $this->pageSettings(), 'users' => $users, ]; //response return new UpdateOwnerResponse($payload); } /** * update account owner * * @return \Illuminate\Http\Response */ public function changeAccountOwnerUpdate($id) { //validate if (!request()->filled('user_id')) { abort(409, __('lang.fill_in_all_required_fields')); } //get the user if (!$user = \App\Models\User::Where('id', request('user_id'))->Where('clientid', $id)->first()) { abort(404); } //reset existing account owner \App\Models\User::where('clientid', $id)->update(['account_owner' => 'no']); //set new owner $user->account_owner = 'yes'; $user->save(); //reponse payload $payload = [ 'client_id' => $id, 'response' => 'update-owner', 'page' => $this->pageSettings(), ]; //response return new UpdateOwnerResponse($payload); } /** * toggle pinned state of clients * * @return \Illuminate\Http\Response */ public function togglePinning(PinnedRepository $pinrepo, $id) { //toggle pin $status = $pinrepo->togglePinned($id, 'client'); //reponse payload $payload = [ 'client_id' => $id, 'status' => $status, ]; //generate a response return new PinningResponse($payload); } /** * basic page setting for this section of the app * @param string $section page section (optional) * @param array $data any other data (optional) * @return array */ private function pageSettings($section = '', $data = []) { // //common settings $page = [ 'crumbs' => [ __('lang.clients'), ], 'crumbs_special_class' => 'list-pages-crumbs', 'page' => 'clients', 'no_results_message' => __('lang.no_results_found'), 'mainmenu_customers' => 'active', 'mainmenu_clients' => 'active', 'submenu_customers' => 'active', 'tabmenu_timeline' => 'active', 'sidepanel_id' => 'sidepanel-filter-clients', 'dynamic_search_url' => url('clients/search?action=search&clientresource_id=' . request('clientresource_id') . '&clientresource_type=' . request('clientresource_type')), 'add_button_classes' => '', 'load_more_button_route' => 'clients', 'source' => 'list', ]; //default modal settings (modify for sepecif sections) $page += [ 'add_modal_title' => __('lang.add_client'), 'add_modal_create_url' => url('clients/create?clientresource_id=' . request('clientresource_id') . '&clientresource_type=' . request('clientresource_type')), 'add_modal_action_url' => url('clients?clientresource_id=' . request('clientresource_id') . '&clientresource_type=' . request('clientresource_type')), 'add_modal_action_ajax_class' => '', 'add_modal_action_ajax_loading_target' => 'commonModalBody', 'add_modal_action_method' => 'POST', ]; //projects list page if ($section == 'clients') { $page += [ 'meta_title' => __('lang.clients'), 'heading' => __('lang.clients'), 'mainmenu_customers' => 'active', ]; return $page; } //client page if ($section == 'client') { //adjust $page['page'] = 'client'; //add $page += [ 'crumbs' => [ __('lang.clients'), ], 'meta_title' => __('lang.client') . ' - ' . $data->client_company_name, 'heading' => __('lang.client') . ' - ' . $data->client_company_name, 'project_id' => request()->segment(2), 'source_for_filter_panels' => 'ext', ]; //ajax loading and tabs return $page; } //create new resource if ($section == 'create') { $page += [ 'section' => 'create', ]; return $page; } //edit new resource if ($section == 'edit') { $page += [ 'section' => 'edit', ]; return $page; } //return return $page; } /** * impersonate a client * * @param int $id client id * @return \Illuminate\Http\Response */ public function ImpersonateClient($id) { //get the client if (!$client = \App\Models\Client::Where('client_id', $id)->first()) { abort(409, __('lang.client_not_found')); } //admin only if (!auth()->user()->is_admin) { abort(403); } //get the primary account owner from User model - where account_owner = yes if (!$owner = \App\Models\User::Where('clientid', $id) ->Where('account_owner', 'yes') ->first()) { abort(409, __('lang.client_owner_not_found')); } //logout admin auth()->logout(); //authenticate this user auth()->loginUsingId($owner->id); //redirect to home $jsondata['redirect_url'] = url('/home'); //ajax response return response()->json($jsondata); } /** * data for the stats widget * @return array */ private function statsWidget($data = array()) { //get expense (all rows - for stats etc) $count_all_projects = $this->clientrepo->search('', ['stats' => 'count_all_projects']); $count_clients = $this->clientrepo->search('', ['stats' => 'count_clients']); $sum_payments = $this->clientrepo->search('', ['stats' => 'sum_payments']); $sum_invoices = $this->clientrepo->search('', ['stats' => 'sum_invoices']); //default values $stats = [ [ 'value' => $count_clients ?? 0, 'title' => __('lang.clients'), 'percentage' => '0%', 'color' => 'bg-success', ], [ 'value' => $count_all_projects ?? 0, 'title' => __('lang.projects'), 'percentage' => '0%', 'color' => 'bg-info', ], [ 'value' => runtimeMoneyFormat($sum_invoices), 'title' => __('lang.invoices'), 'percentage' => '0%', 'color' => 'bg-primary', ], [ 'value' => runtimeMoneyFormat($sum_payments), 'title' => __('lang.payments'), 'percentage' => '0%', 'color' => 'bg-inverse', ], ]; //calculations - set real values if (!empty($data)) { $stats[0]['value'] = '1'; $stats[0]['percentage'] = '10%'; $stats[1]['value'] = '2'; $stats[1]['percentage'] = '20%'; $stats[2]['value'] = '3'; $stats[2]['percentage'] = '30%'; $stats[3]['value'] = '4'; $stats[3]['percentage'] = '40%'; } //return return $stats; } }
Save Changes
Cancel / Back
Close ×
Server Info
Hostname: server1.winmanyltd.com
Server IP: 203.161.60.52
PHP Version: 8.3.27
Server Software: Apache
System: Linux server1.winmanyltd.com 4.18.0-553.22.1.el8_10.x86_64 #1 SMP Tue Sep 24 05:16:59 EDT 2024 x86_64
HDD Total: 117.98 GB
HDD Free: 59.81 GB
Domains on IP: N/A (Requires external lookup)
System Features
Safe Mode:
Off
disable_functions:
None
allow_url_fopen:
On
allow_url_include:
Off
magic_quotes_gpc:
Off
register_globals:
Off
open_basedir:
None
cURL:
Enabled
ZipArchive:
Enabled
MySQLi:
Enabled
PDO:
Enabled
wget:
Yes
curl (cmd):
Yes
perl:
Yes
python:
Yes (py3)
gcc:
Yes
pkexec:
Yes
git:
Yes
User Info
Username: eliosofonline
User ID (UID): 1002
Group ID (GID): 1003
Script Owner UID: 1002
Current Dir Owner: 1002