WC-Local-Pickup/woocommerce-local-pickup-time

Associate Local Pickup Time With "Local Pickup" Shipping Method

Closed this issue ยท 49 comments

Hi I setup my web to do collection and delivery under standard woo-commerce shipping option.
I do have set postcode which I deliver.
On checkout there is always Pickup Time, no matter which option I choose.
It is possible to change the plugin?

@yumthaidelight sorry, I think I missed this issue. I'll start looking into this as soon as I get the next release out.

@yumthaidelight I believe I see the disconnect in how the plugin is working. I need to do some checking but it may in fact be that this plugin was developer prior to WooCommerce including a Local Pickup shipping option. Regardless, I will add this in the 1.4 build to only present the local pickup time to a customer when the "Local Pickup" shipping method is chosen.

yward commented

@timnolte

LAST EDIT: I have solved this as follows:

1- I commented out this rule from your original code:

	// Check if set, if its not set add an error.
		if ( ! $_POST['local_pickup_time_select'] ) {
			wc_add_notice( __( 'Please select a pickup time.', 'woocommerce-local-pickup-time' ), 'error' );
		}

Then I created this snippet to dynamically do everything as follows:
Worth noting that you're free to use the snippet in your next release:




//hide the local pickup thingy
add_action( 'woocommerce_after_checkout_form', 'bbloomer_disable_shipping_local_pickup' );
  
function bbloomer_disable_shipping_local_pickup( $available_gateways ) {
    
   // Part 1: Hide time based on the static choice @ Cart
 
   $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
   $chosen_shipping = $chosen_methods[0];
  if ( 0 !== strpos( $chosen_shipping, 'local_pickup' ) ) {
   ?>
      <script type="text/javascript">
         jQuery('#local-pickup-time-select').fadeOut();
      </script>
   <?php  
   } 
	else {
		?>
		<script type="text/javascript">
		if(jQuery('#local_pickup_time_select').val()) {<?php
			wc_add_notice( __( 'Please select a pickup time.', 'woocommerce-local-pickup-time' ), 'error' );
		?>}   </script>
	<?php
   } 
   
   // Part 2: Hide time based on the dynamic choice @ Checkout
 
   ?>
	<script type="text/javascript">
         jQuery('form.checkout').on('change','input[name^="shipping_method"]',function() {
            var val = jQuery( this ).val();
            if (val.match("^local_pickup")) {
				jQuery('#local-pickup-time-select').fadeIn();	
if(jQuery('#local_pickup_time_select').val()) {<?php
			wc_add_notice( __( 'Please select a pickup time.', 'woocommerce-local-pickup-time' ), 'error' );
		?>}
               } else {
               jQuery('#local-pickup-time-select').fadeOut();
            } 
         });
      </script> -->
   <?php
  
} 
//end of it

@yward thanks for the code block. I'll look at including in an upcoming release.

Any update on this? really need some help with this specifically as Local time pickup should be required when Local Pickup is chose as Shipping Method and Not Required once other shipping is selected.

yward commented

Any update on this? really need some help with this specifically as Local time pickup should be required when Local Pickup is chose as Shipping Method and Not Required once other shipping is selected.

Use my solution detailed here: https://wordpress.org/support/topic/hide-if-shipping-method-isnt-pickup/ until the plugin author implements the code.

I implemented your code above, but the checkout page displays "Please select a pickup time" even if another shipping method was selected on the cart page. If you change your shipping option on the checkout page it seems to update the page correctly, but initially it's incorrect on page load. Any thoughts on how to remedy this?

yward commented

I implemented your code above, but the checkout page displays "Please select a pickup time" even if another shipping method was selected on the cart page. If you change your shipping option on the checkout page it seems to update the page correctly, but initially it's incorrect on page load. Any thoughts on how to remedy this?

You need to disable the default validation in the plugin by commenting the following line:

add_action( 'woocommerce_checkout_process', array( $this, 'field_process' ) );

