Categories
WooCommerce

Advanced Options for WooCommerce

Install the plugin to add advanced options to WooCommerce.

Categories
WooCommerce

Cities Shipping Zones for WooCommerce

Install the plugin to add country’s cities list that will be used as shipping zones.

Cities List

How to create cities list for a country?
By its Local/UNLOCODE/HASC geocoded administrative divisions.

Ho to remove some cities from the list?
Update the code of the cities for removal:

add_filter( 'woocommerce_states', 'csz_remove_woocommerce_states', 50 );
function csz_remove_woocommerce_states( $states ) {
	$unnecessary_cities = array( 'AT10101', 'AT10201', 'AT10301' );
	foreach ( $unnecessary_cities as $city ) {
		unset( $states[ substr( $city, 0, 2 ) ][ $city ] );
	}
	return $states;
}

How to keep only specific cities in the list?
Update the country and cities codes:

add_filter( 'woocommerce_states', 'csz_set_woocommerce_states', 20 );
function csz_set_woocommerce_states( $states ) {
	$country = 'AT';
	$cities = array( 'AT10101', 'AT10201', 'AT10301' );
	$new_states = array();
	foreach ( $cities as $city ) {
		if ( isset( $states[ $country ][ $city ] ) ) {
			$new_states[ $city ] = $states[ $country ][ $city ];
		}
	}
	$states[ $country ] = $new_states;
	return $states;
}

How to create shipping zones for areas inside a city?
Use zipcode, or split the city into sub-city areas (less recommended)- for example:

add_filter( 'woocommerce_states', 'csz_split_woocommerce_states', 30 );
function csz_split_woocommerce_states( $states ) {
	unset( $states['AT']['AT90001'] );
	$states['AT'] += array(
		'AT900011' => 'Wien' . '- ' . __( 'Northern', 'woocommerce' ),
		'AT900012' => 'Wien' . '- ' . __( 'Southern', 'woocommerce' ),
	);
	return $states;
}
Payment Methods Compatability

Make sure that the payment methods the website uses not require a valid state field for the countries you applied the plugin on, for example- in PayPal.

Supported Countries in catalog websites only (without online payments and 3-party integrations): Italy, USA (in State Mode).

State Mode

Although it offers non-optimal UX/UI, the plugin functionality could be applied on certain country’s states. Built-in states list for Denmark, Estonia and Kenya.

Distance Fee

Given a (domestic) city’s distances list, will be possible to add distance based fee for the shipping rate or product price (for example- to sell moving services). Built-in cities distances list for cities in Israel.

Why I can’t see the distance fee in the Checkout?
Resave any shipping method (in order to flush the cache).

How I shall organize the distances list?
Use as index the cities codes (or cities names in English / local name- if the website language is the same and the cities were translated).

Uninstall
  • Remove the locations from WooCommerce Shipping Zones settings.
  • Deactivate the plugin.
  • Update the store location in WooCommerce settings.
  • Consider to convert/erase the state field values of orders and users that were created/updated while the plugin was applied on their locations.
Categories
WooCommerce

WooCommerce Custom Order Fields

And the Persian Mathematician.

Add to the orders custom fields which are visible only to admins:

add_action( 'woocommerce_checkout_create_order', 'condless_before_checkout_create_order', 20, 2 );
function condless_before_checkout_create_order( $order, $data ) {
	$order->update_meta_data( 'shipping_date', __( 'Empty Term.' ) );
	$order->update_meta_data( 'shipping_time', __( 'Empty Term.' ) );
}

add_action( 'woocommerce_admin_order_data_after_shipping_address', 'condless_checkout_field_display_admin_order_meta' );
function condless_checkout_field_display_admin_order_meta( $order ) {
	echo '<p><strong>'. __( 'Shipping', 'woocommerce' ) . ' ' . __( 'Date' ) . ':</strong> ' . get_post_meta( $order->get_id(), 'shipping_date', true ) . '</p>';
	echo '<p><strong>'. __( 'Shipping', 'woocommerce' ) . ' ' . __( 'Time' ) . ':</strong> ' . get_post_meta( $order->get_id(), 'shipping_time', true ) . '</p>';
}

As you probably have noticed- the source of the numbering system is India, the West was exposed to the method only in the 11th century, and mainly through the writings of the Persian Mathematician al-Khwarizmi, which the term “algorithm” was named after him.

Categories
WooCommerce

WooCommerce Product Category Page Customization

Display the product category description after the products instead of before:

add_action( 'woocommerce_archive_description', 'condless_custom_archive_description', 2 );
function condless_custom_archive_description() {
        if( is_product_category() ) {
                remove_action( 'woocommerce_archive_description', 'woocommerce_taxonomy_archive_description' );
                add_action( 'woocommerce_after_main_content', 'woocommerce_taxonomy_archive_description', 5 );
        }
}

Display the category description only on hover (CSS):

.term-description {
	display: none;
}

.woocommerce-products-header__title:hover + .term-description {
	display: block;
	border-style: ridge;
}
Categories
WooCommerce

WooCommerce Product Page Customization

Display product variations under the price instead of in the “additional info” tab:

add_filter( 'woocommerce_product_tabs', 'condless_remove_additional_information_tab', 100, 1 );
function condless_remove_additional_information_tab( $tabs ) {
	unset( $tabs['additional_information'] );
	return $tabs;
}

add_action( 'woocommerce_single_product_summary', 'condless_additional_info_under_add_to_cart', 7 );
function condless_additional_info_under_add_to_cart() {
	global $product;
	if ( $product && ( $product->has_attributes() || apply_filters( 'wc_product_enable_dimensions_display', $product->has_weight() || $product->has_dimensions() ) ) ) {
		wc_display_product_attributes( $product );
	}
}
Categories
WooCommerce

