Support

Home Forums Event Espresso Premium Appointment Booking

Appointment Booking

Posted: August 27, 2021 at 3:27 am


motio

August 27, 2021 at 3:27 am

Hi guys,

our client wants an event, where people could book 15 Minutes Timeslots on 3 specific days.
My solution would be to make one event, set the date times (one datetime = 15 Minute slot) and have so many Tickets as date times where one ticket is connected with one datetime. Afterwards I would make a custom view, where appointments are could be seen by day.
Because this would be a timeconsuming project, I wanted to ask you if this is the best approach or maybe I miss something, that would make my life easier.

I know have to do the custom development myself but I was hoping, if you could point me in the right direction.


Tony

  • Support Staff

August 31, 2021 at 8:43 am

Hi there,

Currently, the method you mentioned above is the only way to set this up within Event Espresso. Event Espresso isn’t really designed to be an ‘appointment’ based system as it kind of works backwards to how appointments would work (which is why, as you’ve found, you need to create individual datetimes for the above).

Due to the number of datetimes and tickets required for this to work I would advise you split the event into individual days rather than one single event.

This is because each day (assuming an 8 hour day) will need 32 datetimes and therefore 32 tickets (one for each timeslot/datetime), multiply that by your 3 days and you’ll have at least 192 ‘entities’ within a single event. That’s going to slow down the queries both on the frontend and the admin a fair amount, splitting the datetimes into 3 days will help.

If you are looking to output the event using custom code you could reduce the frontend loading time and pull specific datetimes/tickets if the user is selecting them before they hit the event itself but it really depends on what you are trying to do.

There is one issue you will likely run into with both of the above solutions and that is you’ll likely hit the max_input_vars limit set on your server with that number of entities on your event(s). The default value for max_input_vars is 1000 and that allows you to create roughly 20 datetimes and tickets within an event. You can contact your host and request they increase the limit if needed (a notice will appear in the event editor once you hit the limit on your server).


motio

September 1, 2021 at 4:40 am

Hi Tony,

thank you for the information. For this purposes, we have a second plugin but like other plugin I was always missing features that event espresso has. The only reason against event espresso in these scenario was the time afford of the input for that event, especially if there were multiple days. I recently found an chrome extension which can search and replace text in forms. That way I only need one event as a template and can duplicate it and change the date via the chrome extension.

Thank you for the suggestion of the separation of days. This way I can show more easily one what day there free spots.

I haven’t got into ajax as a self-taught-developer because the technical part is only a small part of my job. So far I just hide the info (display:none) and show the selected items with javascript again. But for the experience of the user, ajax would be the better solution.

Thank you also for the warning with the “max_input_vars”. We ran in that already a time ago and fortunately have a dedicated server so we could changed that ourselves.

I have one followup question, which is bothering me.
Every datetime (time slot) should have 3 spots. Because the event itself is an 1 on 1 setting, every spot/attendee get an MS Teams Link for that event.
For the previous events (group with one room) I added a custom field to that event and made a shortcode in the message which takes that custom field. That way every event has its own participation link.
For the scenario with 3 rooms I have two approaches:
1. I make 3 custom fields with individuals room link and have 3 spots per datetime. I build a logic that checks how many attendees are already connected that specific datetime and if there is an attendee it will get the second custom field link and if there are two it gets the third.
The problem I see with this approach is, that it would work great until somebody has to cancel his or her appointment and there is already second attendee for that datetime. I don’t see a logic that wouldn’t create a double booking for a room.
Do you see a simple solution for that? Maybe could think of an ID that I could check for that purpose.
2. The second approach is to have 3 identical events with one spot per datetime. Every event has one custom field with a link. In the custom output it would check if the datetime is available. If not it goes to the same datetime of the next event.

I like the first approach a lot more, but the logic must be bulletproof.

I am thankful for every information. And thank you for the great support. In my opinion event espresso is the best time booking product for wordpress.

Beste Grüße (best regards)
Thomas


Tony

  • Support Staff

September 2, 2021 at 5:52 am

This is a little confusing tbh, in the opening post you have:

My solution would be to make one event, set the date times (one datetime = 15 Minute slot) and have so many Tickets as date times where one ticket is connected with one datetime.