which is located in the file: public/class-local-pickup-time.php line 137.

so it'll look like:

//add_action( 'woocommerce_checkout_process', array( $this, 'field_process' ) );

And don't worry, it'll still validate if you have the proper method selected, just it'll validate through my code, not the original one.

make sure to use the code i posted in wordpress.org as the one in this thread is a bit outdated.

I tried your Snippet on Wordpress.org and now it says "There has been a critical error on your website." and it breaks the page.

Wish the author would fix this plugin. It's unusable because the customer should not choose a time for picking up for Delivery.

yward commented

I tried your Snippet on Wordpress.org and now it says "There has been a critical error on your website." and it breaks the page.

Wish the author would fix this plugin. It's unusable because the customer should not choose a time for picking up for Delivery.

Are you sure you tried the last one?

here:
https://pastebin.com/83mM80xS
this goes to your functions. php

You also comment the lines in the original plugin that I pointed out.
If you're not familiar with coding and php, it'll be very hard for me to walk you through.

Goodluck.

@yward Thank you. Didn't see that in your comments above. Unfortunately commenting that out didn't seem to help though. I'm still seeing "Please select a pickup time." even when I pick a different shipping option.

I've already got this work but it seems that on my end I need to reverse the content of the condition below

FROM:

 if( $(shipMethodChecked).val() == '<?php echo $no_delivery; ?>' ||$(shipMethodChecked).val() == '<?php echo $no_delivery2; ?>' ){
					showHide('show','#local-pickup-time-select' );
				}
                else{
					showHide('hide','#local-pickup-time-select' );
				}

TO:

 if( $(shipMethodChecked).val() == '<?php echo $no_delivery; ?>' ||$(shipMethodChecked).val() == '<?php echo $no_delivery2; ?>' ){
					showHide('hide','#local-pickup-time-select' );
				}
                else{
					showHide('show','#local-pickup-time-select' );
				}

I've also corrected the input value on my end since I have more than 3 shippings.

yward commented

I've already got this work but it seems that on my end I need to reverse the content of the condition below

FROM:

 if( $(shipMethodChecked).val() == '<?php echo $no_delivery; ?>' ||$(shipMethodChecked).val() == '<?php echo $no_delivery2; ?>' ){
					showHide('show','#local-pickup-time-select' );
				}
                else{
					showHide('hide','#local-pickup-time-select' );
				}

TO:

 if( $(shipMethodChecked).val() == '<?php echo $no_delivery; ?>' ||$(shipMethodChecked).val() == '<?php echo $no_delivery2; ?>' ){
					showHide('hide','#local-pickup-time-select' );
				}
                else{
					showHide('show','#local-pickup-time-select' );
				}

I've also corrected the input value on my end since I have more than 3 shippings.

Great, I'm glad you got it working!

I've already got this work but it seems that on my end I need to reverse the content of the condition below
FROM:

 if( $(shipMethodChecked).val() == '<?php echo $no_delivery; ?>' ||$(shipMethodChecked).val() == '<?php echo $no_delivery2; ?>' ){
					showHide('show','#local-pickup-time-select' );
				}
                else{
					showHide('hide','#local-pickup-time-select' );
				}

TO:

 if( $(shipMethodChecked).val() == '<?php echo $no_delivery; ?>' ||$(shipMethodChecked).val() == '<?php echo $no_delivery2; ?>' ){
					showHide('hide','#local-pickup-time-select' );
				}
                else{
					showHide('show','#local-pickup-time-select' );
				}

I've also corrected the input value on my end since I have more than 3 shippings.

Great, I'm glad you got it working!

Thanks to your code. Really helpful!

I tried your Snippet on Wordpress.org and now it says "There has been a critical error on your website." and it breaks the page.
Wish the author would fix this plugin. It's unusable because the customer should not choose a time for picking up for Delivery.

Are you sure you tried the last one?

