activities_controller.php
1 year ago
auth_controller.php
1 year ago
booking_form_settings_controller.php
1 year ago
bookings_controller.php
1 year ago
calendars_controller.php
1 year ago
carts_controller.php
1 year ago
controller.php
1 year ago
customer_cabinet_controller.php
1 year ago
customers_controller.php
1 year ago
dashboard_controller.php
1 year ago
default_agent_controller.php
1 year ago
events_controller.php
1 year ago
form_fields_controller.php
1 year ago
integrations_controller.php
1 year ago
invoices_controller.php
1 year ago
manage_booking_by_key_controller.php
1 year ago
manage_order_by_key_controller.php
1 year ago
notifications_controller.php
1 year ago
orders_controller.php
1 year ago
pro_controller.php
1 year ago
process_jobs_controller.php
1 year ago
processes_controller.php
1 year ago
search_controller.php
1 year ago
services_controller.php
1 year ago
settings_controller.php
1 year ago
steps_controller.php
1 year ago
stripe_connect_controller.php
1 year ago
support_topics_controller.php
1 year ago
todos_controller.php
1 year ago
transactions_controller.php
1 year ago
wizard_controller.php
1 year ago
customers_controller.php
370 lines
| 1 | <?php |
| 2 | if ( ! defined( 'ABSPATH' ) ) { |
| 3 | exit; // Exit if accessed directly. |
| 4 | } |
| 5 | |
| 6 | |
| 7 | if ( ! class_exists( 'OsCustomersController' ) ) : |
| 8 | |
| 9 | |
| 10 | class OsCustomersController extends OsController { |
| 11 | |
| 12 | function __construct(){ |
| 13 | parent::__construct(); |
| 14 | |
| 15 | |
| 16 | $this->views_folder = LATEPOINT_VIEWS_ABSPATH . 'customers/'; |
| 17 | $this->vars['page_header'] = OsMenuHelper::get_menu_items_by_id('customers'); |
| 18 | $this->vars['breadcrumbs'][] = array('label' => __('Customers', 'latepoint'), 'link' => OsRouterHelper::build_link(OsRouterHelper::build_route_name('customers', 'index') ) ); |
| 19 | } |
| 20 | |
| 21 | public function destroy(){ |
| 22 | if(filter_var($this->params['id'], FILTER_VALIDATE_INT)){ |
| 23 | $this->check_nonce('destroy_customer_'.$this->params['id']); |
| 24 | $customer = new OsCustomerModel($this->params['id']); |
| 25 | if($customer->delete()){ |
| 26 | $status = LATEPOINT_STATUS_SUCCESS; |
| 27 | $response_html = __('Customer Removed', 'latepoint'); |
| 28 | }else{ |
| 29 | $status = LATEPOINT_STATUS_ERROR; |
| 30 | $response_html = __('Error Removing Customer', 'latepoint'); |
| 31 | } |
| 32 | }else{ |
| 33 | $status = LATEPOINT_STATUS_ERROR; |
| 34 | $response_html = __('Error Removing Customer', 'latepoint'); |
| 35 | } |
| 36 | |
| 37 | if($this->get_return_format() == 'json'){ |
| 38 | $this->send_json(array('status' => $status, 'message' => $response_html)); |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | |
| 43 | public function view_customer_log(){ |
| 44 | |
| 45 | $activities = new OsActivityModel(); |
| 46 | $activities = $activities->where(['customer_id' => absint($this->params['customer_id'])])->order_by('id desc')->get_results_as_models(); |
| 47 | |
| 48 | $customer = new OsCustomerModel($this->params['customer_id']); |
| 49 | |
| 50 | $this->vars['customer'] = $customer; |
| 51 | $this->vars['activities'] = $activities; |
| 52 | |
| 53 | $this->format_render(__FUNCTION__); |
| 54 | } |
| 55 | |
| 56 | |
| 57 | public function quick_new(){ |
| 58 | $customer = new OsCustomerModel(); |
| 59 | |
| 60 | $this->vars['customer'] = $customer; |
| 61 | |
| 62 | $this->format_render('quick_edit'); |
| 63 | } |
| 64 | |
| 65 | public function quick_edit(){ |
| 66 | if(!filter_var($this->params['customer_id'], FILTER_VALIDATE_INT)) $this->access_not_allowed(); |
| 67 | $customer = new OsCustomerModel($this->params['customer_id']); |
| 68 | |
| 69 | $this->vars['customer'] = $customer; |
| 70 | |
| 71 | $this->format_render(__FUNCTION__); |
| 72 | } |
| 73 | |
| 74 | |
| 75 | public function inline_edit_form(){ |
| 76 | $selected_customer = new OsCustomerModel(); |
| 77 | if(isset($this->params['customer_id'])){ |
| 78 | $selected_customer->load_by_id($this->params['customer_id']); |
| 79 | } |
| 80 | $this->vars['default_fields_for_customer'] = OsSettingsHelper::get_default_fields_for_customer(); |
| 81 | $this->vars['selected_customer'] = $selected_customer; |
| 82 | $this->format_render(__FUNCTION__); |
| 83 | } |
| 84 | |
| 85 | public function set_as_guest(){ |
| 86 | if(filter_var($this->params['id'], FILTER_VALIDATE_INT)){ |
| 87 | $customer = new OsCustomerModel($this->params['id']); |
| 88 | if($customer->update_attributes(['is_guest' => true])){ |
| 89 | $status = LATEPOINT_STATUS_SUCCESS; |
| 90 | $response_html = __('Customer is now allowed to book without password', 'latepoint'); |
| 91 | }else{ |
| 92 | $status = LATEPOINT_STATUS_ERROR; |
| 93 | $response_html = $customer->get_error_messages(); |
| 94 | } |
| 95 | }else{ |
| 96 | $status = LATEPOINT_STATUS_ERROR; |
| 97 | $response_html = __('Error setting customer as guest', 'latepoint'); |
| 98 | } |
| 99 | |
| 100 | if($this->get_return_format() == 'json'){ |
| 101 | $this->send_json(array('status' => $status, 'message' => $response_html)); |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | /* |
| 106 | Edit customer |
| 107 | */ |
| 108 | |
| 109 | public function edit_form(){ |
| 110 | $this->vars['page_header'] = __('Edit Customer', 'latepoint'); |
| 111 | $this->vars['breadcrumbs'][] = array('label' => __('Edit Customer', 'latepoint'), 'link' => false ); |
| 112 | |
| 113 | if(filter_var($this->params['id'], FILTER_VALIDATE_INT)){ |
| 114 | // check if allowed to access |
| 115 | $customer = new OsCustomerModel(); |
| 116 | $customer = $customer->where([LATEPOINT_TABLE_CUSTOMERS.'.id' => absint($this->params['id'])])->filter_allowed_records()->set_limit(1)->get_results_as_models(); |
| 117 | $this->vars['customer'] = $customer; |
| 118 | $this->vars['wp_users_for_select'] = OsWpUserHelper::get_wp_users_for_select(); |
| 119 | } |
| 120 | |
| 121 | $this->format_render(__FUNCTION__); |
| 122 | } |
| 123 | |
| 124 | |
| 125 | public function query_for_booking_form(){ |
| 126 | $query = trim($this->params['query']); |
| 127 | $sql_query = '%'.$query.'%'; |
| 128 | $query = $this->params['query']; |
| 129 | $customers = new OsCustomerModel(); |
| 130 | $this->vars['query'] = $query; |
| 131 | $this->vars['customers'] = $customers->where(array('OR' => array('CONCAT (first_name, " ", last_name) LIKE ' => $sql_query, 'email LIKE' => $sql_query, 'phone LIKE' => $sql_query)))->set_limit(20)->order_by('first_name asc, last_name asc')->get_results_as_models(); |
| 132 | |
| 133 | $this->format_render(__FUNCTION__); |
| 134 | } |
| 135 | |
| 136 | |
| 137 | /* |
| 138 | Create customer |
| 139 | */ |
| 140 | |
| 141 | public function create(){ |
| 142 | $this->check_nonce('new_customer'); |
| 143 | $customer = new OsCustomerModel(); |
| 144 | $customer->set_data($this->params['customer']); |
| 145 | if($customer->save()){ |
| 146 | // translators: %s is the html of a customer edit link |
| 147 | $response_html = sprintf(__('Customer Created ID: %s', 'latepoint'), '<span class="os-notification-link" '.OsCustomerHelper::quick_customer_btn_html($customer->id).'>'.$customer->id.'</span>'); |
| 148 | $status = LATEPOINT_STATUS_SUCCESS; |
| 149 | do_action('latepoint_customer_created', $customer); |
| 150 | }else{ |
| 151 | $response_html = $customer->get_error_messages(); |
| 152 | $status = LATEPOINT_STATUS_ERROR; |
| 153 | } |
| 154 | if($this->get_return_format() == 'json'){ |
| 155 | $this->send_json(array('status' => $status, 'message' => $response_html)); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | |
| 160 | /* |
| 161 | Update customer |
| 162 | */ |
| 163 | |
| 164 | public function update(){ |
| 165 | if(isset($this->params['customer']['id']) && filter_var($this->params['customer']['id'], FILTER_VALIDATE_INT)){ |
| 166 | $this->check_nonce('edit_customer_'.$this->params['customer']['id']); |
| 167 | $customer = new OsCustomerModel($this->params['customer']['id']); |
| 168 | if(!$customer || !OsRolesHelper::can_user_make_action_on_model_record($customer, 'edit')){ |
| 169 | $response_html = __('Access Restricted', 'latepoint'); |
| 170 | $status = LATEPOINT_STATUS_ERROR; |
| 171 | }else{ |
| 172 | $old_customer_data = $customer->get_data_vars(); |
| 173 | $customer->set_data($this->params['customer']); |
| 174 | if($customer->save()){ |
| 175 | // translators: %s is the html of a customer edit link |
| 176 | $response_html = sprintf(__('Customer Updated ID: %s', 'latepoint'), '<span class="os-notification-link" '.OsCustomerHelper::quick_customer_btn_html($customer->id).'>'.$customer->id.'</span>'); |
| 177 | $status = LATEPOINT_STATUS_SUCCESS; |
| 178 | do_action('latepoint_customer_updated', $customer, $old_customer_data); |
| 179 | }else{ |
| 180 | $response_html = $customer->get_error_messages(); |
| 181 | $status = LATEPOINT_STATUS_ERROR; |
| 182 | } |
| 183 | } |
| 184 | }else{ |
| 185 | $response_html = __('Invalid customer ID', 'latepoint'); |
| 186 | $status = LATEPOINT_STATUS_ERROR; |
| 187 | } |
| 188 | if($this->get_return_format() == 'json'){ |
| 189 | $this->send_json(array('status' => $status, 'message' => $response_html)); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | public function mini_profile(){ |
| 194 | if(filter_var($this->params['customer_id'], FILTER_VALIDATE_INT)){ |
| 195 | $customer = new OsCustomerModel($this->params['customer_id']); |
| 196 | $this->vars['upcoming_booking'] = $customer->get_future_bookings(1, true); |
| 197 | $this->vars['customer'] = $customer; |
| 198 | |
| 199 | |
| 200 | $pie_labels = []; |
| 201 | $pie_colors = []; |
| 202 | $pie_values = []; |
| 203 | $pie_chart_data = OsBookingHelper::get_stat('bookings', ['group_by' => 'status', 'customer_id' => $customer->id]); |
| 204 | $colors = ['#2752E4', '#C066F1', '#26B7DD', '#E8C634', '#19CED6', '#2FEAA3', '#252a3e', '#8d87a5', '#b9b784']; |
| 205 | $status_colors = [ |
| 206 | LATEPOINT_BOOKING_STATUS_APPROVED => '#35d893', |
| 207 | LATEPOINT_BOOKING_STATUS_PENDING => '#e6b935', |
| 208 | LATEPOINT_BOOKING_STATUS_PAYMENT_PENDING => '#4ca4ef', |
| 209 | LATEPOINT_BOOKING_STATUS_CANCELLED => '#f1585d' |
| 210 | ]; |
| 211 | $i = 0; |
| 212 | foreach($pie_chart_data as $pie_data){ |
| 213 | $pie_labels[] = $pie_data['status']; |
| 214 | $pie_colors[] = isset($status_colors[$pie_data['status']]) ? $status_colors[$pie_data['status']] : $colors[$i]; |
| 215 | $pie_values[] = $pie_data['stat']; |
| 216 | $i++; |
| 217 | } |
| 218 | |
| 219 | $this->vars['pie_chart_data'] = ['labels' => $pie_labels, 'colors' => $pie_colors, 'values' => $pie_values]; |
| 220 | |
| 221 | |
| 222 | |
| 223 | $this->set_layout('none'); |
| 224 | $response_html = $this->format_render_return(__FUNCTION__); |
| 225 | }else{ |
| 226 | $status = LATEPOINT_STATUS_ERROR; |
| 227 | $response_html = __('Error Accessing Customer', 'latepoint'); |
| 228 | } |
| 229 | |
| 230 | if($this->get_return_format() == 'json'){ |
| 231 | $this->send_json(array('status' => $status, 'message' => $response_html)); |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | public function connect_all_to_wp_users(){ |
| 236 | $customers = new OsCustomerModel(); |
| 237 | $customers = $customers->where(['wordpress_user_id' => ['OR' => [0, 'IS NULL']]])->get_results_as_models(); |
| 238 | if($customers){ |
| 239 | foreach($customers as $customer){ |
| 240 | $wp_user_id = OsCustomerHelper::create_wp_user_for_customer($customer); |
| 241 | if($wp_user_id) $customer->update_attributes(['wordpress_user_id' => $wp_user_id]); |
| 242 | } |
| 243 | } |
| 244 | if($this->get_return_format() == 'json'){ |
| 245 | $this->send_json(array('status' => LATEPOINT_STATUS_SUCCESS, 'message' => __('Customers Connected', 'latepoint'))); |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | public function disconnect_from_wp_user(){ |
| 250 | $customer_id = $this->params['customer_id']; |
| 251 | $customer = new OsCustomerModel(); |
| 252 | $customer = $customer->where(['id' => $customer_id])->set_limit(1)->get_results_as_models(); |
| 253 | if($customer){ |
| 254 | $customer->update_attributes(['wordpress_user_id' => NULL]); |
| 255 | } |
| 256 | if($this->get_return_format() == 'json'){ |
| 257 | $this->send_json(array('status' => LATEPOINT_STATUS_SUCCESS, 'message' => __('Customer Disconnected', 'latepoint'))); |
| 258 | } |
| 259 | } |
| 260 | |
| 261 | public function connect_to_wp_user(){ |
| 262 | $customer_id = $this->params['customer_id']; |
| 263 | $customer = new OsCustomerModel(); |
| 264 | $customer = $customer->where(['id' => $customer_id])->set_limit(1)->get_results_as_models(); |
| 265 | if($customer && !$customer->wordpress_user_id){ |
| 266 | $wp_user = OsCustomerHelper::create_wp_user_for_customer($customer); |
| 267 | } |
| 268 | if($this->get_return_format() == 'json'){ |
| 269 | $this->send_json(array('status' => LATEPOINT_STATUS_SUCCESS, 'message' => __('Customer Connected', 'latepoint'))); |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | |
| 274 | public function index(){ |
| 275 | |
| 276 | $this->vars['page_header'] = false; |
| 277 | $page_number = isset($this->params['page_number']) ? $this->params['page_number'] : 1; |
| 278 | $per_page = OsSettingsHelper::get_number_of_records_per_page(); |
| 279 | $offset = ($page_number > 1) ? (($page_number - 1) * $per_page) : 0; |
| 280 | |
| 281 | |
| 282 | $customers = new OsCustomerModel(); |
| 283 | $query_args = []; |
| 284 | |
| 285 | $filter = isset($this->params['filter']) ? $this->params['filter'] : false; |
| 286 | |
| 287 | // TABLE SEARCH FILTERS |
| 288 | if($filter){ |
| 289 | if($filter['id']) $query_args['id'] = $filter['id']; |
| 290 | if($filter['registration_date_from'] && $filter['registration_date_to']){ |
| 291 | $query_args[LATEPOINT_TABLE_CUSTOMERS.'.created_at >='] = $filter['registration_date_from']; |
| 292 | $query_args[LATEPOINT_TABLE_CUSTOMERS.'.created_at <='] = $filter['registration_date_to']; |
| 293 | } |
| 294 | if($filter['customer']){ |
| 295 | $query_args['concat_ws(" ", '.LATEPOINT_TABLE_CUSTOMERS.'.first_name,'.LATEPOINT_TABLE_CUSTOMERS.'.last_name) LIKE'] = '%'.$filter['customer'].'%'; |
| 296 | $this->vars['customer_name_query'] = $filter['customer']; |
| 297 | } |
| 298 | if($filter['phone']){ |
| 299 | $query_args['phone LIKE'] = '%'.$filter['phone'].'%'; |
| 300 | $this->vars['phone_query'] = $filter['phone']; |
| 301 | } |
| 302 | if($filter['email']){ |
| 303 | $query_args['email LIKE'] = '%'.$filter['email'].'%'; |
| 304 | $this->vars['email_query'] = $filter['email']; |
| 305 | } |
| 306 | } |
| 307 | |
| 308 | |
| 309 | // OUTPUT CSV IF REQUESTED |
| 310 | if(isset($this->params['download']) && $this->params['download'] == 'csv'){ |
| 311 | $csv_filename = 'customers_'.OsUtilHelper::random_text(); |
| 312 | |
| 313 | header("Content-Type: text/csv"); |
| 314 | header("Content-Disposition: attachment; filename={$csv_filename}.csv"); |
| 315 | |
| 316 | $labels_row = [ __('ID', 'latepoint'), |
| 317 | __('Name', 'latepoint'), |
| 318 | __('Phone', 'latepoint'), |
| 319 | __('Email', 'latepoint'), |
| 320 | __('Total Appointments', 'latepoint'), |
| 321 | __('Registered On', 'latepoint') ]; |
| 322 | |
| 323 | |
| 324 | $customers_data = []; |
| 325 | $customers_data[] = $labels_row; |
| 326 | |
| 327 | |
| 328 | $customers_arr = $customers->where($query_args)->filter_allowed_records()->order_by('id desc')->get_results_as_models(); |
| 329 | if($customers_arr){ |
| 330 | foreach($customers_arr as $customer){ |
| 331 | $values_row = [ $customer->id, |
| 332 | $customer->full_name, |
| 333 | $customer->phone, |
| 334 | $customer->email, |
| 335 | $customer->total_bookings_count, |
| 336 | $customer->formatted_created_date()]; |
| 337 | $values_row = apply_filters('latepoint_customer_row_for_csv_export', $values_row, $customer, $this->params); |
| 338 | $customers_data[] = $values_row; |
| 339 | } |
| 340 | } |
| 341 | $customers_data = apply_filters('latepoint_customers_data_for_csv_export', $customers_data, $this->params); |
| 342 | OsCSVHelper::array_to_csv($customers_data); |
| 343 | return; |
| 344 | } |
| 345 | |
| 346 | $customers->where($query_args)->filter_allowed_records(); |
| 347 | $count_total_customers = clone $customers; |
| 348 | |
| 349 | $total_customers = $count_total_customers->count(); |
| 350 | $total_pages = ceil($total_customers / $per_page); |
| 351 | |
| 352 | $this->vars['customers'] = $customers->set_limit($per_page)->set_offset($offset)->order_by('id desc')->get_results_as_models(); |
| 353 | $this->vars['total_customers'] = $total_customers; |
| 354 | |
| 355 | $this->vars['total_pages'] = ceil($total_customers / $per_page); |
| 356 | $this->vars['per_page'] = $per_page; |
| 357 | $this->vars['current_page_number'] = $page_number; |
| 358 | |
| 359 | $this->vars['showing_from'] = (($page_number - 1) * $per_page) ? (($page_number - 1) * $per_page) : 1; |
| 360 | $this->vars['showing_to'] = min($page_number * $per_page, $this->vars['total_customers']); |
| 361 | |
| 362 | $this->format_render(['json_view_name' => '_table_body', 'html_view_name' => __FUNCTION__], [], ['total_pages' => $total_pages, 'showing_from' => $this->vars['showing_from'], 'showing_to' => $this->vars['showing_to'], 'total_records' => $total_customers]); |
| 363 | } |
| 364 | |
| 365 | |
| 366 | |
| 367 | } |
| 368 | |
| 369 | |
| 370 | endif; |