So a single DateTime per 15minutes slot booking, right?

But now you have 3 slots on a single datetime?

I think this may provide some context for my questions above:

For the previous events (group with one room) I added a custom field to that event and made a shortcode in the message which takes that custom field. That way every event has its own participation link.
For the scenario with 3 rooms I have two approaches:

So you now have 3 rooms which you are trying to accommodate within a single event? Is that correct?

(I’m trying to make sure I follow what you are doing so I don’t send you down the wrong path)

Every datetime (time slot) should have 3 spots. Because the event itself is an 1 on 1 setting, every spot/attendee get an MS Teams Link for that event.

A ‘Datetime’ is an instance of the event, so each of your datetimes is the timeslot and if it’s a 1 on 1 setting I’m not sure why you have 3 ‘slots’ (qty?) for a single datetime?

Do you see a simple solution for that? Maybe could think of an ID that I could check for that purpose.

I’m not 100% sure I follow, but I’ll try to answer.

Assuming you are checking for ‘Approved’ registrations (those are the only registrations that apply to the sold values) then you should just be able to check the number of Approved registrations on the DateTime itself.

There are sold counts on the datetime which will be updated if a registration is cancelled, so using $datetime->sold() (assuming you have the datetime object) should give you the correct value.

2. The second approach is to have 3 identical events with one spot per datetime. Every event has one custom field with a link. In the custom output it would check if the datetime is available. If not it goes to the same datetime of the next event.

I like the first approach a lot more, but the logic must be bulletproof.

In my opinion (based on what I’m getting from the above) then Option 2 sounds like a much simpler set up and would likely be the one I use.

Option 1 sounds a lot more complicated here and as you mentioned, your logic for the correct links etc would need to be battle-tested. However, as mentioned above I’m not entire sure I follow what you are trying to do so can’t a for sure if either will work right now.


motio

September 2, 2021 at 6:18 am

Thank you for your help. And I am sorry for the confusion. As I was reading your answer, I got a new idea for the possible solution.

Each datetime hast 3 available spots and is connected to 3 Tickets. A Ticket has one available spot and contains the MS Teams link in the description of the ticket. So each event has approx 32 datetimes and 96 tickets.

My only concern is the amount of tickets per event. Are there any limitation for the ticket count or will 96 tickets cause any other negative effect?


Tony

  • Support Staff

September 2, 2021 at 9:01 am

Within Event Espresso there isn’t a limit to how many tickets you can assign, however, it does increase the queries on the page so depends if your server can handle the load.

However, the only real way you’ll be able to know if it’s going to be an issue is to create the event and test what happens with that many tickets.

I’m assuming you’ll be filtering the ticket selection to many it easier for your users to select an option rather than scrolling through all 96 tickets?


motio

September 9, 2021 at 4:08 am

Hi Tony,

my client changed the schedule a bit, so I have “only” 60 Tickets. I had to put up the max_input_vars quit a bit but it is working really great and I am happy that I can use event espresso for those kinds of project from now on.

I have a question for the form. What is the “row” value needed for? Is it essential for submitting the form?
<input type="hidden" name="tkt-slctr-rows-'.$event_id.'" value="'.$ticket_rows.'">

For those who are interested and would like a starting point, here is how it looks like and the first draft of the code.

Appointment booking

function ee_ticketselector_button ($event_url, $event_id, $ticket_id, $ticket_rows){
  $email_input_id = time().'.'.rand(1000,9999);
  return '
  <form method="POST" action="'.$event_url.'" name="ticket-selector-form-'.$event_id.'">
        <input type="hidden" name="ee" value="process_ticket_selections">
        
        <input type="hidden" name="noheader" value="true">
        <input type="hidden" name="tkt-slctr-return-url-'.$event_id.'" value="'.$event_url.'#tkt-slctr-tbl-'.$event_id.'">
        <input type="hidden" name="tkt-slctr-rows-'.$event_id.'" value="'.$ticket_rows.'">
        <input type="hidden" name="tkt-slctr-max-atndz-'.$event_id.'" value="1">
        <input type="hidden" name="tkt-slctr-event-id" value="'.$event_id.'">

        <input type="hidden" name="tkt-slctr-qty-'.$event_id.'[]" value="1">
        <input type="hidden" name="tkt-slctr-ticket-id-'.$event_id.'[]" value="'.$ticket_id.'">

        <input style="display:none" type="email" id="tkt-slctr-request-processor-email-'.$email_input_id.'" name="tkt-slctr-request-processor-email" value="">
        <input id="ticket-selector-submit-'.$event_id.'-btn" class="" type="submit" value="Termin buchen" data-ee-disable-after-recaptcha="true">
    </form>';
}