here:
https://pastebin.com/83mM80xS
this goes to your functions. php

You also comment the lines in the original plugin that I pointed out.
If you're not familiar with coding and php, it'll be very hard for me to walk you through.

Goodluck.

@yward Looking over that pastebin and it doesn't look like what you posted on wordpress.org. Which one should we use? Also, I have 5 shipping methods. @sharls05 Does that matter?

yward commented

I tried your Snippet on Wordpress.org and now it says "There has been a critical error on your website." and it breaks the page.
Wish the author would fix this plugin. It's unusable because the customer should not choose a time for picking up for Delivery.

Are you sure you tried the last one?
here:
https://pastebin.com/83mM80xS
this goes to your functions. php
You also comment the lines in the original plugin that I pointed out.
If you're not familiar with coding and php, it'll be very hard for me to walk you through.
Goodluck.

@yward Looking over that pastebin and it doesn't look like what you posted on wordpress.org. Which one should we use? Also, I have 5 shipping methods. @sharls05 Does that matter?

You should use the one in the pastebin, and it doesn't matter how many shipping methods you have, it only matters how many of those shipping method is pickup.

If you only have one pickup option, use my code as is, if you have more, let me know and I'll walk you through.

I have one pickup option, but my understanding is that pickup is just a flat rate zero cost shipping method. How do you identify it as a pickup option?

yward commented

I have one pickup option, but my understanding is that pickup is just a flat rate zero cost shipping method. How do you identify it as a pickup option?

No pickup isn't flat rate, pickup has a unique identifier by woocommerce which is local_pickup:* where star is a number, in most cases one default local pickup would be local_pickup:3 also in some expressions local_pickup by its own is identifiable by woocommerce, it's not part of flat_rate

If you skim through my code in the pastebin you'll notice me using those variables.

Also worth noting, my pastebin considers you have 2 local pickup options but will still work with 1 as the expressions are using OR when validating conditions.

Understood. I'm now using your pastebin and that seems to be working well. Thank you!

yward commented

Understood. I'm now using your pastebin and that seems to be working well. Thank you!

My pleasure! Glad I could help.

@yward So I'm having a strange thing happen, if I comment out the code in the original plugin that you suggested, I get a critical error on my site. Leave it, it works, and as far as I can tell is hiding the pickup times if another shipping method is picked. Soo, yay? Although I'm worried something is broken if its doing this.

yward commented

@yward So I'm having a strange thing happen, if I comment out the code in the original plugin that you suggested, I get a critical error on my site. Leave it, it works, and as far as I can tell is hiding the pickup times if another shipping method is picked. Soo, yay? Although I'm worried something is broken if its doing this.

Can you tell me which line are you commenting?
The only line you need to comment is
//add_action( 'woocommerce_checkout_process', array( $this, 'field_process' ) );

@yward

I'm getting complaints that the users can't see the drop down selection. I tested it myself and it's displayed initially for me, but if you toggle the shipping method to something else and then back to local pickup the drop down selection is not displayed. If you refresh the page then it is displayed again. Any idea how to address this?

@yward I wonder if you can help me, please? I added in your snippet to hide the pickup time when a delivery option was selected and it worked a treat, thank you :) Then I added another pickup option for a specific date and it is still showing the choose time dropdown box but I want this to be hidden as it would be if you picked the delivery option.

If it helps clarify things, I have a pickup option set with days Wednesday-Friday for collection, which appear in the dropdown for selection a date/time. I have one specific Saturday that I want to allow people to pickup, so I created a new pickup option for it. But I need to hide the dropdown as it doesn't include Saturdays.

Is there something I can do to the snippet of yours I already added to make the dropdown disappear when the date-specific pickup option is selected?

Yours hopefully... :)

yward commented

@yward

I'm getting complaints that the users can't see the drop down selection. I tested it myself and it's displayed initially for me, but if you toggle the shipping method to something else and then back to local pickup the drop down selection is not displayed. If you refresh the page then it is displayed again. Any idea how to address this?

