Disable a woocommerce delivery method on weekends and cut off time in the week - wordpress

Based on Hide specific shipping method depending on day time in WooCommerce answer code, I am looking to only allow Monday to Friday before 3pm.
//hide shipping method based on time
add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_time', 10, 2 );
function hide_shipping_method_based_on_time( $rates, $package )
{
// Set your default time zone (http://php.net/manual/en/timezones.php)
date_default_timezone_set('Europe/London');
// Here set your shipping rate Id
$shipping_rate_id = 'flat_rate:29';
// When this shipping method is available and after 2 PM
if ( array_key_exists( $shipping_rate_id, $rates ) && date('H') > 14 ) {
unset($rates[$shipping_rate_id]); // remove it
}
return $rates;
}

You will use the date() function with N parameter to handle the day of the week and H parameter to handle hours as follow to disable a specific shipping method on weekends and after 3 PM the weekdays:
// Hide shipping method based on the day of the week and time
add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_day_of_the_week_and_time', 10, 2 );
function hide_shipping_method_based_on_day_of_the_week_and_time( $rates, $package )
{
// Set your default time zone (http://php.net/manual/en/timezones.php)
date_default_timezone_set('Europe/London');
// Here set your shipping rate Id
$shipping_rate_id = 'flat_rate:29';
// When this shipping method is available and after 2 PM
if ( array_key_exists( $shipping_rate_id, $rates )
&& ! ( date('H') <= 15 && ! in_array(date('N'), [6,7]) ) ) {
unset($rates[$shipping_rate_id]); // remove it
}
return $rates;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Clearing shipping caches:
You will need to empty your cart, to clear cached shipping data
Or In shipping settings, you can disable / save any shipping method, then enable back / save.

Related

Hide express paid shipping options when stock of the product is 0 or less than 0 (backorder cases) in Wocommerce checkout

I set 2 methods of delivery:
Express shipping 48 hours at a cost which es a % of the total cart $ amount
Normal Free shipping in 29 days
The functionality that I want is the following:
If the stock of the product is = 0 or less than 0 (backorder is allowed), the Express shipping option should be hidden. Just must show the Normal free shipping option.
If the stock of the product is >0, both options should be shown.
If I selected more than one product, and one or more of the products does not have stock, the Express shipping option also should be hidden.
From another answer related to this question, I tried the script showed in the answer.
The problem is the following: in the last part of the script there is a mention to a variable in an external plugin.
How I adapt the code to a more generic woocommerce without that plugin?
Script:
/* !Hide Shipping Options Woocommerce */
add_filter( 'woocommerce_available_shipping_methods', 'hide_shipping_based_on_quantity' , 10, 1 );
function check_cart_for_oos() {
// load the contents of the cart into an array.
global $woocommerce;
$found = false;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
$_product_quantity = $_product->get_stock_quantity();
$_cart_quantity = $values['quantity'];
if (($_product_quantity <= 0) || ($_cart_quantity > $_product_quantity)) {
$found = true;
break;
}
}
return $found;
}
function hide_shipping_based_on_quantity( $available_methods ) {
// use the function check_cart_for_oos() to check the cart for products with 0 stock.
if ( check_cart_for_oos() ) {
// remove the rate you want
unset( $available_methods['table_rate_shipping_next-day'] ); // Replace "table_rate_shipping_next-day" with "table_rate_shipping_your-identifier".
}
// return the available methods without the one you unset.
return $available_methods;
}
From: Remove next day shipping method for out of stock items in Woocommerce
In that answer, it's already mentioned to use your own shipping method identifier. So you just need to replace the shipping method identifier with yours.
// use the function check_cart_for_oos() to check the cart for products with 0 stock.
if ( check_cart_for_oos() ) {
// remove the rate you want
unset( $available_methods['USE_YOUR_OWN_IDENTIFIER_HERE'] ); // Replace "table_rate_shipping_next-day" with "table_rate_shipping_your-identifier".
}

WooCommerce Distance Rate Shipping causing tax rate to reset

I am on the verge of losing it with this problem. So what I am attempting is to apply Zero rate tax rate when a specific coupon ('12345') is applied to the order. This site also has the plugin WooCommerce Distance Rate Shipping installed which adds its own costs and tax to the order based on billing distance.
While the billing address fields are empty, the following code successfully detects the coupon in question and sets tax rate to 'Zero Rate':
function apply_matched_coupons() {
$coupon_code = '12345';
if ( !is_admin() && WC()->cart->has_discount( $coupon_code ) ) {
$tax_class = 'Zero rate';
}
return $tax_class;
};
add_action( 'woocommerce_product_tax_class','apply_matched_coupons' );
But when an address is typed in the billing fields, the Woocommerce order update AJAX works and the WooCommerce Distance Rate Shipping plugin reads the billing addresss, re-checks its rules, applies its costs and also adds its tax. Hence, overwriting my Zero Tax rate set earlier. Screenshot is attached. I believe a hook like woocommerce_checkout_update_order_review may work which fires each time the order is updated on checkout, but can't figure out exactly how to set it.
The plugin's page here does show an example to set the $rule_cost to 0 with this code:
add_filter( 'woocommerce_distance_rate_shipping_rule_cost_distance_shipping', function( $rule_cost, $rule, $distance, $package ) {
$order_total = $package['contents_cost'];
if ( $order_total > 100 && $distance <= 5 ) {
$rule_cost = 0;
}
return $rule_cost;
}, 10, 4 );
Could this help in any way?
screenshot of extra tax added by the said plugin

Troubleshooting Woocommerce order emails customized according to shipping method