WooCommerce Shipping

Change the message for customers from abroad from “There are no shipping methods available” to “Contact us to get a shipping quote”.

add_filter( 'woocommerce_no_shipping_available_html', 'condless_customize_default_message' );
add_filter( 'woocommerce_cart_no_shipping_available_html', 'condless_customize_default_message' );
function condless_customize_default_message( $wpautop ) {
	if ( WC()->countries->get_base_country() != WC()->customer->get_shipping_country() ) {
		$wpautop = __( 'Contact us to get a shipping quote' );
	}
	return $wpautop;
}

Set up minimum payment for purchase with shipping, write in the shipping settings Cost field (replace 350 with relevant value):

350 - [fee percent="100" max_fee="350"]
Categories
WooCommerce

Woocommerce Checkout Page Customization

And Back to the Future.

Reorder checkout fields:

add_filter( 'woocommerce_checkout_fields', 'condless_reordering_checkout_fields' );
function condless_reordering_checkout_fields( $fields ) {
        $billing_order = array(
                'billing_first_name',
                'billing_last_name',
                'billing_email',
                'billing_phone',
                'billing_company',
                'billing_address_1',
                'billing_address_2',
                'billing_postcode',
                'billing_city',
                'billing_state',
                'billing_country'
        );
        $count = 0;
        $priority = 10;
        foreach( $billing_order as $field_name ) {
                $count++;
                $fields['billing'][$field_name]['priority'] = $count * $priority;
        }
        $fields['billing']['billing_email']['class'] = array('form-row-first');
        $fields['billing']['billing_phone']['class'] = array('form-row-last');
        $fields['billing']['billing_postcode']['class'] = array('form-row-first');
        $fields['billing']['billing_city']['class'] = array('form-row-last');
        return $fields;
}

As you probably have noticed- Jigowatt ltd, the developers of Jigoshop on which WooCommerce code is based, was named after the pronunciation mistake of the word Gigawatt in the movie Back to the Future.

Categories
WooCommerce

WooCommerce Auto Change Order Status

Change automatically the order status from “On hold” to “Processing”, to allow a customer who pay in bank transfer (which take some time) to view the digital product download link on the “Order Received” page (must refresh the page, verify that the “Grant access to downloadable products after payment” option is enabled):

add_action( 'woocommerce_thankyou', 'condless_woocommerce_auto_processing_orders' );
function condless_woocommerce_auto_processing_orders( $order_id ) {
	if ( ! $order_id ) {
		return;
	}
	$order = wc_get_order( $order_id );
	if ( $order->has_status( 'on-hold' ) ) {
        	$order->update_status( 'processing' );
	}
}
Categories
WooCommerce

WooCommerce Cart Page Customization

Modify “Update cart” button text for mobile view:

add_filter( 'gettext', 'condless_change_update_cart_text', 20, 3 );
function condless_change_update_cart_text( $translated, $text, $domain ) {
	if ( wp_is_mobile() && is_cart() && $translated == 'Update cart' ) {
		$translated = 'Update it';
	}
	return $translated;
}

Remove the product added/removed messages:

add_filter( 'wc_add_to_cart_message_html', '__return_null' );
add_filter( 'woocommerce_cart_item_removed_notice_type', '__return_null' );
Categories
WooCommerce

WooCommerce Shop Page Customization

Change the default products display sorting to descending alphabet order:

add_filter( 'woocommerce_get_catalog_ordering_args', 'condless_get_catalog_ordering_args' );
function condless_get_catalog_ordering_args( $args ) {
	$args = array( 'orderby' => 'title', 'order' => 'DESC' );
	return $args;
}

Change the prices range seperator to “/”:

add_filter( 'woocommerce_format_price_range', 'condless_filter_woocommerce_format_price_range', 10, 3 );
function condless_filter_woocommerce_format_price_range( $price, $from, $to ) {
    $price = sprintf( _x( '%1$s &frasl; %2$s', 'Price range: from-to', 'woocommerce' ), is_numeric( $from ) ? wc_price( $from ) : $from, is_numeric( $to ) ? wc_price( $to ) : $to );
    return $price;
}

Add quantity field to products (enable AJAX button option):

add_filter( 'woocommerce_loop_add_to_cart_link', 'condless_quantity_inputs_for_loop_ajax_add_to_cart', 10, 2 );
function condless_quantity_inputs_for_loop_ajax_add_to_cart( $html, $product ) {
	if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) {
		$class = implode( ' ', array_filter( array(
			'button',
			'product_type_' . $product->get_type(),
			$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
			$product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
        ) ) );
	$html = sprintf( '%s%s<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>%s',
		'<form class="cart">',
		woocommerce_quantity_input( array(), $product, false ),
		esc_url( $product->add_to_cart_url() ),
		esc_attr( isset( $quantity ) ? $quantity : 1 ),
		esc_attr( $product->get_id() ),
		esc_attr( $product->get_sku() ),
		esc_attr( isset( $class ) ? $class : 'button' ),
		esc_html( $product->add_to_cart_text() ),
		'</form>'
		);
	}
	return $html;
}

add_action( 'wp_footer', 'condless_archives_quantity_fields_script' );
function condless_archives_quantity_fields_script() {
	?>
	<script type='text/javascript'>
		jQuery(function($){
			$(".add_to_cart_button.product_type_simple").on('click', function() { var $button = $(this); $button.attr('data-quantity', $button.parent().find('input.qty').val()); });
			$(document.body).on("adding_to_cart", function() { $("a.added_to_cart").remove(); });
		});
	</script>
	<?php
}