The dynamic show/hide the drop list uses jQuery, if it's not working for you most likely you have a jQuery conflict, check your console and any try to disable other plugins until you find the conflicting one.

yward commented

@yward I wonder if you can help me, please? I added in your snippet to hide the pickup time when a delivery option was selected and it worked a treat, thank you :) Then I added another pickup option for a specific date and it is still showing the choose time dropdown box but I want this to be hidden as it would be if you picked the delivery option.

If it helps clarify things, I have a pickup option set with days Wednesday-Friday for collection, which appear in the dropdown for selection a date/time. I have one specific Saturday that I want to allow people to pickup, so I created a new pickup option for it. But I need to hide the dropdown as it doesn't include Saturdays.

Is there something I can do to the snippet of yours I already added to make the dropdown disappear when the date-specific pickup option is selected?

Yours hopefully... :)

Hello Vicky,
The problem here is that the plugin and my snippet both look for ALL local pickup shipping methods, not just a specific one.
A work around I would suggest for you to create your other pickup option, the Saturday one, as a flat rate with 0 price in your woocommerce configuration instead of a local pick up. You can still rename it to display as "Pick Up" in front end, but this way the plugin and my code won't recognize it as pick up.

@yward

I want to make sure my implementation is correct. Earlier in this thread you said to comment out these lines:

// Check if set, if its not set add an error. if ( ! $_POST['local_pickup_time_select'] ) { wc_add_notice( __( 'Please select a pickup time.', 'woocommerce-local-pickup-time' ), 'error' ); }

Then later in the thread you said only comment out this:

//add_action( 'woocommerce_checkout_process', array( $this, 'field_process' ) );

Can you confirm?

yward commented

@yward

I want to make sure my implementation is correct. Earlier in this thread you said to comment out these lines:

// Check if set, if its not set add an error. if ( ! $_POST['local_pickup_time_select'] ) { wc_add_notice( __( 'Please select a pickup time.', 'woocommerce-local-pickup-time' ), 'error' ); }

Then later in the thread you said only comment out this:

//add_action( 'woocommerce_checkout_process', array( $this, 'field_process' ) );

Can you confirm?

either one is fine. the first way we actually commented the actual code that rendered the warning, while the second method we commented the action that makes that code work. Doesn't matter which one you use, the 2nd way is just "cleaner" code.

Also this is not related to your issue. That code is responsible for validating that you have selected a pickup time if the chosen method is pickup, it doesn't affect hiding/displaying the pickup time drop list.

Thank you for that confirmation. I've spent most of the last hour troubleshooting this on a staging site. I've disabled nearly all plugins, but the problem persists. I'm not seeing any JQuery errors in the console. The only remaining plugins activated are WooCommerce and plugins to give me enough shipping options to test:

WooCommerce Services
Jetpack
Code Snippets
WooCommerce Local Pickup Time Select
WooCommerce PayPal Checkout Gateway

Additionally, I've disabled all other code snippets. I have now also re-activated a different shipping plugin and deactivated these two which also did not help:

WooCommerce Services
Jetpack

yward commented

Additionally, I've disabled all other code snippets. I have now also re-activated a different shipping plugin and deactivated these two which also did not help:

WooCommerce Services
Jetpack

Can you please send the code you have in your functions.php?

That didn't paste so well. Try this:

https://pastebin.com/JnAUPKkx

The rest of my functions.php is default from the theme. I make all additions using Code Snippets, but here's my actual functions.php that I do not edit

https://pastebin.com/1b9tv8Ph

yward commented

The rest of my functions.php is default from the theme. I make all additions using Code Snippets, but here's my actual functions.php that I do not edit

https://pastebin.com/1b9tv8Ph