Currently my two options for shipping are regular shipping (using the Flexible Shipping plugin) and local pickup. I would like my Completed Order emails to be customized according to the shipping method used for the order (e.g. I'd like the header to say "We've shipped your order!" for regular shipping and "Your order is ready for pickup!" for local pickup).
Here's my first attempt at modifying the text through my child theme's functions.php (code based on LoicTheAztec answer in this thread). Currently, instead of inserting the desired text, it shows the default text that I entered in Woocommerce>Settings>Emails>Order Completed>Completed order>Email heading, regardless of shipping method selected.
add_action( 'woocommerce_email_header ', 'modify_header_by_shipping', 10, 2 );
function modify_header_by_shipping( $email_heading, $email ) {
// Only modify "Customer Completed Order" email notification
if( 'customer_completed_order' != $email->id ) return;
//Initialize variable
$found = false;
// Get $order object from $email
$order = $email->object;
// Iterating through Order shipping methods
foreach($order->get_shipping_methods() as $value){
$rate_id = $value->get_method_id(); // Get the shipping rate ID
if ( 'shipping_method_0_local_pickup5' == $rate_id )
$found = true;
}
if ($found)
echo '<p>'.__("Your order is ready for pickup!","woocommerce").'</p>';
else
echo '<p>'.__("We've shipped your order!","woocommerce").'</p>';
}
Here's my ordering page: https://carrickseeds.ca/checkout/

woocommerce tiered flat rate based on a custom field

I have a website where customer chooses a zone in a dropdown in billing fields. These are 4 zones: zone1, zone2 and zone3 as an example.
The idea is that if customer chose zone1 and total cart is less than $1000, customer needs to pay a shipping rate of $100. If more than $1000, customer gets free shipping.
I need to replicate that for the other 2 zones with different cart amounts and shipping rates. Is this possible?
Right now, I have the following working code but customer has to manually choose a flat rate. Problem is, of course, customers... If free shipping is displayed, they will choose that one knowing they dont apply for that option when total amount is less for their zone.
/* Change shipping based on total cost purchased. */
add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
$threshold_centro = 1000;
$threshold_hasta_el_5 = 1500;
$threshold_arelauquen = 2000;
if ( WC()->cart-> cart_contents_total < $threshold_centro ) {
unset( $rates['free_shipping:9'] );
}
elseif ( WC()->cart-> cart_contents_total < $threshold_hasta_el_5 ) {
unset( $rates['flat_rate:2'] );
}
elseif ( WC()->cart-> cart_contents_total < $threshold_arelauquen ) {
unset( $rates['flat_rate:2'], $rates['flat_rate:3'] );
}
else {
unset( $rates['flat_rate:2'], $rates['flat_rate:3'], $rates['flat_rate:4'], $rates['flat_rate:5'], $rates['flat_rate:6'] );
}
return $rates;
}
and the custom field is this one: billing_wcccf_id_qXZZegrC774HULq
Try to set a WC session when you trigger the selectbox and the use it in your if statement to get the right shipping rate or use a switch
WC->session->set('your session name', 'value')
WC->session->get('your session')

Disable Cancel Subscription for single subscription in WooCommerce

I have 3 subscriptions available on my WooCommerce site. 1 of the subscription plans is Annual Paid Monthly. This essential means a minimum term of 12 month but paid month to month. WooCommerce doesn't natively support this.
What I would like to do is detect if the user is on a particular subscription and if so, hide the cancel button until the subscription is greater than 11 months.
I found this below that hides the cancel button in all cases. I'm looking for a way to check if the subscription is XXX and if so, hide the cancel button instead
/**
* Only copy the opening php tag if needed
*/
function sv_edit_my_memberships_actions( $actions ) {
// remove the "Cancel" action for members
unset( $actions['cancel'] );
return $actions;
}
add_filter( 'wc_memberships_members_area_my-memberships_actions', 'sv_edit_my_memberships_actions' );
add_filter( 'wc_memberships_members_area_my-membership-details_actions', 'sv_edit_my_memberships_actions' );
First of you need to enumerate the users current active subscriptions and detect the one we shall filter using wc_memberships_get_user_active_memberships and compare the starting date with the current date. I provided a snippet of code that might help you on the way :)
function sv_edit_my_memberships_actions( $actions ) {
// Get the current active user
$user_id = wp_get_current_user();
if(!$user_id) // No valid user, abort
return $actions;
// Only query active subscriptions
$memberships_info = wc_memberships_get_user_active_memberships($user_id, array(
'status' => array( 'active' ),
));
// Loop through each active subscription
foreach ($memberships_info as $membership) {
$subscription_start_date = date("Y/m/d", strtotime($membership->get_start_date()));
//$subscription_end_date = date("Y/m/d", strtotime($membership->get_end_date()));
//$subscription_name = $membership->get_plan()->get_name();
//$subscription_id = $membership->get_plan()->get_id();
if($subscription_id == 'YOUR_ID') { // Active subscription
// Compare the starting date of the subscription with the current date
$datetime1 = date_create($subscription_start_date);
$datetime2 = date_create(date(time()));
$interval = date_diff($datetime1, $datetime2);
if($interval->format('%m') <= 11) {
// remove the "Cancel" action for members
unset( $actions['cancel'] );
}
}
}
return $actions;
}
add_filter( 'wc_memberships_members_area_my-memberships_actions', 'sv_edit_my_memberships_actions' );
add_filter( 'wc_memberships_members_area_my-membership-details_actions', 'sv_edit_my_memberships_actions' );

Resources