activities_helper.php
3 months ago
agent_helper.php
3 months ago
analytics_helper.php
4 months ago
auth_helper.php
3 months ago
blocks_helper.php
3 months ago
booking_helper.php
3 months ago
bricks_helper.php
3 months ago
bundles_helper.php
3 months ago
calendar_helper.php
3 months ago
carts_helper.php
3 months ago
connector_helper.php
3 months ago
csv_helper.php
3 months ago
customer_helper.php
3 months ago
customer_import_helper.php
3 months ago
database_helper.php
3 months ago
debug_helper.php
3 months ago
defaults_helper.php
3 months ago
elementor_helper.php
3 months ago
email_helper.php
3 months ago
encrypt_helper.php
3 months ago
events_helper.php
3 months ago
form_helper.php
3 months ago
icalendar_helper.php
3 months ago
image_helper.php
3 months ago
invoices_helper.php
3 months ago
license_helper.php
3 months ago
location_helper.php
3 months ago
marketing_systems_helper.php
3 months ago
meeting_systems_helper.php
3 months ago
menu_helper.php
3 months ago
meta_helper.php
3 months ago
migrations_helper.php
3 months ago
money_helper.php
3 months ago
notifications_helper.php
3 months ago
nps_survey_helper.php
3 months ago
order_intent_helper.php
3 months ago
orders_helper.php
3 months ago
otp_helper.php
3 months ago
pages_helper.php
3 months ago
params_helper.php
3 months ago
payments_helper.php
3 months ago
price_breakdown_helper.php
3 months ago
process_jobs_helper.php
3 months ago
processes_helper.php
3 months ago
replacer_helper.php
3 months ago
resource_helper.php
3 months ago
roles_helper.php
3 months ago
router_helper.php
3 months ago
service_helper.php
3 months ago
sessions_helper.php
3 months ago
settings_helper.php
3 months ago
short_links_systems_helper.php
3 months ago
shortcodes_helper.php
3 months ago
sms_helper.php
3 months ago
steps_helper.php
3 months ago
stripe_connect_helper.php
3 months ago
styles_helper.php
3 months ago
support_topics_helper.php
3 months ago
time_helper.php
3 months ago
timeline_helper.php
3 months ago
transaction_helper.php
3 months ago
transaction_intent_helper.php
3 months ago
util_helper.php
3 months ago
version_specific_updates_helper.php
3 months ago
whatsapp_helper.php
3 months ago
work_periods_helper.php
3 months ago
wp_datetime.php
3 months ago
wp_user_helper.php
3 months ago
events_helper.php
474 lines
| 1 | <?php |
| 2 | /* |
| 3 | * Copyright (c) 2022 LatePoint LLC. All rights reserved. |
| 4 | */ |
| 5 | |
| 6 | |
| 7 | class OsEventsHelper { |
| 8 | |
| 9 | public static function week_grid( OsWpDateTime $calendar_start, OsWpDateTime $calendar_end, OsWpDateTime $target_date, array $services_with_resources, array $filter = [] ) { |
| 10 | $now_datetime = OsTimeHelper::now_datetime_object(); |
| 11 | $html = ''; |
| 12 | |
| 13 | |
| 14 | $start_time = 540; |
| 15 | $end_time = 1080; |
| 16 | |
| 17 | $min_service_duration = false; |
| 18 | |
| 19 | $day_slots = []; |
| 20 | for ( $day_date = clone $calendar_start; $day_date <= $calendar_end; $day_date->modify( '+1 day' ) ) { |
| 21 | $day_slots[ $day_date->format( 'Y-m-d' ) ] = []; |
| 22 | foreach ( $services_with_resources as $service_resources ) { |
| 23 | if ( empty( $service_resources['resources'][ $day_date->format( 'Y-m-d' ) ] ) ) { |
| 24 | continue; |
| 25 | } |
| 26 | $clean_periods = []; |
| 27 | foreach ( $service_resources['resources'][ $day_date->format( 'Y-m-d' ) ] as $resource ) { |
| 28 | if ( ! empty( $filter['agent_id'] ) && $resource->agent_id != $filter['agent_id'] ) { |
| 29 | continue; |
| 30 | } |
| 31 | if ( ! empty( $filter['service_id'] ) && $resource->service_id != $filter['service_id'] ) { |
| 32 | continue; |
| 33 | } |
| 34 | if ( ! empty( $filter['location_id'] ) && $resource->location_id != $filter['location_id'] ) { |
| 35 | continue; |
| 36 | } |
| 37 | foreach ( $resource->work_time_periods as $time_period ) { |
| 38 | $clean_periods[] = $time_period; |
| 39 | } |
| 40 | } |
| 41 | $merged_periods = \LatePoint\Misc\TimePeriod::merge_periods( $clean_periods ); |
| 42 | |
| 43 | |
| 44 | foreach ( $merged_periods as $time_period ) { |
| 45 | if ( ( $time_period->end_time - $time_period->start_time ) > 0 ) { |
| 46 | $min_service_duration = $min_service_duration ? min( $min_service_duration, ( $time_period->end_time - $time_period->start_time ) ) : $time_period->end_time - $time_period->start_time; |
| 47 | } |
| 48 | $service_box_data = [ |
| 49 | 'model' => $service_resources['model'], |
| 50 | 'time_period' => $time_period, |
| 51 | ]; |
| 52 | $day_slots[ $day_date->format( 'Y-m-d' ) ][ $time_period->start_time ][] = $service_box_data; |
| 53 | $start_time = min( $start_time, $time_period->start_time ); |
| 54 | $end_time = max( $end_time, $time_period->end_time ); |
| 55 | } |
| 56 | } |
| 57 | ksort( $day_slots[ $day_date->format( 'Y-m-d' ) ] ); |
| 58 | } |
| 59 | |
| 60 | $html .= '<div class="latepoint-calendar-week">'; |
| 61 | |
| 62 | // make it start a little earlier so that there is some space between day labels and first bookings |
| 63 | $start_time = $start_time - 60; |
| 64 | |
| 65 | // make sure timeline starts at hour marks |
| 66 | if ( $start_time % 60 != 0 ) { |
| 67 | $start_time = $start_time - ( $start_time % 60 ); |
| 68 | } |
| 69 | $day_duration = $end_time - $start_time; |
| 70 | |
| 71 | $hour_height_css = ''; |
| 72 | if ( $min_service_duration && $min_service_duration < 60 ) { |
| 73 | $default_hour_height = 44; |
| 74 | $hour_height = ceil( 60 / $min_service_duration ) * $default_hour_height; |
| 75 | $hour_height_css = 'style="height: ' . $hour_height . 'px"'; |
| 76 | } |
| 77 | |
| 78 | for ( $day_date = clone $calendar_start; $day_date <= $calendar_end; $day_date->modify( '+1 day' ) ) { |
| 79 | |
| 80 | |
| 81 | |
| 82 | $is_today = ( $day_date->format( 'Y-m-d' ) == $now_datetime->format( 'Y-m-d' ) ); |
| 83 | $is_day_in_past = ( $day_date->format( 'Y-m-d' ) < $now_datetime->format( 'Y-m-d' ) ); |
| 84 | $is_target_month = ( $day_date->format( 'm' ) == $target_date->format( 'm' ) ); |
| 85 | $is_next_month = ( $day_date->format( 'm' ) > $target_date->format( 'm' ) ); |
| 86 | $is_prev_month = ( $day_date->format( 'm' ) < $target_date->format( 'm' ) ); |
| 87 | |
| 88 | |
| 89 | $day_class = ''; |
| 90 | if ( $is_today ) { |
| 91 | $day_class .= ' os-today'; |
| 92 | } |
| 93 | if ( $is_day_in_past ) { |
| 94 | $day_class .= ' os-day-passed'; |
| 95 | } |
| 96 | if ( $is_target_month ) { |
| 97 | $day_class .= ' os-month-current'; |
| 98 | } |
| 99 | if ( $is_next_month ) { |
| 100 | $day_class .= ' os-month-next'; |
| 101 | } |
| 102 | if ( $is_prev_month ) { |
| 103 | $day_class .= ' os-month-prev'; |
| 104 | } |
| 105 | $day_class .= ' day-weekday-' . $day_date->format( 'N' ); |
| 106 | |
| 107 | $html .= '<div class="le-day-wrapper ' . $day_class . '">'; |
| 108 | |
| 109 | |
| 110 | $html .= '<div class="le-day-weekday-wrapper">'; |
| 111 | $html .= '<div class="le-day-weekday">' . OsBookingHelper::get_weekday_name_by_number( $day_date->format( 'N' ) ) . '</div>'; |
| 112 | if ( $day_date->format( 'd' ) == '1' ) { |
| 113 | $html .= '<div class="os-day-month">' . OsUtilHelper::get_month_name_by_number( $day_date->format( 'n' ) ) . '</div>'; |
| 114 | } |
| 115 | $html .= '<div class="le-day-number" |
| 116 | data-os-params="' . OsUtilHelper::build_os_params( |
| 117 | [ |
| 118 | 'target_date_string' => $day_date->format( 'Y-m-d' ), |
| 119 | 'filter' => $filter, |
| 120 | ] |
| 121 | ) . '" |
| 122 | data-os-output-target="lightbox" |
| 123 | data-os-action="' . OsRouterHelper::build_route_name( 'events', 'events_day_view' ) . '">' . $day_date->format( 'j' ) . |
| 124 | '</div>'; |
| 125 | $html .= '</div>'; |
| 126 | |
| 127 | $html .= '<div class="le-day-schedule-wrapper">'; |
| 128 | $html .= '<div class="day-schedule-timeslots">'; |
| 129 | for ( $i = $start_time; $i < $end_time; $i += 60 ) { |
| 130 | $html .= '<div class="day-schedule-timeslot-wrapper">'; |
| 131 | $html .= '<div class="day-schedule-timeslot" ' . $hour_height_css . '><div class="day-schedule-timeslot-value">' . OsTimeHelper::minutes_to_hours_and_minutes( $i, null, true, true ) . '</div></div>'; |
| 132 | $html .= '</div>'; |
| 133 | |
| 134 | } |
| 135 | foreach ( $day_slots[ $day_date->format( 'Y-m-d' ) ] as $day_slot_services ) { |
| 136 | foreach ( $day_slot_services as $day_slot_service ) { |
| 137 | $slot_duration = $day_slot_service['time_period']->end_time - $day_slot_service['time_period']->start_time; |
| 138 | $start_position = ( $day_slot_service['time_period']->start_time - $start_time ) / $day_duration * 100; |
| 139 | $height = $slot_duration / $day_duration * 100; |
| 140 | $extra_attrs = 'style="top: ' . $start_position . '%; height: ' . $height . '%"'; |
| 141 | $html .= self::event_service_box_html( $day_slot_service['model'], $day_slot_service['time_period'], $filter, $day_date, $extra_attrs ); |
| 142 | } |
| 143 | } |
| 144 | $html .= '</div>'; |
| 145 | $html .= '</div>'; |
| 146 | $html .= '</div>'; |
| 147 | } |
| 148 | $html .= '</div>'; |
| 149 | return $html; |
| 150 | } |
| 151 | |
| 152 | public static function month_grid( OsWpDateTime $calendar_start, OsWpDateTime $calendar_end, OsWpDateTime $target_date, array $services_with_resources, array $filter = [] ) { |
| 153 | $now_datetime = OsTimeHelper::now_datetime_object(); |
| 154 | $html = ''; |
| 155 | $html .= '<div class="latepoint-calendar-month">'; |
| 156 | |
| 157 | $weekdays = OsBookingHelper::get_weekdays_arr(); |
| 158 | foreach ( $weekdays as $weekday_number => $weekday_name ) { |
| 159 | $html .= '<div class="le-weekday weekday-' . ( $weekday_number + 1 ) . '">' . $weekday_name . '</div>'; |
| 160 | } |
| 161 | |
| 162 | for ( $day_date = clone $calendar_start; $day_date <= $calendar_end; $day_date->modify( '+1 day' ) ) { |
| 163 | $is_today = ( $day_date->format( 'Y-m-d' ) == $now_datetime->format( 'Y-m-d' ) ); |
| 164 | $is_day_in_past = ( $day_date->format( 'Y-m-d' ) < $now_datetime->format( 'Y-m-d' ) ); |
| 165 | $is_target_month = ( $day_date->format( 'm' ) == $target_date->format( 'm' ) ); |
| 166 | $is_next_month = ( $day_date->format( 'm' ) > $target_date->format( 'm' ) ); |
| 167 | $is_prev_month = ( $day_date->format( 'm' ) < $target_date->format( 'm' ) ); |
| 168 | |
| 169 | $day_class = ''; |
| 170 | if ( $is_today ) { |
| 171 | $day_class .= ' os-today'; |
| 172 | } |
| 173 | if ( $is_day_in_past ) { |
| 174 | $day_class .= ' os-day-passed'; |
| 175 | } |
| 176 | if ( $is_target_month ) { |
| 177 | $day_class .= ' os-month-current'; |
| 178 | } |
| 179 | if ( $is_next_month ) { |
| 180 | $day_class .= ' os-month-next'; |
| 181 | } |
| 182 | if ( $is_prev_month ) { |
| 183 | $day_class .= ' os-month-prev'; |
| 184 | } |
| 185 | $day_class .= ' day-weekday-' . $day_date->format( 'N' ); |
| 186 | |
| 187 | $html .= '<div class="le-day-wrapper ' . $day_class . '">'; |
| 188 | |
| 189 | if ( $day_date->format( 'd' ) == '1' ) { |
| 190 | $html .= '<div class="os-day-month">' . OsUtilHelper::get_month_name_by_number( $day_date->format( 'n' ) ) . '</div>'; |
| 191 | } |
| 192 | $html .= '<div class="le-day-number" |
| 193 | data-os-params="' . OsUtilHelper::build_os_params( |
| 194 | [ |
| 195 | 'target_date_string' => $day_date->format( 'Y-m-d' ), |
| 196 | 'filter' => $filter, |
| 197 | ] |
| 198 | ) . '" |
| 199 | data-os-output-target="lightbox" |
| 200 | data-os-action="' . OsRouterHelper::build_route_name( 'events', 'events_day_view' ) . '">' . $day_date->format( 'j' ) . |
| 201 | '</div>'; |
| 202 | $day_services_html = []; |
| 203 | foreach ( $services_with_resources as $service_resources ) { |
| 204 | if ( empty( $service_resources['resources'][ $day_date->format( 'Y-m-d' ) ] ) ) { |
| 205 | continue; |
| 206 | } |
| 207 | $clean_periods = []; |
| 208 | foreach ( $service_resources['resources'][ $day_date->format( 'Y-m-d' ) ] as $resource ) { |
| 209 | if ( ! empty( $filter['agent_id'] ) && $resource->agent_id != $filter['agent_id'] ) { |
| 210 | continue; |
| 211 | } |
| 212 | if ( ! empty( $filter['service_id'] ) && $resource->service_id != $filter['service_id'] ) { |
| 213 | continue; |
| 214 | } |
| 215 | if ( ! empty( $filter['location_id'] ) && $resource->location_id != $filter['location_id'] ) { |
| 216 | continue; |
| 217 | } |
| 218 | foreach ( $resource->work_time_periods as $time_period ) { |
| 219 | $clean_periods[] = $time_period; |
| 220 | } |
| 221 | } |
| 222 | $merged_periods = \LatePoint\Misc\TimePeriod::merge_periods( $clean_periods ); |
| 223 | foreach ( $merged_periods as $time_period ) { |
| 224 | $day_services_html[ $time_period->start_time ][] = self::event_service_box_html( $service_resources['model'], $time_period, $filter, $day_date ); |
| 225 | } |
| 226 | } |
| 227 | ksort( $day_services_html ); |
| 228 | $daily_count = 0; |
| 229 | foreach ( $day_services_html as $day_service_html ) { |
| 230 | if ( $daily_count >= 4 ) { |
| 231 | // translators: %d is the number of services |
| 232 | $more = sprintf( __( '+ %d more', 'latepoint' ), count( $day_services_html ) - 4 ); |
| 233 | $html .= '<div class="le-more-services" |
| 234 | data-os-params="' . esc_attr( |
| 235 | OsUtilHelper::build_os_params( |
| 236 | [ |
| 237 | 'target_date_string' => $day_date->format( 'Y-m-d' ), |
| 238 | 'filter' => $filter, |
| 239 | ] |
| 240 | ) |
| 241 | ) . '" |
| 242 | data-os-output-target="lightbox" |
| 243 | data-os-action="' . esc_attr( OsRouterHelper::build_route_name( 'events', 'events_day_view' ) ) . '">' . esc_html( $more ) . '</div>'; |
| 244 | break; |
| 245 | } |
| 246 | $daily_count++; |
| 247 | $html .= implode( '', $day_service_html ); |
| 248 | } |
| 249 | $html .= '</div>'; |
| 250 | } |
| 251 | $html .= '</div>'; |
| 252 | return $html; |
| 253 | } |
| 254 | |
| 255 | public static function event_service_box_html( OsServiceModel $service, \LatePoint\Misc\TimePeriod $time_period, array $filter, OsWpDateTime $start_date, string $extra_attrs = '' ) { |
| 256 | $service_box_html = ''; |
| 257 | $selected_attributes = ''; |
| 258 | |
| 259 | if ( ! empty( $filter['agent_id'] ) ) { |
| 260 | $selected_attributes .= ' data-selected-agent="' . esc_attr( $filter['agent_id'] ) . '" '; |
| 261 | } |
| 262 | if ( ! empty( $filter['location_id'] ) ) { |
| 263 | $selected_attributes .= ' data-selected-location="' . esc_attr( $filter['location_id'] ) . '" '; |
| 264 | } |
| 265 | if ( ! empty( $filter['show_agents'] ) ) { |
| 266 | $selected_attributes .= ' data-show-agents="' . esc_attr( $filter['show_agents'] ) . '" '; |
| 267 | } |
| 268 | if ( ! empty( $filter['show_locations'] ) ) { |
| 269 | $selected_attributes .= ' data-show-locations="' . esc_attr( $filter['show_locations'] ) . '" '; |
| 270 | } |
| 271 | |
| 272 | |
| 273 | if ( OsEventsHelper::is_service_slot_passed( $service, $start_date, $time_period ) ) { |
| 274 | $service_box_html .= '<div class="le-service-wrapper is-passed" ' . $extra_attrs . '><div class="is-passed-message">' . esc_html__( 'This event has passed', 'latepoint' ) . '</div>'; |
| 275 | } else { |
| 276 | $start_time_attr = ( ( $time_period->end_time - $time_period->start_time ) > $service->duration ) ? '' : 'data-selected-start-time="' . esc_attr( $time_period->start_time ) . '"'; |
| 277 | $service_box_html .= '<div class="le-service-wrapper os_trigger_booking" ' . $extra_attrs . ' ' . $selected_attributes . ' |
| 278 | data-selected-service="' . esc_attr( $service->id ) . '" |
| 279 | data-selected-start-date="' . esc_attr( $start_date->format( 'Y-m-d' ) ) . '" |
| 280 | ' . $start_time_attr . ' |
| 281 | data-hide-side-panel="yes">'; |
| 282 | } |
| 283 | $service_box_html .= '<div class="le-service-inner">'; |
| 284 | $service_box_html .= '<div class="le-color-elem" style="background-color: ' . esc_attr( $service->bg_color ) . '"></div>'; |
| 285 | $service_box_html .= '<div class="le-service-name">' . esc_html( $service->name ) . '</div>'; |
| 286 | $service_box_html .= '<div class="le-service-time-period">' . OsTimeHelper::minutes_to_hours_and_minutes( $time_period->start_time ) . ' - ' . OsTimeHelper::minutes_to_hours_and_minutes( $time_period->end_time ) . '</div>'; |
| 287 | $service_box_html .= '</div>'; |
| 288 | $service_box_html .= '</div>'; |
| 289 | return $service_box_html; |
| 290 | } |
| 291 | |
| 292 | public static function events_grid( OsWpDateTime $target_date, array $filter = [], $range_type = 'week', array $restrictions = [] ): string { |
| 293 | $html = ''; |
| 294 | |
| 295 | switch ( $range_type ) { |
| 296 | case 'week': |
| 297 | # Get bounds for a month of a targeted day |
| 298 | $calendar_start = clone $target_date; |
| 299 | // set monday as start of the week |
| 300 | $start_of_the_week_day = 1; |
| 301 | // figure out what week day is target and then find start and end of that week |
| 302 | $shift = $calendar_start->format( 'N' ) - $start_of_the_week_day; |
| 303 | if ( $shift ) { |
| 304 | $calendar_start->modify( '-' . $shift . ' days' ); |
| 305 | } |
| 306 | $calendar_end = clone $calendar_start; |
| 307 | $calendar_end->modify( '+6 days' ); |
| 308 | |
| 309 | $next_period = clone $calendar_start; |
| 310 | $next_period->modify( '+7 days' ); |
| 311 | |
| 312 | $prev_period = clone $calendar_start; |
| 313 | $prev_period->modify( '-7 days' ); |
| 314 | break; |
| 315 | case 'month': |
| 316 | # Get bounds for a month of a targeted day |
| 317 | $calendar_start = clone $target_date; |
| 318 | $calendar_start->modify( 'first day of this month' ); |
| 319 | $calendar_end = clone $target_date; |
| 320 | $calendar_end->modify( 'last day of this month' ); |
| 321 | |
| 322 | $next_period = clone $target_date; |
| 323 | $next_period->modify( 'first day of next month' ); |
| 324 | |
| 325 | $prev_period = clone $target_date; |
| 326 | $prev_period->modify( 'first day of previous month' ); |
| 327 | |
| 328 | |
| 329 | $weekday_for_first_day_of_month = $calendar_start->format( 'N' ) - 1; |
| 330 | $weekday_for_last_day_of_month = $calendar_end->format( 'N' ) - 1; |
| 331 | |
| 332 | |
| 333 | if ( $weekday_for_first_day_of_month > 0 ) { |
| 334 | $calendar_start->modify( '-' . $weekday_for_first_day_of_month . ' days' ); |
| 335 | } |
| 336 | |
| 337 | if ( $weekday_for_last_day_of_month < 6 ) { |
| 338 | $days_to_add = 6 - $weekday_for_last_day_of_month; |
| 339 | $calendar_end->modify( '+' . $days_to_add . ' days' ); |
| 340 | } |
| 341 | break; |
| 342 | } |
| 343 | |
| 344 | |
| 345 | $now_datetime = OsTimeHelper::now_datetime_object(); |
| 346 | |
| 347 | |
| 348 | $services = new OsServiceModel(); |
| 349 | if ( ! empty( $restrictions['show_services'] ) ) { |
| 350 | $services->where( [ 'id' => explode( ',', $restrictions['show_services'] ) ] ); |
| 351 | } |
| 352 | $services = $services->should_be_active()->get_results_as_models(); |
| 353 | |
| 354 | $services_with_resources = []; |
| 355 | |
| 356 | foreach ( $services as $service ) { |
| 357 | $services_with_resources[ 'service_' . $service->id ] = [ |
| 358 | 'model' => $service, |
| 359 | 'work_periods' => [], |
| 360 | ]; |
| 361 | $booking_request = new \LatePoint\Misc\BookingRequest( |
| 362 | [ |
| 363 | 'service_id' => $service->id, |
| 364 | ] |
| 365 | ); |
| 366 | $services_with_resources[ 'service_' . $service->id ]['resources'] = OsResourceHelper::get_resources_grouped_by_day( $booking_request, $calendar_start, $calendar_end ); |
| 367 | } |
| 368 | |
| 369 | $clean_filter = []; |
| 370 | foreach ( $filter as $filter_key => $filter_value ) { |
| 371 | if ( ! empty( $filter_value ) ) { |
| 372 | $clean_filter[ $filter_key ] = $filter_value; |
| 373 | } |
| 374 | } |
| 375 | |
| 376 | $filter_class = empty( $clean_filter ) ? '' : 'show-filters'; |
| 377 | |
| 378 | $clean_filter = array_merge( $clean_filter, $restrictions ); |
| 379 | $agent_restriction = ! empty( $restrictions['show_agents'] ) ? explode( ',', $restrictions['show_agents'] ) : []; |
| 380 | $service_restriction = ! empty( $restrictions['show_services'] ) ? explode( ',', $restrictions['show_services'] ) : []; |
| 381 | |
| 382 | $html .= '<div class="latepoint-calendar-wrapper ' . $filter_class . '" data-route-name="' . OsRouterHelper::build_route_name( 'events', 'load_calendar_events' ) . '" data-target-date="' . $target_date->format( 'Y-m-d' ) . '">'; |
| 383 | $html .= '<div class="latepoint-calendar-controls-wrapper">'; |
| 384 | $html .= OsFormHelper::hidden_field( 'restrictions', wp_json_encode( $restrictions ) ); |
| 385 | $html .= '<div class="latepoint-calendar-controls">'; |
| 386 | if ( $range_type == 'week' ) { |
| 387 | if ( $calendar_start->format( 'M' ) == $calendar_end->format( 'M' ) ) { |
| 388 | $html .= '<div class="le-week">' . $calendar_start->format( 'M j' ) . ' - ' . $calendar_end->format( 'j' ) . '</div>'; |
| 389 | } else { |
| 390 | $html .= '<div class="le-week">' . $calendar_start->format( 'M j' ) . ' - ' . $calendar_end->format( 'M j' ) . '</div>'; |
| 391 | } |
| 392 | } |
| 393 | if ( $range_type == 'month' ) { |
| 394 | $html .= '<div class="le-month">' . OsUtilHelper::get_month_name_by_number( $target_date->format( 'n' ) ) . '</div>'; |
| 395 | } |
| 396 | $html .= '<div class="le-range-selector">' . OsFormHelper::select_field( |
| 397 | 'calendar_range_type', |
| 398 | false, |
| 399 | [ |
| 400 | 'week' => __( 'Weekly', 'latepoint' ), |
| 401 | 'month' => __( 'Monthly', 'latepoint' ), |
| 402 | ], |
| 403 | $range_type |
| 404 | ) . '</div>'; |
| 405 | $html .= '<div class="le-filter le-filter-trigger"><i class="latepoint-icon latepoint-icon-ui-47"></i><span>' . __( 'Filters', 'latepoint' ) . '</span></div>'; |
| 406 | $html .= OsFormHelper::hidden_field( 'target_date_string', $target_date->format( 'Y-m-d' ) ); |
| 407 | $html .= '<div class="le-navigation-wrapper">'; |
| 408 | $html .= '<div class="le-navigation"> |
| 409 | <div class="le-navigation-button le-navigation-trigger" data-target-date="' . $prev_period->format( 'Y-m-d' ) . '"><i class="latepoint-icon latepoint-icon-arrow-left"></i></div> |
| 410 | <div class="le-today le-navigation-trigger" data-target-date="' . $now_datetime->format( 'Y-m-d' ) . '">' . __( 'Today', 'latepoint' ) . '</div> |
| 411 | <div class="le-navigation-button le-navigation-trigger" data-target-date="' . $next_period->format( 'Y-m-d' ) . '"><i class="latepoint-icon latepoint-icon-arrow-right"></i></div> |
| 412 | </div>'; |
| 413 | $html .= '</div>'; |
| 414 | $html .= '</div>'; |
| 415 | $html .= '<div class="latepoint-calendar-filters">'; |
| 416 | $html .= '<div class="le-filters-label">' . __( 'Show:', 'latepoint' ) . '</div>'; |
| 417 | $html .= OsFormHelper::select_field( |
| 418 | 'filter[agent_id]', |
| 419 | false, |
| 420 | array_merge( |
| 421 | [ |
| 422 | [ |
| 423 | 'value' => '', |
| 424 | 'label' => __( 'All Agents', 'latepoint' ), |
| 425 | ], |
| 426 | ], |
| 427 | OsAgentHelper::get_agents_list( false, $agent_restriction ) |
| 428 | ), |
| 429 | $clean_filter['agent_id'] ?? '' |
| 430 | ); |
| 431 | $html .= OsFormHelper::select_field( |
| 432 | 'filter[service_id]', |
| 433 | false, |
| 434 | array_merge( |
| 435 | [ |
| 436 | [ |
| 437 | 'value' => '', |
| 438 | 'label' => __( 'All Services', 'latepoint' ), |
| 439 | ], |
| 440 | ], |
| 441 | OsServiceHelper::get_services_list( false, $service_restriction ) |
| 442 | ), |
| 443 | $clean_filter['service_id'] ?? '' |
| 444 | ); |
| 445 | $html .= '</div>'; |
| 446 | $html .= '</div>'; |
| 447 | |
| 448 | switch ( $range_type ) { |
| 449 | case 'week': |
| 450 | $html .= self::week_grid( $calendar_start, $calendar_end, $target_date, $services_with_resources, $clean_filter ); |
| 451 | break; |
| 452 | case 'month': |
| 453 | $html .= self::month_grid( $calendar_start, $calendar_end, $target_date, $services_with_resources, $clean_filter ); |
| 454 | break; |
| 455 | } |
| 456 | |
| 457 | $html .= '</div>'; |
| 458 | return $html; |
| 459 | } |
| 460 | |
| 461 | private static function is_service_slot_passed( OsServiceModel $service, OsWpDateTime $start_date, \LatePoint\Misc\TimePeriod $time_period ): bool { |
| 462 | $now_datetime = OsTimeHelper::now_datetime_object(); |
| 463 | $is_day_in_past = ( $start_date->format( 'Y-m-d' ) < $now_datetime->format( 'Y-m-d' ) ); |
| 464 | $is_today = ( $start_date->format( 'Y-m-d' ) == $now_datetime->format( 'Y-m-d' ) ); |
| 465 | |
| 466 | try { |
| 467 | $is_passed = ( $is_day_in_past || $is_today && ( OsWpDateTime::os_createFromFormat( LATEPOINT_DATETIME_DB_FORMAT, $start_date->format( 'Y-m-d' ) . ' ' . OsTimeHelper::minutes_to_army_hours_and_minutes( $time_period->end_time - $service->duration ) . ':00' ) < $now_datetime ) ); |
| 468 | } catch ( Exception $e ) { |
| 469 | $is_passed = false; |
| 470 | } |
| 471 | return $is_passed; |
| 472 | } |
| 473 | } |
| 474 |