Please try adding the code in your functions.php file and see if it works, I do not have your code snippets plugin and never used it, so cannot really support it. It's a good practice generally to avoid using plugins you don't need, add code snippets is as easy as pasting them to the end of your functions.php files, no plugin needed for that.

I put it in my functions.php as requested and it still doesn't work. When I tried doing so I received a "Scrape nonce check failed" when trying from the theme editor. Not sure why. I had to use web hosting tools to modify the functions.php directly.

I agree with your statement on not using plugins you don't need. That being said the Code Snippets plugin is something I use on all my sites and find it extremely helpful to organize extra code. There isn't much if any overhead in using it, it's very popular, and works quite well.

yward commented

I put it in my functions.php as requested and it still doesn't work. When I tried doing so I received a "check nonce failed" when trying from the theme editor. Not sure why. I had to use web hosting tools to modify the functions.php directly.

I agree with your statement on not using plugins you don't need. That beings said the Code Snippets plugin is something I use on all my sites and find it extremely helpful to organize extra code. There isn't much if any overhead in using it, it's very popular, and works quite well.

the snippet doesn't use nonce at all, the error is irrelevant to it. You can trace the error by turning on WordPress debugging in your config.php and you'll find they error file in wp-content folder.

From following this topic and Wordpress.org forums I understood that the author is about to implement this functionality into an upcoming version so it'd spare you having to go through all the debugging.
I'm using my snippet on a production site with 100+ daily orders since November last year and it seems stable,but sadly WordPress setups differ entirely, different themes and plugins so some extra work might be needed in case of conflicts.
Anyhow, before you go through debugging, as a last solution try installing "jQuey Updater" plugin and see if it solves you jQuey error.
If not feel free to post your debug logs here and I'll try my best to help.

Hi there. I've implemented your code, but it's not validating the selection......so if Local Pickup is selected, and no date/time is selected, it simply passes through to payment without any validation.

Using Woo-Commerce

1- I want to Implement Per Product Individual Shipping Cost In Local City,Within State,Out of State. Example Suppose I have Order a Product INR 100, Order in a City = Shipping Cost Flat Price 20,Within State = Shipping Cost Flat Price 30, Out of State = Flat Price 40..
2- If Total Product in Cart = INR 500 Then eligible for Shipping Otherwise Show message Not eligible for Shipping
& Insist Customer to Add More Product for Shipping Process...
Please Help Can it Possible to Use this Condition.....

yward commented

Using Woo-Commerce

1- I want to Implement Per Product Individual Shipping Cost In Local City,Within State,Out of State. Example Suppose I have Order a Product INR 100, Order in a City = Shipping Cost Flat Price 20,Within State = Shipping Cost Flat Price 30, Out of State = Flat Price 40..
2- If Total Product in Cart = INR 500 Then eligible for Shipping Otherwise Show message Not eligible for Shipping
& Insist Customer to Add More Product for Shipping Process...
Please Help Can it Possible to Use this Condition.....

Your request has nothing to do with this plugin, I advise you take a look at "Booster" plugin for woocommerce, it allows you to set similar conditions.

+1 vote for this enhancement

For those still looking for a work-around, I can confirm that the code suggested at the end of this support thread on the WordPress forum still works:
https://wordpress.org/support/topic/hide-if-shipping-method-isnt-pickup/
However, instead of commenting a line in the plugin original file, I would recommend un-registering the action like this:

if ( class_exists( 'Local_Pickup_Time' ) ) {
	remove_action( 'woocommerce_checkout_process', array( Local_Pickup_Time::get_instance(), 'field_process') );
}

Popping this here in case it's helpful... I came here via:
https://wordpress.org/support/topic/disable-pickup-time-for-virtual-products/

Basically, I wanted to hide the pickup time box when the basket only contains virtual items. I didn't want to do this with jquery after the fact, because it has the potential to cause issues where javascript is disabled or when the jquery takes a while to load. As there's no existing solution that suits, here's one I put together that uses native hooks:

