Created
May 15, 2017 08:47
Star
You must be signed in to star a gist
Add capacity control to services of WPMUDEV Appointments+ plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: Appointments capacity control | |
Plugin URI: https://premium.wpmudev.org/ | |
Description: Add capacity control to services | |
Author: Panos Lyrakis @ WPMUDEV | |
Author URI: https://premium.wpmudev.org/ | |
License: GPLv2 or later | |
*/ | |
/* | |
Requires to modify function apppointments_is_range_busy() | |
and add the following somwhere on the beginning : | |
============= | |
$force_availability = apply_filters( 'app-force_availability', false, $start, $end, $args ); | |
if( $force_availability ){ | |
$is_busy = apply_filters( 'app-is_busy_custom', false, $start, $end, $args ); | |
return $is_busy; | |
} | |
============ | |
*/ | |
if( ! class_exists( 'WPMUDEV_App_Capacity_Control' ) ){ | |
class WPMUDEV_App_Capacity_Control{ | |
private static $_instance = null; | |
public $version; | |
public static function get_instance() { | |
if ( is_null( self::$_instance ) ) { | |
self::$_instance = new WPMUDEV_App_Capacity_Control(); | |
} | |
return self::$_instance; | |
} | |
private function __construct(){ | |
add_filter( 'app-force_availability', array( $this, 'force_availability' ), 10, 4 ); | |
add_filter( 'app-is_busy_custom', array( $this, 'is_busy' ), 10, 4 ); | |
add_filter( 'app_additional_fields', array( $this, 'additional_field'), 10 ); | |
add_action( 'wpmudev_appointments_insert_appointment', array( $this, 'save_additional_fields' ), 10 ); | |
add_action( 'wp_ajax_pre_confirmation_slot_capacity', array( $this, 'ajax_slot_capacity' ) ); | |
add_action( 'wp_ajax_nopriv_pre_confirmation_slot_capacity', array( $this, 'ajax_slot_capacity' ) ); | |
/* | |
//TODO | |
add_filter('app_notification_message', array($this, 'expand_email_macros'), 10, 3); | |
add_filter('app_confirmation_message', array($this, 'expand_email_macros'), 10, 3); | |
add_filter('app_reminder_message', array($this, 'expand_email_macros'), 10, 3); | |
add_filter('app_removal_notification_message', array($this, 'expand_email_macros'), 10, 3); | |
*/ | |
} | |
public function force_availability( $force_it, $start, $end, $args ){ | |
return true; | |
} | |
public function is_busy( $is_busy, $start, $end, $args ){ | |
$service_id = (int)$args['service_id']; | |
$start = date( 'Y-m-d H:i:s', $start ); | |
$end = date( 'Y-m-d H:i:s', $end ); | |
$av_args = array( | |
'service_id' => $service_id, | |
'start' => $start, | |
'end' => $end | |
); | |
$service_capacity = $this->get_availability( $av_args ); | |
return ! $service_capacity > 0; | |
} | |
public function get_availability( $args ){ | |
global $wpdb; | |
$service_id = (int)$args['service_id']; | |
$service = appointments_get_service( $service_id ); | |
$service_capacity = (int)$service->capacity; //appointments_get_service_capacity( $service_id ); //(int)$args[ 'capacity' ]; | |
/* | |
$service_id = (int)$args['service_id']; | |
$start = (int)$args['start']; | |
$end = (int)$args['end']; | |
$un_args = array( | |
'service_id' => $service_id, | |
'start' => $start, | |
'end' => $end | |
); | |
*/ | |
$unavail = self::get_unavail( $args ); | |
if( is_numeric( $unavail ) && $unavail > 0 ){ | |
$workers_count = count( appointments_get_workers_by_service( $service_id ) ); | |
$service_capacity = $workers_count * $service_capacity; | |
$service_capacity -= $unavail; | |
//return ! $service_capacity > 0; | |
} | |
//return false; | |
return $service_capacity; | |
} | |
public static function get_unavail( $args ){ | |
global $wpdb; | |
$service_id = $args[ 'service_id' ]; | |
$start = $args[ 'start' ]; | |
$end = $args[ 'end' ]; | |
$booked_query = "SELECT SUM( app_meta.meta_value ) AS unavail FROM {$wpdb->prefix}app_appointments as app | |
LEFT JOIN {$wpdb->prefix}app_appointmentmeta AS app_meta ON app.ID = app_meta.app_appointment_id | |
WHERE | |
app.service={$service_id} AND app.status IN( 'pending','confirmed', 'paid' ) AND ( ( app.start BETWEEN '{$start}' AND '{$end}' ) OR ( app.end BETWEEN '{$start}' AND '{$end}' ) ) AND app_meta.meta_key = 'app_item_count'"; | |
return $wpdb->get_var( $booked_query ); | |
} | |
public function ajax_slot_capacity(){ | |
$service_id = (int)$_POST[ 'service_id' ]; | |
$start = date('Y-m-d H:i:s', $_POST[ 'start' ] ); | |
$end = date('Y-m-d H:i:s', $_POST[ 'end' ] ); | |
$args = array( | |
'service_id' => $service_id, | |
'start' => $start, | |
'end' => $end | |
); | |
$availability = $this->get_availability( $args ); | |
$response = array( 'capacity' => $availability ); | |
wp_send_json( $response ); | |
} | |
public function additional_field( $fields_html ){ | |
global $wpdb; | |
//$services_capacities = $wpdb->get_results( "SELECT ID, capacity FROM {$wpdb->prefix}app_services", ARRAY_A ); | |
ob_start(); | |
?> | |
<div class="appointments-capacity-field"> | |
<label> | |
<span>Select number</span> | |
<select name="app-service-capacity-select" id="app-service-capacity-select"></select> | |
</label> | |
</div> | |
<script type="text/javascript"> | |
(function($){ | |
$(document).ready(function(){ | |
$.ajaxSetup({ | |
beforeSend: function (jqxhr, settings) { | |
settings.data += '&' + encodeURIComponent( 'app-service-capacity-select' ) + '=' + encodeURIComponent( $( '#app-service-capacity-select' ).val() ); | |
} | |
}); | |
//var services_capacities = JSON.parse( '<?php //echo json_encode( $services_capacities ); ?>' ); | |
var $body = $('body'); | |
var capacity_selector = $( '#app-service-capacity-select' ); | |
$body.on( 'click', '.app_timetable_cell.free, .app_week_timetable_cell.free', function( $element ) { | |
/*if( ! isNaN( selected_service ) ){ | |
return; | |
}*/ | |
var confirmation_btn = $( '.appointments-confirmation-button' ); | |
var selected_slot_meta = $( this ).find( '.appointments_take_appointment' ).val(); | |
var selected_meta_parts = selected_slot_meta.split(':'); | |
var selected_service = selected_meta_parts[1]; | |
var start = selected_meta_parts[3]; | |
var end = selected_meta_parts[4]; | |
var cap_data = { | |
action : "pre_confirmation_slot_capacity", | |
nonce : AppShortcodeConfirmation.nonce, | |
service_id : selected_service, | |
start : start, | |
end : end | |
}; | |
confirmation_btn.hide( 300 ); | |
$.post( AppShortcodeConfirmation.ajaxurl, cap_data, function( response ) { | |
var capacity = 1; | |
if ( response && response.error ) { | |
//Just do nothing and leave capacity to 1 | |
//console.log( 'No capacity response' ); | |
} | |
else{ | |
capacity = response.capacity; | |
} | |
var selector_options = ''; | |
for( var c = 1; c <= capacity; c++ ){ | |
selector_options += '<option value="' + c + '">' + c + '</option>'; | |
} | |
capacity_selector.append( selector_options ); | |
confirmation_btn.show( 300 ); | |
}, 'json'); | |
/*$.each(services_capacities, function(i,item){ | |
if( item.ID == selected_service ){ | |
capacity = item.capacity; | |
} | |
});*/ | |
} ); | |
}); | |
})(jQuery); | |
</script> | |
<?php | |
$capacity_selector = ob_get_clean(); | |
return $fields_html . $capacity_selector; | |
} | |
public function save_additional_fields( $app_id ){ | |
if( ! isset( $_REQUEST[ 'app-service-capacity-select' ] ) || ! is_numeric( $_REQUEST[ 'app-service-capacity-select' ] ) ){ | |
return; | |
} | |
$capacity_selected = (int)$_REQUEST['app-service-capacity-select']; | |
update_metadata( 'app_appointment', $app_id, 'app_item_count', $capacity_selected ); | |
} | |
} | |
add_action( 'plugins_loaded', function(){ | |
$GLOBALS['WPMUDEV_App_Capacity_Control'] = WPMUDEV_App_Capacity_Control::get_instance(); | |
}, 10 ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In order the above to work on Appointments+ version 2.1.0 you need to modify file
includes/helpers.php
and add the following at the beginning of function apppointments_is_range_busy():
$force_availability = apply_filters( 'app-force_availability', false, $start, $end, $args ); if( $force_availability ){ $is_busy = apply_filters( 'app-is_busy_custom', false, $start, $end, $args ); return $is_busy; }