Can customers schedule two services at once?

My client runs a laundry service. We are using Appointments+ to schedule pickup and delivery services. I have the pickup all set, but now need to setup delivery. They want it in the same window, if possible. If NOT possible, then we'd like to have the first submit button (when scheduling pickup) to take them to a calendar to schedule delivery. Ideally, the schedule would follow rules to allow a certain period of working hours between the two. Ie, if pickup is at 8am, then delivery can be same day at 6pm. But if pickup is at noon, delivery cannot be until 8am the next morning. Any help would be appreciated.

  • Jack Kitterhing

    Hi there @Kelly,

    Hope you're well today and thanks for your question.

    I've just been speaking with the lead developer and currently this isn't possible, though I've added this as a feature request.

    One work around currently would be to use the following shortcodes on one page

    [app_monthly_schedule service="<PICKUP_ID>"]
    <br />
    [app_monthly_schedule service="<DELIVERY_ID>"]

    And use the MarketPress integration, so that a customer can add appointments to the cart and checkout.

    But the pickup service, wouldn't replicate the delivery service hours, so you can set the hours to be the same, but then the end user must pick the correct hours.

    Replace PICKUP_ID and DELIVERY_ID with the actual ID of those services, such as service="1"

    Thank you!

    Kind Regards
    Jack.

  • Kelly

    Having attempted to setup MarketPress, I am thinking I would much rather have my setup like this:

    1. customer schedules pickup, clicks confirm
    2. popup window tells them we have their appointment
    3. they click OK, then instead of reloading the schedule pickup page, it takes them to the schedule delivery page

    This seems like it should be a straightforward change to the code, I'm just not sure where. Am I wrong? Can you tell me where I adjust the behavior of that OK button?

    Alternatively, the "confirm this appointment" button could record their request and then take them to the delivery page...

    I don't fancy setting up a-whole-nother plugin when we aren't really using any of the other functionality.

    Thanks again for your help.
    ~KJ

  • Kelly

    I have figured out how to redirect the customer after they schedule pickup, but I would like them to go to a confirmation page or thank you page after they schedule delivery. Is it possible to have 2 redirects on the app_confirmation shortcode?

    I added the redirect function from scheduling on page 1 to scheduling on page 2, but it appears I can't redirect from scheduling on page 2 to a thank you page.

    This is turning into kind of a deal breaker. :slight_frown:

    Is there a way I can talk to someone about this? I checked the live chat schedule for this week, and it doesn't appear Ve will be hosting any, as far as I can tell.

  • Jack Kitterhing

    Hi there @Kelly,

    Hope you're well today and thanks for the additional information.

    At the moment, that can only have one redirect and not two that shortcode, but perhaps we can do another redirect anyway, can I have the URL of the page your directing to first, then the page you want to redirect to after that page please?

    Ve has live chats on Tuesday, though I've also flagged him on this thread as well :slight_smile:

    Thanks!

    Kind Regards
    Jack.

  • Kelly

    You are a legend - thank you!!

    The first confirm button should redirect to:

    http://islandfreshlaundry.com/dev/delivery/

    and the second should redirect to:

    http://islandfreshlaundry.com/dev/thanks/

    When we go live, the url will change from http://islandfreshlaundry.com/dev/ to http://islandfreshlaundry.com/ - can you use a relative url?

    Many, many thanks!
    ~KJ

    PS: Please excuse any weirdness in how the site looks - it is still under construction. :slight_smile:

  • Jack Kitterhing

    Hi there @Kelly,

    Hope you're well today, just wanted to confirm on the redirects as you mentioned two separate confirmation buttons.

    So once they have scheduled the pickup, they get redirect to schedule a delivery, then once they done that it should redirect to the thanks page, correct? :slight_smile:

    1: Currently not possible, though would make a nice addition :slight_smile:

    2: Sure, are you using the additional fields add-on? :slight_smile: Please advise.

    Thanks!

    Kind Regards
    Jack.

  • Kelly

    Hi, Jack...

    Yep, that's the process. I have the calendars on separate pages - one for pickup, one for delivery, so there is a confirmation button when they schedule each one. Does that make sense? You are correct about the logic.

    1. Alright. We'll be fine with 2 emails.

    2. Great! We are using the additional fields add-on. Currently we have 3 additional fields, two of which are required. We need zip code and # of bags to be required on the first form, but not on the second.

    Can you tell me what you think the time frame might be? I am under pressure to get this done promptly since yours is the second plugin I tried (I am now a believer!!!). I appreciate your time and effort!

    ~KJ

  • Jack Kitterhing

    Hi there @Kelly,

    Thanks for the confirmation, would you mind if I book a couple of test appointments for testing? :slight_smile:

    I'm thinking of a couple of ways to do this, We could do a time delay redirect, i.e, book pickup, > redirect to delivery, on click redirect to thank you page, the time delay would come in within the first redirect.

    On the fields, you can make a field not required, but the fields must be separate, i.e, you can't the same field and have it required on one but not the other, so you might need to create the same field twice :slight_smile:

    Thanks!

    Kind Regards
    Jack.

  • Jack Kitterhing

    Hi @Kelly,

    Try this,

    function app_redirect ($script) {
    	$page = get_page_by_path("appointment-2");
    	$url = ($page && !empty($page->ID))
    		? "'" . get_blog_permalink(get_current_blog_id(), $page->ID) . "'"
    		: 'app_location()'
    	;
    	return str_replace("window.location.href=app_location()", "window.location.href={$url}", $script);
    }
    add_filter('app_footer_scripts', 'app_redirect');

    Replace appointment-2 with the slug of your delivery page, so this will redirect from the pickup page to the delivery page :slight_smile:

    Thank you!

    Kind Regards
    Jack.

  • Kelly

    Hmm... just tested the code. I am able to schedule the pickup, but it takes me back to the pickup page. What do you think?

    I changed this:

    function app_redirect( $script ){
        return str_replace("window.location.href=app_location()", "window.location.href='http://islandfreshlaundry.com/dev/delivery'", $script);
    }
    add_filter( 'app_footer_scripts', 'app_redirect' );

    to this:

    function app_redirect ($script) {
    	$page = get_page_by_path("http://islandfreshlaundry.com/dev/delivery");
    	$url = ($page && !empty($page->ID))
    		? "'" . get_blog_permalink(get_current_blog_id(), $page->ID) . "'"
    		: 'app_location()'
    	;
    	return str_replace("window.location.href=app_location()", "window.location.href={$url}", $script);
    }
    add_filter('app_footer_scripts', 'app_redirect');
  • Kelly

    Thank you, @Jack. I have tried the folloing variations, and still come back to schedule a pickup instead of delivery:

    /delivery/ (which seems to cause problems with using the monthly app calendar)
    /delivery (which *sometimes* causes problems using the monthly app calendar)
    ./delivery
    ./delivery/
    ../delivery
    /dev/delivery

    In all cases where I was able to use the app calendar, I was redirected to schedule a pickup instead of moving forward to schedule a delivery time. :slight_frown:

    Thoughts?

  • Jack Kitterhing

    Hi there @Kelly,

    Hope you're well today, I've discussed this with the lead developer and this should work :slight_smile:

    function app_location_conditional () {
    if (!is_singular()) return false;
    global $post;
    $location = false;
    if (259 == $post->ID) $location = '/home';
    else if (184 == $post->ID) $location = '/test';
    if (empty($location)) return false;
    echo <<<EOAppLocationReplacementJs
    <script>
    (function ($) {
    $(function () {
    if (window.app_location) window.app_location = function () {
    return "{$location}";
    }
    });
    })(jQuery);
    </script>
    EOAppLocationReplacementJs;
    }
    add_action('wp_footer', 'app_location_conditional', 999)

    Just replace the /home and /test with your actual pages :slight_smile:

    But not the full URL, any issues, let me know :slight_smile:

    Thanks!

    Kind Regards
    Jack.

  • Kelly

    Hi @Jack.

    I hope all is well with you this morning. I'm watching the snow come down and wondering how many inches I will have to hike thhrough to get to the WordPressNYC meetup tonight!

    So, I added the above code to my functions.php file for the theme (it occurs to me I should verify that I'm putting that in the right file). I had to add a closing ; on the last line, and I swapped out the slugs, but otherwise I added it as is. After clicking to confirm the appointment on the "schedule a pick up page", I still end up at the "schedule a pick up page". sigh.

    I want to make sure that I'm replacing the slugs above (/home, /test) correctly. I should be replacing those with the slugs of the pages I want to redirect TO, right? so the 259 should be /delivery and 184 should be /thanks? Do I need to verify hat 259 and 184 are the correct post IDs? If so, should they be the post IDs of the pages where I'm *starting*? Ie, if I'm ON page with post ID 259, redirect to /delivery?

    Many thanks - I'm obviously only marginally familiar with php (I will be taking a class next month!!). I can read between the lines, but I don't always know what I'm reading. :slight_smile:

    ~KJ

  • Kelly

    IT WORKS!!!!!!!!!!!! I made the changes I asked about above, and it works. (also, need to use the subfolder + slug, as so: /dev/slug ... is that subfolder part of the slug? the wordpress and site addresses include it, so I thought it would be redundant?). Anyway, it works!

    So now... back to less pressing questions. :slight_smile:

    You indicated above that I could duplicate fields in order to have a field required on one page, but not on the other. Here's the exact thing that is happening:

    I fill in all the required fields (the default & custom fields that I added) on the pick up page. When I roll to the delivery page, all the default fields are populated, but the custom fields are blank. This makes sense to me even though I don't know the exact logic behind it. If I try to submit the form that way, it forces me to fill in those custom fields. That's great, except the customer has already filled them in.

    How can I show the non required duplicate custom fields on the second signup page (the delivery page) OR how can I get it to populate those fields when it rolls over?

  • Jack Kitterhing

    Hi there @Kelly,

    Hope you're well today and hope there wasn't too much Snow to get to the meetup! :slight_smile:

    Awesome, glad it works, that's fantastic and yep looks like I missed the ; on the last line, oops, good spot! :slight_smile:

    Just to clarify we're trying to post the data from the first form onto the second form, so they don't have to fill it in twice, correct? :slight_smile:

    Thanks!

    Kind Regards
    Jack.

  • Kelly

    Thank you, sir. As it turned out, my kid's after school program was closed due to snow, which threw my whole afternoon out of whack! But I'm back on the case today. :slight_smile:

    So... a few things:

    1. The whole redirect thing worked... until I installed and activated the membership plugin. Turns out I need a way for folks to login after all. They don't want it to be required - only if folks want to pay online after the fact (meaning not part of the signup process). So I am creating two membership levels - one free registered level and a free guest level (the default). Folks who are registered will see the ability to pay their bill, folks who aren't registered won't see that.

    2. Yes, we'd like to post the data from the first form onto the second form so they don't have to fill it in twice.

    3. My client is hoping to have this whole thing wrapped up by the end of the month. Really kicking myself for trying and waiting around as long as I did with the other plugin I tried before I signed up for wpmudev. Alas, I did and now I am here - better late than never. I really appreciate all the help you guys are sending my way.

    ~KJ

  • Jack Kitterhing

    Hi there @Kelly,

    Hope you're well today, sorry about the delay.

    Glad that plugin works great! :slight_smile:

    On passing the data, we can technically pass the variables using $_POST, but the issue with this, is, it's a A+ form right? So we need to take into consideration WordPress and Appointments+, let me check with the lead developer @Vladislav here on this :slight_smile:

    Thanks for your patience here.

    Kind Regards
    Jack.

  • Vladislav

    Hello,

    Actually, let me just ask something first :slight_smile: to make sure we're not looking into an issue. When your visitors schedule an appointment, a cookie is set for them with most of the info they already entered - except for notes and additional fields, the rest should be preserved. This will then be used to populate the form in the future, for as long as the cookie lives. Is this not what's happening?

  • Kelly

    Thanks, @Jack. Hi, @Vladislav! Yes, the cookie is working as you describe it - they are hoping to also capture the additional info. It's a little complicated. We have added 3 extra fields:

    We want this stored longterm: Zip code
    Ideally, we want to save these two for the duration of their time on the site - maybe half an hour or an hour: # of Bags and Payment Method

    If the last two must be stored in the same cookie as the first, it's not the end of the world. :slight_smile:

    I was hoping that the membership plugin's user info might populate this form, but I suspect that would be a whole different job, and one that we don't really have time for.

    Many thanks for your attention to this. I appreciate it.
    ~KJ

  • Vladislav

    Hello,

    While this isn't exactly trivial, it should certainly be doable. We'll implement it in two steps - the first step is to intercept at the moment when a new appointment is created and set a cookie with additional fields values recorded, like this:

    function my_app_save_additional_fields ($app_id) {
    	global $appointments;
    	$fields = !empty($appointments->options['additional_fields']) ? $appointments->options['additional_fields'] : array();
    	if (empty($fields)) return false;
    	$cookie = array();
    	foreach ($fields as $field) {
    		if (empty($field['required'])) continue;
    		$name = preg_replace('/[^-_a-z0-9]/', '', strtolower($field['label']));
    		$cookie[$name] = $_POST[$name];
    	}
    	if (empty($cookie)) return false;
    	$expire = $appointments->local_time + 3600 * 24 * ( $appointments->options["app_limit"] + 365 );
    	$cookiepath = defined('COOKIEPATH') ? COOKIEPATH : '/';
    	$cookiedomain = defined('COOKIEDOMAIN') ? COOKIEDOMAIN : '';
    	@setcookie("wpmudev_appointments_additional_fields", serialize($cookie), $expire, $cookiepath, $cookiedomain);
    }
    add_action('app_new_appointment', 'my_app_save_additional_fields');

    This will check additional fields and, if any, set the cookie with the passed in values. Next up, we will need to make use of those values and pre-populate the fields. We will do this dynamically, with some javascript, but we'll also use some PHP to inject the script in proper place, check the cookie etc, like this:

    function my_app_populate_additional_fields () {
    	if (empty($_COOKIE['wpmudev_appointments_additional_fields'])) return false;
    	$data = unserialize(stripslashes($_COOKIE['wpmudev_appointments_additional_fields']));
    	if (empty($data)) return false;
    	?>
    <script type="text/javascript">
    (function ($) {
    var field_data = <?php echo json_encode($data); ?>;
    function populate_fields () {
    	setTimeout(function () {
    		var $fields = $(".appointments-field-entry");
    		$.each(field_data, function (idx, el) {
    			var $field = $fields.filter('[data-name="' + idx + '"]');
    			if ($field.length) $field.val(el);
    		})
    	}, 300);
    }
    
    $(document).ajaxSend(function(e, xhr, opts) {
    	if (!opts.data) return true;
    	if (!opts.data.match(/action=pre_confirmation/)) return true;
    	xhr.success(populate_fields);
    });
    })(jQuery);
    </script>
    	<?php
    }
    add_action('app-footer_scripts-after', 'my_app_populate_additional_fields', 99);

    This part will actually load up and apply your data to the form each time a confirmation form is loaded. You can apply this by adding both of these snippets to your theme's functions.php or, possibly better yet, in a mu-plugin.

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.