function jt_cart_has_physical_items() {
	$has_physical = false;
	foreach ( WC()->cart->get_cart() as $cart_item ) {
		if ( !$cart_item['data']->is_virtual( ) ) {
			$has_physical = true;
			break; // no point continuing once we've found one physical item
		}
	}
	return $has_physical;
}

add_action( 'woocommerce_before_checkout_form', function() {
	if ( jt_cart_has_physical_items() === false ) {
		// find and unhook the time_select dropdown
		$time_select_hooked_location = apply_filters( 'local_pickup_time_select_location', 'woocommerce_after_order_notes' );
		remove_action( $time_select_hooked_location, [ Local_Pickup_Time::get_instance(), 'time_select' ] );
	}
} );

add_action( 'woocommerce_checkout_process', function() {
	if ( jt_cart_has_physical_items() === false ) {
		// remove the processing of the field
		remove_action( 'woocommerce_checkout_process', [ Local_Pickup_Time::get_instance(), 'field_process' ] );
		remove_action( 'woocommerce_checkout_update_order_meta', [ Local_Pickup_Time::get_instance(), 'update_order_meta' ] );
	}
}, 1 );

(this can be placed in your theme functions.php or similar)

Sorry to comment twice in a row (not sure of etiquette) but I've had to modify the code today as I realised that the pick-up time dropdown was showing even when a user had selected Shipping - which I'm guessing is the issue the OP had. I've now amended the code to check the chosen shipping method and hide the pick-up time dropdown if the word "shipping" is found.

NB: this works because my alternative to pick-up is called "Free Shipping". If yours is called e.g. Free Delivery, or something like that, you'd need to change the word it's checking for here: if ( stripos( $chosen_methods[0], 'shipping' ) ) {

This only hides the pick-up time box if the user selects shipping at the basket level. If the user selects pick-up on the basket, and then changes to shipping at checkout, the pick-up time dropdown remains. There's probably a way to check for this when WooCommerce does its auto-update address thing but that's outside of the scope of my changes at this time.

function jt_cart_has_physical_items() {
	$has_physical = false;

	foreach ( WC()->cart->get_cart() as $cart_item ) {
		if ( !$cart_item['data']->is_virtual( ) ) {
			$has_physical = true;
			break; // no point continuing once we've found one physical item
		}
	}
	return $has_physical;
}

function jt_customer_picked_shipping() {
	$has_shipping = false;
	$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
	if ( stripos( $chosen_methods[0], 'shipping' ) ) {
		$has_shipping = true;
	}
	return $has_shipping;
}

add_action( 'woocommerce_before_checkout_form', function() {
	if ( jt_cart_has_physical_items() === false || jt_customer_picked_shipping() === true ) {
		// find and unhook the time_select dropdown
		$time_select_hooked_location = apply_filters( 'local_pickup_time_select_location', 'woocommerce_after_order_notes' );
		remove_action( $time_select_hooked_location, [ Local_Pickup_Time::get_instance(), 'time_select' ] );
	}
} );

add_action( 'woocommerce_checkout_process', function() {
	if ( jt_cart_has_physical_items() === false || jt_customer_picked_shipping() === true  ) {
		// remove the processing of the field
		remove_action( 'woocommerce_checkout_process', [ Local_Pickup_Time::get_instance(), 'field_process' ] );
		remove_action( 'woocommerce_checkout_update_order_meta', [ Local_Pickup_Time::get_instance(), 'update_order_meta' ] );

	}
}, 1 );

@timnolte
I seem to have a problem on the checkout page. When I change to delivery option and back to local pickup the pickup time does not change accordingly. If I cset the pickup or delivery options in the cart, the checkout page displays correctly.

@timnolte where can I get the latest version as a compiled plugin?

@000x2a sorry for the delay on getting the next release out. I just have some final cleanup to do so that I can get the release out with the new features and fixes. I will look to get it released this week.

Thanks @timnolte that sounds great!