Account for tax classes

This commit is contained in:
Mike Jolley 2015-06-09 14:58:27 +01:00
parent e6ae10ee9a
commit fe58e1b5e9
3 changed files with 105 additions and 83 deletions

View File

@ -294,8 +294,8 @@ class WC_Query {
$this->product_query( $q );
if ( is_search() ) {
add_filter( 'posts_where', array( $this, 'search_post_excerpt' ) );
add_filter( 'wp', array( $this, 'remove_posts_where' ) );
add_filter( 'posts_where', array( $this, 'search_post_excerpt' ) );
add_filter( 'wp', array( $this, 'remove_posts_where' ) );
}
// We're on a shop page so queue the woocommerce_get_products_in_view function
@ -317,11 +317,11 @@ class WC_Query {
// If this is not a WC Query, do not modify the query
if ( empty( $wp_the_query->query_vars['wc_query'] ) || empty( $wp_the_query->query_vars['s'] ) )
return $where;
return $where;
$where = preg_replace(
"/post_title\s+LIKE\s*(\'\%[^\%]+\%\')/",
"post_title LIKE $1) OR (post_excerpt LIKE $1", $where );
"/post_title\s+LIKE\s*(\'\%[^\%]+\%\')/",
"post_title LIKE $1) OR (post_excerpt LIKE $1", $where );
return $where;
}
@ -378,16 +378,16 @@ class WC_Query {
// Abort if we're not on a post type archive/product taxonomy
if ( ! $query->is_post_type_archive( 'product' ) && ! $query->is_tax( get_object_taxonomies( 'product' ) ) )
return $posts;
return $posts;
$filtered_posts = array();
$queried_post_ids = array();
foreach ( $posts as $post ) {
if ( in_array( $post->ID, $this->post__in ) ) {
$filtered_posts[] = $post;
$queried_post_ids[] = $post->ID;
}
if ( in_array( $post->ID, $this->post__in ) ) {
$filtered_posts[] = $post;
$queried_post_ids[] = $post->ID;
}
}
$query->posts = $filtered_posts;
@ -398,9 +398,9 @@ class WC_Query {
$this->filtered_product_ids = $queried_post_ids;
if ( sizeof( $this->layered_nav_post__in ) > 0 ) {
$this->layered_nav_product_ids = array_intersect( $this->unfiltered_product_ids, $this->layered_nav_post__in );
$this->layered_nav_product_ids = array_intersect( $this->unfiltered_product_ids, $this->layered_nav_post__in );
} else {
$this->layered_nav_product_ids = $this->unfiltered_product_ids;
$this->layered_nav_product_ids = $this->unfiltered_product_ids;
}
return $filtered_posts;
@ -498,8 +498,8 @@ class WC_Query {
if ( false === ( $unfiltered_product_ids = get_transient( $transient_name ) ) ) {
// Get all visible posts, regardless of filters
$unfiltered_product_ids = get_posts(
// Get all visible posts, regardless of filters
$unfiltered_product_ids = get_posts(
array_merge(
$current_wp_query,
array(
@ -672,9 +672,9 @@ class WC_Query {
$in = array( 'visible', 'catalog' );
$meta_query = array(
'key' => '_visibility',
'value' => $in,
'compare' => $compare
'key' => '_visibility',
'value' => $in,
'compare' => $compare
);
return $meta_query;
@ -691,10 +691,10 @@ class WC_Query {
$meta_query = array();
if ( get_option( 'woocommerce_hide_out_of_stock_items' ) == 'yes' ) {
$meta_query = array(
'key' => '_stock_status',
'key' => '_stock_status',
'value' => $status,
'compare' => '='
);
);
}
return $meta_query;
}
@ -719,21 +719,21 @@ class WC_Query {
$name = 'filter_' . $attribute;
$query_type_name = 'query_type_' . $attribute;
if ( ! empty( $_GET[ $name ] ) && taxonomy_exists( $taxonomy ) ) {
if ( ! empty( $_GET[ $name ] ) && taxonomy_exists( $taxonomy ) ) {
$_chosen_attributes[ $taxonomy ]['terms'] = explode( ',', $_GET[ $name ] );
$_chosen_attributes[ $taxonomy ]['terms'] = explode( ',', $_GET[ $name ] );
if ( empty( $_GET[ $query_type_name ] ) || ! in_array( strtolower( $_GET[ $query_type_name ] ), array( 'and', 'or' ) ) )
$_chosen_attributes[ $taxonomy ]['query_type'] = apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
else
$_chosen_attributes[ $taxonomy ]['query_type'] = strtolower( $_GET[ $query_type_name ] );
if ( empty( $_GET[ $query_type_name ] ) || ! in_array( strtolower( $_GET[ $query_type_name ] ), array( 'and', 'or' ) ) )
$_chosen_attributes[ $taxonomy ]['query_type'] = apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
else
$_chosen_attributes[ $taxonomy ]['query_type'] = strtolower( $_GET[ $query_type_name ] );
}
}
}
}
add_filter('loop_shop_post_in', array( $this, 'layered_nav_query' ) );
}
add_filter('loop_shop_post_in', array( $this, 'layered_nav_query' ) );
}
}
/**
@ -857,63 +857,80 @@ class WC_Query {
* @return array
*/
public function price_filter( $filtered_posts = array() ) {
global $wpdb;
global $wpdb;
if ( isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) ) {
if ( isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) ) {
$matched_products = array();
$min = isset( $_GET['min_price'] ) ? floatval( $_GET['min_price'] ) : 0;
$max = isset( $_GET['max_price'] ) ? floatval( $_GET['max_price'] ) : 9999999999;
$tax_display_mode = get_option( 'woocommerce_tax_display_shop' );
$tax_prices_include_tax = get_option( 'woocommerce_prices_include_tax' );
//check if tax are include and display mode
if($tax_display_mode=='incl' && $tax_prices_include_tax=='no') {
$_tax = new WC_Tax();
$tax_rates= $_tax->get_rates();
foreach($tax_rates as $tax) {
$my_tax = $tax;
break;
// If displaying prices in the shop including taxes, but prices don't include taxes..
if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
foreach ( $tax_classes as $tax_class ) {
$tax_rates = WC_Tax::get_rates( $tax_class );
$min_class = $min - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $min, $tax_rates ) );
$max_class = $max - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $max, $tax_rates ) );
$matched_products_query = apply_filters( 'woocommerce_price_filter_results', $wpdb->get_results( $wpdb->prepare( '
SELECT DISTINCT ID, post_parent, post_type FROM %1$s
INNER JOIN %2$s pm1 ON ID = pm1.post_id
INNER JOIN %2$s pm2 ON ID = pm2.post_id
WHERE post_type IN ( "product", "product_variation" )
AND post_status = "publish"
AND pm1.meta_key IN ("' . implode( '","', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) . '")
AND pm1.meta_value BETWEEN %3$d AND %4$d
AND pm2.meta_key = "_tax_class"
AND pm2.meta_value = "%5$s"
', $wpdb->posts, $wpdb->postmeta, $min_class, $max_class, sanitize_title( $tax_class ) ), OBJECT_K ), $min_class, $max_class );
if ( $matched_products_query ) {
foreach ( $matched_products_query as $product ) {
if ( $product->post_type == 'product' ) {
$matched_products[] = $product->ID;
}
if ( $product->post_parent > 0 ) {
$matched_products[] = $product->post_parent;
}
}
}
}
} else {
$matched_products_query = apply_filters( 'woocommerce_price_filter_results', $wpdb->get_results( $wpdb->prepare( '
SELECT DISTINCT ID, post_parent, post_type FROM %1$s
INNER JOIN %2$s pm1 ON ID = post_id
WHERE post_type IN ( "product", "product_variation" )
AND post_status = "publish"
AND pm1.meta_key IN ("' . implode( '","', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) . '")
AND pm1.meta_value BETWEEN %3$d AND %4$d
', $wpdb->posts, $wpdb->postmeta, $min, $max, $tax_class ), OBJECT_K ), $min, $max );
if ( $matched_products_query ) {
foreach ( $matched_products_query as $product ) {
if ( $product->post_type == 'product' ) {
$matched_products[] = $product->ID;
}
if ( $product->post_parent > 0 ) {
$matched_products[] = $product->post_parent;
}
}
}
}
$matched_products = array_unique( $matched_products );
//calculation the negative dif in tax
$tax_down = ( 10000/($my_tax['rate']+100) )/100;
$min =floor($min*$tax_down);
$max =ceil($max*$tax_down);
// Filter the id's
if ( 0 === sizeof( $filtered_posts ) ) {
$filtered_posts = $matched_products;
} else {
$filtered_posts = array_intersect( $filtered_posts, $matched_products );
}
$filtered_posts[] = 0;
}
$matched_products_query = apply_filters( 'woocommerce_price_filter_results', $wpdb->get_results( $wpdb->prepare( '
SELECT DISTINCT ID, post_parent, post_type FROM %1$s
INNER JOIN %2$s ON ID = post_id
WHERE post_type IN ( "product", "product_variation" )
AND post_status = "publish"
AND meta_key IN ("' . implode( '","', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) . '")
AND meta_value BETWEEN %3$d AND %4$d
', $wpdb->posts, $wpdb->postmeta, $min, $max ), OBJECT_K ), $min, $max );
if ( $matched_products_query ) {
foreach ( $matched_products_query as $product ) {
if ( $product->post_type == 'product' ) {
$matched_products[] = $product->ID;
}
if ( $product->post_parent > 0 && ! in_array( $product->post_parent, $matched_products ) ) {
$matched_products[] = $product->post_parent;
}
}
}
// Filter the id's
if ( 0 === sizeof( $filtered_posts ) ) {
$filtered_posts = $matched_products;
} else {
$filtered_posts = array_intersect( $filtered_posts, $matched_products );
}
$filtered_posts[] = 0;
}
return (array) $filtered_posts;
return (array) $filtered_posts;
}
}

View File

@ -104,7 +104,7 @@ class WC_Tax {
* @param array $rates
* @return array
*/
private static function calc_inclusive_tax( $price, $rates ) {
public static function calc_inclusive_tax( $price, $rates ) {
$taxes = array();
$regular_tax_rates = $compound_tax_rates = 0;
@ -148,7 +148,7 @@ class WC_Tax {
* @param array $rates
* @return array
*/
private static function calc_exclusive_tax( $price, $rates ) {
public static function calc_exclusive_tax( $price, $rates ) {
$taxes = array();
if ( $rates ) {

View File

@ -161,15 +161,20 @@ class WC_Widget_Price_Filter extends WC_Widget {
$form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) );
}
if ( 'yes' === get_option( 'woocommerce_calc_taxes' ) ) {
if ( 'incl' == get_option( 'woocommerce_tax_display_shop' ) && 'no' == get_option( 'woocommerce_prices_include_tax' ) ) {
$rates = WC_Tax::get_rates();
if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
$min = 0;
if ( is_array( $rates ) && ! empty( $rates ) ) {
$_tax = current( $rates );
foreach ( $tax_classes as $tax_class ) {
$tax_rates = WC_Tax::get_rates( $tax_class );
$class_min = $min + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $min, $tax_rates ) );
$class_max = $max + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $max, $tax_rates ) );
$min = floor( ( $min ) * ( ( $_tax['rate'] + 100 ) / 100 ) );
$max = ceil( $max * ( ( $_tax['rate'] + 100 ) / 100 ) ) + 1;
if ( $min === 0 || $class_min < $min ) {
$min = $class_min;
}
if ( $class_max > $max ) {
$max = $class_max;
}
}
}