function check_event_datetime_ticket($var) {	
  if ($var->get('TKT_sold') == 0 && $var->reserved() == 0) {
    return true;
  } 
}

//* Adds table with datetimes after content
add_action('AHEE_event_details_after_the_content', 'custom_ticket_selector_gt');
function custom_ticket_selector_gt() {
  global $post;
  $get_event_tags = array_map(function($o) { return $o->name ;}, get_the_tags() );
 
  if (in_array('GT', $get_event_tags )) {
    
    $event = EEH_Event_View::get_event();
    $event_datetimes = $event->datetimes_in_chronological_order();
    $event_id = $post->ID;
    $event_ticket_count = $event->tickets_on_sale();
    $seats_available = $event->spaces_remaining() > 0 ? true : false ;
    $loop_index = 1;

    echo '<table>';
      foreach ($event_datetimes as $event_datetime_key => $event_datetime) {
        if ($seats_available) {
          if ($event_datetime->spaces_remaining() > 0) {
            $tickets_filtered = reset(array_filter($event_datetime->tickets(), 'check_event_datetime_ticket'));
            $registration_message = ee_ticketselector_button ($event->get_permalink(), $event_id, $tickets_filtered->ID(), $event_ticket_count);
          } else {
            $registration_message = 'Ausgebucht';
          }
        } else {
          $registration_message = 'Ausgebucht';
        }
        
        if ($loop_index % 2 != 0) {
          echo '<tr class="ee_gt_table_tr"> <td class="ee_gt_table_clock"><span class="ee_gt_table_clock_hour">'.$event_datetime->start_time('G').'</span><span class="">00</span></td> <td id="" class="ee_gt_table_td"><div id="" class="ee_gt_table_datetime">';
        }
        echo  '<div id="" class="ee_gt_table_datetime_child">
                <div id="" class="">
                  <span class="dashicons dashicons-clock"></span><span class="">'.$event_datetime->start_time('G:i').' - '.$event_datetime->end_time().' Uhr </span></div><div id="" class="ee_gt_table_datetime_button"><span>'.$registration_message.'</span>
                </div>
              </div>';
        if ($loop_index % 2 == 0) {
          echo '</div></td></tr>';
        }
        $loop_index++;
      }
    echo '</table>';

    echo '
          <style type="text/css">

            .event-datetimes, .post-navigation{
              display: none !important;
            }

            .ee_gt_table_tr{
              margin-bottom: 10px;
              padding-bottom: :   10px !important;
            }
            
            .ee_gt_table_td{
              padding:   0px !important;
            }

            .ee_gt_table_clock{
              vertical-align: top;
              margin: 0px;
              padding:0px;
              padding-left: 5px;
            }

            .ee_gt_table_clock_hour{
              font-size: 30px;
              font-weight: normal;
            }

            .ee_gt_table_datetime{
              display: flex;
              flex-flow: row wrap;
              justify-content: space-around;
              align-items: center;
              min-width: 400px;
              margin:   10 !important;
              margin-bottom: 10px;
            }

            .ee_gt_table_datetime_child {
              display: flex;
              flex-flow: row wrap;
              justify-content: space-between;
              align-items: center;
              min-width: 400px;
              min-height: 57px !important;
              background-color: #F0F0F0;
              margin-top:   10px;
              margin-left:   10px;
              margin-right:   10px;
              padding: 10px;
            }

            .ee_gt_table_datetime_button {
              min-width: 190px;
              text-align: center;
            }
            </style>
    ';  
  }
}

You must be logged in to reply to this support post. Sign In or Register for an Account

Event Espresso