PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.1.7
LatePoint – Calendar Booking Plugin for Appointments and Events v5.1.7
5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / controllers / dashboard_controller.php
latepoint / lib / controllers Last commit date
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
dashboard_controller.php
305 lines
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly.
4 }
5
6
7 if ( ! class_exists( 'OsDashboardController' ) ) :
8
9
10 class OsDashboardController extends OsController {
11
12 private $booking;
13
14
15 function __construct(){
16 parent::__construct();
17
18 $this->views_folder = LATEPOINT_VIEWS_ABSPATH . 'dashboard/';
19 $this->vars['page_header'] = __('Dashboard', 'latepoint');
20
21 }
22
23
24 public function pro_agents(){
25
26 }
27
28 /*
29 Index
30 */
31
32 public function index(){
33 $this->vars['page_header'] = false;
34
35 ob_start();
36 $this->widget_bookings_and_availability_timeline();
37 $this->vars['widget_bookings_and_availability_timeline'] = ob_get_clean();
38
39 ob_start();
40 $this->widget_daily_bookings_chart();
41 $this->vars['widget_daily_bookings_chart'] = ob_get_clean();
42
43 ob_start();
44 $this->widget_upcoming_appointments(3);
45 $this->vars['widget_upcoming_appointments'] = ob_get_clean();
46
47 $this->set_layout('admin');
48 $this->format_render(__FUNCTION__);
49 }
50
51 public function widget_upcoming_appointments($limit = 3){
52 $agents = new OsAgentModel();
53 $services = new OsServiceModel();
54 $bookings = new OsBookingModel();
55 $locations = new OsLocationModel();
56
57 $selected_agent_id = isset($this->params['agent_id']) ? OsAuthHelper::get_current_user()->check_if_allowed_record_id($this->params['agent_id'], 'agent') : false;
58 $selected_service_id = isset($this->params['service_id']) ? OsAuthHelper::get_current_user()->check_if_allowed_record_id($this->params['service_id'], 'service') : false;
59 $selected_location_id = isset($this->params['location_id']) ? OsAuthHelper::get_current_user()->check_if_allowed_record_id($this->params['location_id'], 'location') : false;
60
61 $this->vars['upcoming_bookings'] = $bookings->get_upcoming_bookings($selected_agent_id, false, $selected_service_id, $selected_location_id, $limit);
62
63 $this->vars['agents'] = $agents->should_be_active()->filter_allowed_records()->get_results_as_models();
64 $this->vars['services'] = $services->should_be_active()->filter_allowed_records()->get_results_as_models();
65 $this->vars['locations'] = $locations->should_be_active()->filter_allowed_records()->get_results_as_models();
66
67 $this->vars['selected_agent_id'] = $selected_agent_id;
68 $this->vars['selected_service_id'] = $selected_service_id;
69 $this->vars['selected_location_id'] = $selected_location_id;
70
71
72 $this->set_layout('none');
73 $this->format_render(__FUNCTION__);
74 }
75
76
77
78 public function widget_daily_bookings_chart($date_from = false, $date_to = false){
79 if($date_from == false){
80 $date_from = isset($this->params['date_from']) ? OsWpDateTime::os_createFromFormat('Y-m-d', $this->params['date_from']) : new OsWpDateTime('-1 week');
81 }
82 if($date_to == false){
83 $date_to = isset($this->params['date_to']) ? OsWpDateTime::os_createFromFormat('Y-m-d', $this->params['date_to']) : new OsWpDateTime('now');
84 }
85
86
87 $filter = new \LatePoint\Misc\Filter();
88 $filter = OsRolesHelper::filter_allowed_records_from_arguments_or_filter($filter);
89
90 if(!empty($this->params['agent_id'])) $filter->agent_id = $this->params['agent_id'];
91 if(!empty($this->params['service_id'])) $filter->service_id = $this->params['service_id'];
92 if(!empty($this->params['location_id'])) $filter->location_id = $this->params['location_id'];
93
94 if(!OsRolesHelper::are_all_records_allowed()){
95 if(!OsRolesHelper::are_all_records_allowed('agent')) $agent_id = OsRolesHelper::get_allowed_records('agent');
96 }
97
98
99
100 $daily_bookings = OsBookingHelper::get_total_bookings_per_day_for_period($date_from->format('Y-m-d'), $date_to->format('Y-m-d'), $filter);
101
102 $daily_chart_data = [];
103 // fill data array with all the days
104 for($day_date=clone $date_from; $day_date<=$date_to; $day_date->modify('+1 day')){
105 $daily_chart_data[OsTimeHelper::get_nice_date_with_optional_year($day_date->format('Y-m-d'), false)] = 0;
106 }
107 // update the days with count of bookings
108 foreach($daily_bookings as $bookings_for_day){
109 $daily_chart_data[OsTimeHelper::get_nice_date_with_optional_year(gmdate( 'Y-m-d', strtotime($bookings_for_day->start_date)), false)] = $bookings_for_day->bookings_per_day;
110 }
111
112 $this->vars['total_bookings'] = OsBookingHelper::get_stat_for_period('bookings', $date_from->format('Y-m-d'), $date_to->format('Y-m-d'), $filter);
113 $this->vars['total_price'] = OsBookingHelper::get_stat_for_period('price', $date_from->format('Y-m-d'), $date_to->format('Y-m-d'), $filter);
114 $this->vars['total_duration'] = OsBookingHelper::get_stat_for_period('duration', $date_from->format('Y-m-d'), $date_to->format('Y-m-d'), $filter);
115 $this->vars['total_new_customers'] = OsBookingHelper::get_new_customer_stat_for_period($date_from, $date_to, $filter);
116
117 $day_difference = $date_from->diff($date_to);
118 $day_difference = ($day_difference->d > 0) ? $day_difference->d : 1;
119
120 $prev_date_from = clone $date_from;
121 $prev_date_from->modify('-'.$day_difference.' days');
122 $prev_date_to = clone $date_to;
123 $prev_date_to->modify('-'.$day_difference.' days');
124
125 $this->vars['prev_total_bookings'] = OsBookingHelper::get_stat_for_period('bookings', $prev_date_from->format('Y-m-d'), $prev_date_to->format('Y-m-d'), $filter);
126 $this->vars['prev_total_price'] = OsBookingHelper::get_stat_for_period('price', $prev_date_from->format('Y-m-d'), $prev_date_to->format('Y-m-d'), $filter);
127 $this->vars['prev_total_duration'] = OsBookingHelper::get_stat_for_period('duration', $prev_date_from->format('Y-m-d'), $prev_date_to->format('Y-m-d'), $filter);
128 $this->vars['prev_total_new_customers'] = OsBookingHelper::get_new_customer_stat_for_period($prev_date_from, $prev_date_to, $filter);
129
130
131 $agents = new OsAgentModel();
132 $services = new OsServiceModel();
133 $locations = new OsLocationModel();
134
135 $this->vars['agents'] = $agents->should_be_active()->filter_allowed_records()->get_results_as_models();
136 $this->vars['services'] = $services->should_be_active()->filter_allowed_records()->get_results_as_models();
137 $this->vars['locations'] = $locations->should_be_active()->filter_allowed_records()->get_results_as_models();
138
139 $this->vars['filter'] = $filter;
140
141 $this->vars['date_from'] = $date_from->format('Y-m-d');
142 $this->vars['date_to'] = $date_to->format('Y-m-d');
143
144 $this->vars['daily_bookings_chart_labels_string'] = implode(',', array_keys($daily_chart_data));
145 $this->vars['daily_bookings_chart_data_values_string'] = implode(',', array_values($daily_chart_data));
146
147 $pie_labels = [];
148 $pie_colors = [];
149 $pie_values = [];
150 $pie_chart_data = OsBookingHelper::get_stat_for_period('bookings', $date_from->format('Y-m-d'), $date_to->format('Y-m-d'), $filter,'service_id');
151 foreach($pie_chart_data as $pie_data){
152 $service = new OsServiceModel($pie_data['service_id']);
153 $pie_labels[] = $service->name;
154 $pie_colors[] = $service->bg_color;
155 $pie_values[] = $pie_data['stat'];
156 }
157
158 $this->vars['pie_chart_data'] = ['labels' => $pie_labels, 'colors' => $pie_colors, 'values' => $pie_values];
159
160 $this->vars['date_period_string'] = OsTimeHelper::format_date_with_locale(OsSettingsHelper::get_readable_date_format(), $date_from).' - '.OsTimeHelper::format_date_with_locale(OsSettingsHelper::get_readable_date_format(), $date_to);
161
162 $this->set_layout('none');
163 $this->format_render(__FUNCTION__);
164 }
165
166
167
168 public function widget_bookings_and_availability_timeline(){
169 $target_date = isset($this->params['date_from']) ? OsWpDateTime::os_createFromFormat('Y-m-d', $this->params['date_from']) : new OsWpDateTime('now');
170
171 $services = new OsServiceModel();
172 $agents = new OsAgentModel();
173 $locations = new OsLocationModel();
174
175 $agents_models = $agents->should_be_active()->filter_allowed_records()->get_results_as_models();
176 $services_models = $services->should_be_active()->filter_allowed_records()->get_results_as_models();
177 $locations_models = $locations->should_be_active()->filter_allowed_records()->get_results_as_models();
178
179 $this->vars['services'] = $services_models;
180 $this->vars['locations'] = $locations_models;
181 $this->vars['agents'] = $agents_models;
182
183 if($services_models && !empty($this->params['service_id'])){
184 $selected_service = $services->load_by_id($this->params['service_id']);
185 }else{
186 $selected_service = false;
187 }
188
189
190 if($locations_models){
191 // show all locations option if agent can only be present at one place - because it means he does not have overlapping appointments on the calendar
192 $default_location_id = OsSettingsHelper::is_on('one_location_at_time') ? false : $locations_models[0]->id;
193 $selected_location_id = !empty($this->params['location_id']) ? $this->params['location_id'] : $default_location_id;
194 }else{
195 $selected_location_id = false;
196 }
197
198 $this->vars['selected_location'] = $selected_location_id ? new OsLocationModel($selected_location_id) : false;
199 $this->vars['selected_location_id'] = $selected_location_id;
200
201 $timeblock_interval = OsSettingsHelper::get_default_timeblock_interval();
202 $selected_service_id = ($selected_service) ? $selected_service->id : false;
203
204 $this->vars['selected_service'] = $selected_service;
205 $this->vars['selected_service_id'] = $selected_service_id;
206
207
208
209 // we are using two separate booking requests because the calendar on top has to generate availability timeline,
210 // which can only be generated if we know service to check for. The second booking request is used to retrieve
211 // shared resources for all services and locations (unless specific location is selected)
212 $availability_booking_request = new \LatePoint\Misc\BookingRequest(['start_date' => $target_date->format('Y-m-d')]);
213 $general_booking_request = new \LatePoint\Misc\BookingRequest(['start_date' => $target_date->format('Y-m-d')]);
214 if($selected_location_id){
215 $availability_booking_request->location_id = $selected_location_id;
216 $general_booking_request->location_id = $selected_location_id;
217 }
218 if($selected_service){
219 $availability_booking_request->service_id = $selected_service->id;
220 // TODO add capacity and duration select box and POST params if multiple durations in a service
221 $availability_booking_request->duration = $selected_service->duration;
222 $timeblock_interval = $selected_service->get_timeblock_interval();
223 }
224
225 if(count($agents_models) == 1) {
226 $availability_booking_request->agent_id = $agents_models[0]->id;
227 $general_booking_request->agent_id = $agents_models[0]->id;
228 }
229
230 $settings = ['accessed_from_backend' => true];
231 $resources = OsResourceHelper::get_resources_grouped_by_day($general_booking_request, $target_date, $target_date, $settings);
232 $availability_resources = OsResourceHelper::get_resources_grouped_by_day($availability_booking_request, $target_date, $target_date, $settings);
233 $work_boundaries = OsResourceHelper::get_work_boundaries_for_resources($resources[$target_date->format('Y-m-d')]);
234 $work_total_minutes = $work_boundaries->end_time - $work_boundaries->start_time;
235
236 $this->vars['timeblock_interval'] = $timeblock_interval;
237
238 $bookings = [];
239 $agent_work_time_periods = [];
240 if($agents_models){
241 foreach($agents_models as $agent){
242 $agent_work_time_periods[$agent->id] = [];
243 $args = ['agent_id' => $agent->id];
244 if($selected_location_id) $args['location_id'] = $selected_location_id;
245 $args['status'] = OsCalendarHelper::get_booking_statuses_to_display_on_calendar();
246 $args = OsRolesHelper::filter_allowed_records_from_arguments_or_filter($args);
247 $bookings[$agent->id] = OsBookingHelper::get_bookings_for_date($target_date->format('Y-m-d'), $args);
248 }
249 foreach($availability_resources[$target_date->format('Y-m-d')] as $resource){
250 if(isset($agent_work_time_periods[$resource->agent_id])) $agent_work_time_periods[$resource->agent_id] = array_merge($agent_work_time_periods[$resource->agent_id], $resource->work_time_periods);
251 }
252 }
253
254
255 $this->vars['agent_work_time_periods'] = $agent_work_time_periods;
256
257 $this->vars['availability_booking_request'] = $availability_booking_request;
258 $this->vars['general_booking_request'] = $general_booking_request;
259
260 $agents_resources = [];
261 foreach ($agents_models as $agent) {
262 $agent_booking_request = clone $availability_booking_request;
263 $agent_booking_request->agent_id = $agent->id;
264 $daily_resources = OsResourceHelper::get_resources_grouped_by_day($agent_booking_request, $target_date, null, $settings);
265 $agents_resources['agent_' . $agent->id] = $daily_resources[$target_date->format('Y-m-d')];
266 }
267 $this->vars['agents_resources'] = $agents_resources;
268 $this->vars['timeline_boundaries'] = OsResourceHelper::get_work_boundaries_for_groups_of_resources($agents_resources);
269
270 $this->vars['work_total_minutes'] = $work_total_minutes;
271 $this->vars['work_boundaries'] = $work_boundaries;
272 $this->vars['show_day_info'] = OsAuthHelper::is_admin_logged_in();
273 $this->vars['target_date_obj'] = $target_date;
274 $this->vars['target_date'] = $target_date->format('Y-m-d');
275 $this->vars['target_date_string'] = OsTimeHelper::get_readable_date($target_date);
276
277 $this->vars['what_to_show'] = isset($this->params['what_to_show']) ? $this->params['what_to_show'] : 'appointments';
278
279
280 $today_date = new OsWpDateTime('today');
281
282 if($target_date->format('Y-m-d') == $today_date->format('Y-m-d')){
283 $time_now = OsTimeHelper::now_datetime_object();
284 $time_now_in_minutes = OsTimeHelper::convert_datetime_to_minutes($time_now);
285 if(($time_now_in_minutes<=$work_boundaries->end_time && $time_now_in_minutes>=$work_boundaries->start_time)){
286 $this->vars['time_now_label'] = $time_now->format(OsTimeHelper::get_time_format());
287 // agents row with avatars and margin below - offset that needs to be accounted for when calculating "time now" indicator position
288 $this->vars['time_now_indicator_left_offset'] = ($time_now_in_minutes - $work_boundaries->start_time) / $work_total_minutes * 100;
289 $this->vars['show_today_indicator'] = true;
290 }else{
291 $this->vars['show_today_indicator'] = false;
292 }
293 }else{
294 $this->vars['show_today_indicator'] = false;
295 }
296
297 $this->set_layout('none');
298
299 $this->format_render(__FUNCTION__);
300 }
301
302
303 }
304
305 endif;