/** * Get all data needed for this report and store in the class */ private function query_report_data() { $this->report_data = new stdClass(); $this->report_data->orders = (array) $this->get_order_report_data(array('data' => array('_order_total' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_sales'), '_order_shipping' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_shipping'), '_order_tax' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_tax'), '_order_shipping_tax' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_shipping_tax'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => array_merge(array('shop_order_refund'), wc_get_order_types('sales-reports')), 'order_status' => array('completed', 'processing', 'on-hold'), 'parent_order_status' => array('completed', 'processing', 'on-hold'))); $this->report_data->order_counts = (array) $this->get_order_report_data(array('data' => array('ID' => array('type' => 'post_data', 'function' => 'COUNT', 'name' => 'count', 'distinct' => true), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'order_status' => array('completed', 'processing', 'on-hold'))); $this->report_data->coupons = (array) $this->get_order_report_data(array('data' => array('order_item_name' => array('type' => 'order_item', 'function' => '', 'name' => 'order_item_name'), 'discount_amount' => array('type' => 'order_item_meta', 'order_item_type' => 'coupon', 'function' => 'SUM', 'name' => 'discount_amount'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'where' => array(array('key' => 'order_items.order_item_type', 'value' => 'coupon', 'operator' => '=')), 'group_by' => $this->group_by_query . ', order_item_name', 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'order_status' => array('completed', 'processing', 'on-hold'))); $this->report_data->order_items = (array) $this->get_order_report_data(array('data' => array('_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_count'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'where' => array(array('key' => 'order_items.order_item_type', 'value' => 'line_item', 'operator' => '=')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'order_status' => array('completed', 'processing', 'on-hold'))); $this->report_data->refunded_order_items = (array) $this->get_order_report_data(array('data' => array('_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_count'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'where' => array(array('key' => 'order_items.order_item_type', 'value' => 'line_item', 'operator' => '=')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'order_status' => array('refunded'))); $this->report_data->partial_refunds = (array) $this->get_order_report_data(array('data' => array('_refund_amount' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_refund'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date'), '_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_count')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_status' => false, 'parent_order_status' => array('completed', 'processing', 'on-hold'))); foreach ($this->report_data->partial_refunds as $key => $value) { $this->report_data->partial_refunds[$key]->order_item_count = $this->report_data->partial_refunds[$key]->order_item_count * -1; } $this->report_data->order_items = array_merge($this->report_data->order_items, $this->report_data->partial_refunds); $this->report_data->total_order_refunds = array_sum((array) absint($this->get_order_report_data(array('data' => array('ID' => array('type' => 'post_data', 'function' => 'COUNT', 'name' => 'total_orders')), 'query_type' => 'get_var', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'order_status' => array('refunded'))))); $this->report_data->full_refunds = (array) $this->get_order_report_data(array('data' => array('_order_total' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_refund'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_status' => array('refunded'))); $this->report_data->refunds = array_merge($this->report_data->partial_refunds, $this->report_data->full_refunds); $this->report_data->total_sales = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->orders, 'total_sales')), 2); $this->report_data->total_tax = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->orders, 'total_tax')), 2); $this->report_data->total_shipping = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->orders, 'total_shipping')), 2); $this->report_data->total_shipping_tax = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->orders, 'total_shipping_tax')), 2); $this->report_data->total_refunds = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->partial_refunds, 'total_refund')) + array_sum(wp_list_pluck($this->report_data->full_refunds, 'total_refund')), 2); $this->report_data->total_coupons = number_format(array_sum(wp_list_pluck($this->report_data->coupons, 'discount_amount')), 2); $this->report_data->total_orders = absint(array_sum(wp_list_pluck($this->report_data->order_counts, 'count'))); $this->report_data->total_partial_refunds = array_sum(wp_list_pluck($this->report_data->partial_refunds, 'order_item_count')) * -1; $this->report_data->total_item_refunds = array_sum(wp_list_pluck($this->report_data->refunded_order_items, 'order_item_count')) * -1; $this->report_data->total_items = absint(array_sum(wp_list_pluck($this->report_data->order_items, 'order_item_count')) * -1); $this->report_data->average_sales = wc_format_decimal($this->report_data->total_sales / ($this->chart_interval + 1), 2); $this->report_data->net_sales = wc_format_decimal($this->report_data->total_sales - $this->report_data->total_shipping - $this->report_data->total_tax - $this->report_data->total_shipping_tax, 2); }
/** * Get the legend for the main chart sidebar * @return array */ public function get_chart_legend() { $legend = array(); $order_totals = $this->get_order_report_data(array('data' => array('_order_total' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_sales'), '_order_shipping' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_shipping')), 'filter_range' => true)); $total_sales = $order_totals->total_sales; $total_shipping = $order_totals->total_shipping; $total_orders = absint($this->get_order_report_data(array('data' => array('ID' => array('type' => 'post_data', 'function' => 'COUNT', 'name' => 'total_orders')), 'query_type' => 'get_var', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count')))); $total_items = absint($this->get_order_report_data(array('data' => array('_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_qty')), 'query_type' => 'get_var', 'order_types' => wc_get_order_types('order-count'), 'filter_range' => true))); // Get discount amounts in range $total_coupons = $this->get_order_report_data(array('data' => array('discount_amount' => array('type' => 'order_item_meta', 'order_item_type' => 'coupon', 'function' => 'SUM', 'name' => 'discount_amount')), 'where' => array(array('key' => 'order_items.order_item_type', 'value' => 'coupon', 'operator' => '=')), 'query_type' => 'get_var', 'order_types' => wc_get_order_types('order-count'), 'filter_range' => true)); $this->average_sales = $total_sales / ($this->chart_interval + 1); switch ($this->chart_groupby) { case 'day': $average_sales_title = sprintf(__('%s average daily sales', 'woocommerce'), '<strong>' . wc_price($this->average_sales) . '</strong>'); break; case 'month': $average_sales_title = sprintf(__('%s average monthly sales', 'woocommerce'), '<strong>' . wc_price($this->average_sales) . '</strong>'); break; } $legend[] = array('title' => sprintf(__('%s sales in this period', 'woocommerce'), '<strong>' . wc_price($total_sales) . '</strong>'), 'color' => $this->chart_colours['sales_amount'], 'highlight_series' => 5); $legend[] = array('title' => $average_sales_title, 'color' => $this->chart_colours['average'], 'highlight_series' => 2); $legend[] = array('title' => sprintf(__('%s orders placed', 'woocommerce'), '<strong>' . $total_orders . '</strong>'), 'color' => $this->chart_colours['order_count'], 'highlight_series' => 1); $legend[] = array('title' => sprintf(__('%s items purchased', 'woocommerce'), '<strong>' . $total_items . '</strong>'), 'color' => $this->chart_colours['item_count'], 'highlight_series' => 0); $legend[] = array('title' => sprintf(__('%s charged for shipping', 'woocommerce'), '<strong>' . wc_price($total_shipping) . '</strong>'), 'color' => $this->chart_colours['shipping_amount'], 'highlight_series' => 4); $legend[] = array('title' => sprintf(__('%s worth of coupons used', 'woocommerce'), '<strong>' . wc_price($total_coupons) . '</strong>'), 'color' => $this->chart_colours['coupon_amount'], 'highlight_series' => 3); return $legend; }
public function update_ransaction_status() { global $wpdb; $held_duration = get_option('woocommerce_hold_stock_minutes'); if ($held_duration < 1 || get_option('woocommerce_manage_stock') != 'yes') { return; } $date = date("Y-m-d H:i:s", strtotime('-' . absint(0) . ' MINUTES', current_time('timestamp'))); $unpaid_orders = $wpdb->get_results($wpdb->prepare("\n\t\t\tSELECT posts.ID, postmeta.meta_key, postmeta.meta_value, posts.post_modified\n\t\t\tFROM {$wpdb->posts} AS posts\n\t\t\tRIGHT JOIN {$wpdb->postmeta} AS postmeta ON posts.id=postmeta.post_id\n\t\t\tWHERE \tposts.post_type IN ('" . implode("','", wc_get_order_types()) . "')\n\t\t\tAND \tposts.post_status = 'wc-pending'\n\t\t\tAND \tposts.post_modified + INTERVAL 10 MINUTE < %s\n\t\t", $date)); $pending_array = ''; foreach ($unpaid_orders as $value) { if ($value->meta_key == '_order_total') { $pending_array[] = $value; } } if (!empty($pending_array)) { $response_URL = "https://paynetzuat.atomtech.in/paynetz/vfts"; $this->atom_port = $this->settings['atom_port']; foreach ($pending_array as $val) { $mer_txn = $val->ID; $amt = $val->meta_value; $date = date("Y-m-d", strtotime($val->post_modified)); $merchant_id = 160; $param = "?merchantid=" . $merchant_id . "&merchanttxnid=" . $mer_txn . "&amt=" . $amt . "&tdate=" . $date; $ch = curl_init(); $useragent = 'woo-commerce plugin'; curl_setopt($ch, CURLOPT_URL, $response_URL); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_PORT, 443); curl_setopt($ch, CURLOPT_POSTFIELDS, $param); curl_setopt($ch, CURLOPT_USERAGENT, $useragent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //information received from gateway is stored in $response. $response = curl_exec($ch); if (curl_errno($ch)) { echo '<div class="woocommerce-error">Curl error: "' . curl_error($ch) . ". Error in gateway credentials.</div>"; die; } curl_close($ch); $parser = xml_parser_create(''); xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); xml_parse_into_struct($parser, trim($response), $xml_values); xml_parser_free($parser); $result_resp = $xml_values[0]['attributes']['VERIFIED']; $unpaid_order = $mer_txn; if ($unpaid_order) { $order = wc_get_order($unpaid_order); if (apply_filters('woocommerce_cancel_unpaid_order', 'checkout' === get_post_meta($unpaid_order, '_created_via', true), $order)) { if ($result_resp == 'SUCCESS') { $order->update_status('completed', __('Unpaid order completed - time limit reached.', 'woocommerce')); } } } } } }
/** * Get all WooCommerce screen ids * * @return array */ function wc_get_screen_ids() { $wc_screen_id = sanitize_title(__('WooCommerce', 'woocommerce')); $screen_ids = array('toplevel_page_' . $wc_screen_id, $wc_screen_id . '_page_wc-reports', $wc_screen_id . '_page_wc-settings', $wc_screen_id . '_page_wc-status', $wc_screen_id . '_page_wc-addons', 'toplevel_page_wc-reports', 'product_page_product_attributes', 'edit-product', 'product', 'edit-shop_coupon', 'shop_coupon', 'edit-product_cat', 'edit-product_tag', 'edit-product_shipping_class', 'profile', 'user-edit'); foreach (wc_get_order_types() as $type) { $screen_ids[] = $type; $screen_ids[] = 'edit-' . $type; } return apply_filters('woocommerce_screen_ids', $screen_ids); }
/** * Filters for post types */ public function restrict_manage_posts() { global $typenow, $wp_query; if (in_array($typenow, wc_get_order_types('order-meta-boxes'))) { $selected_coutry = isset($_GET['country']) ? $_GET['country'] : 'all'; $countries = array_merge(array('all' => __('All countries', 'woocommerce-jetpack')), wcj_get_countries()); echo '<select id="country" name="country">'; foreach ($countries as $code => $name) { echo '<option value="' . $code . '" ' . selected($code, $selected_coutry, false) . '>' . $name . '</option>'; } echo '</select>'; } }
public function woocommerce_dashboard_status_widget_sales_query($query) { global $wpdb; // Replace query to one that returns the totals in base currency $query = array(); $query['fields'] = "SELECT SUM( postmeta.meta_value ) FROM {$wpdb->posts} as posts"; $query['join'] = "INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id "; $query['where'] = "WHERE posts.post_type IN ( '" . implode("','", wc_get_order_types('reports')) . "' ) "; $query['where'] .= "AND posts.post_status IN ( 'wc-" . implode("','wc-", apply_filters('woocommerce_reports_order_statuses', array('completed', 'processing', 'on-hold'))) . "' ) "; $query['where'] .= "AND postmeta.meta_key = '_order_total_base_currency' "; $query['where'] .= "AND posts.post_date >= '" . date('Y-m-01', current_time('timestamp')) . "' "; $query['where'] .= "AND posts.post_date <= '" . date('Y-m-d H:i:s', current_time('timestamp')) . "' "; return $query; }
/** * column_default function. * * @param WP_User $user * @param string $column_name * @return string */ public function column_default($user, $column_name) { global $wpdb; if ('orders' == $column_name) { if (!($count = get_user_meta($user->ID, '_order_count', true))) { global $wpdb; $count = $wpdb->get_var("SELECT COUNT(*)\r\n\t\t\t\t\tFROM {$wpdb->posts} as posts\r\n\r\n\t\t\t\t\tLEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id\r\n\r\n\t\t\t\t\tWHERE meta.meta_key = '_customer_user'\r\n\t\t\t\t\tAND posts.post_type IN ('" . implode("','", wc_get_order_types('order-count')) . "')\r\n\t\t\t\t\tAND posts.post_status IN ('" . implode("','", array_keys(wc_get_order_statuses())) . "')\r\n\t\t\t\t\tAND posts.post_parent = 0\r\n\t\t\t\t\tAND meta_value = {$user->ID}\r\n\t\t\t\t"); update_user_meta($user->ID, '_order_count', absint($count)); } $result = absint($count); } else { $result = parent::column_default($user, $column_name); } return $result; }
public static function exclude_comments($clauses) { global $wpdb, $typenow; if (is_admin() && in_array($typenow, wc_get_order_types()) && current_user_can('manage_woocommerce')) { return $clauses; // Don't hide when viewing orders in admin } if (!$clauses['join']) { $clauses['join'] = ''; } if (!strstr($clauses['join'], "JOIN {$wpdb->posts}")) { $clauses['join'] .= " LEFT JOIN {$wpdb->posts} ON comment_post_ID = {$wpdb->posts}.ID "; } if ($clauses['where']) { $clauses['where'] .= ' AND '; } $clauses['where'] .= " {$wpdb->posts}.post_type NOT IN ('" . implode("','", wc_crm_get_exclude_comments_post_types()) . "') "; return $clauses; }
/** * Get all data needed for this report and store in the class */ private function query_report_data() { $this->report_data = new stdClass(); $this->report_data->orders = (array) $this->get_order_report_data(array('data' => array('_order_total' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_sales'), '_order_shipping' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_shipping'), '_order_tax' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_tax'), '_order_shipping_tax' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_shipping_tax'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('sales-reports'), 'order_status' => array('completed', 'processing', 'on-hold', 'refunded'))); $this->report_data->refunded_orders = (array) $this->get_order_report_data(array('data' => array('_order_total' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_sales'), '_order_shipping' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_shipping'), '_order_tax' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_tax'), '_order_shipping_tax' => array('type' => 'meta', 'function' => 'SUM', 'name' => 'total_shipping_tax'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date'), 'ID' => array('type' => 'post_data', 'function' => 'COUNT', 'name' => 'count', 'distinct' => true)), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('sales-reports'), 'order_status' => array('refunded'))); $this->report_data->order_counts = (array) $this->get_order_report_data(array('data' => array('ID' => array('type' => 'post_data', 'function' => 'COUNT', 'name' => 'count', 'distinct' => true), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'order_status' => array('completed', 'processing', 'on-hold', 'refunded'))); $this->report_data->coupons = (array) $this->get_order_report_data(array('data' => array('order_item_name' => array('type' => 'order_item', 'function' => '', 'name' => 'order_item_name'), 'discount_amount' => array('type' => 'order_item_meta', 'order_item_type' => 'coupon', 'function' => 'SUM', 'name' => 'discount_amount'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'where' => array(array('key' => 'order_items.order_item_type', 'value' => 'coupon', 'operator' => '=')), 'group_by' => $this->group_by_query . ', order_item_name', 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'order_status' => array('completed', 'processing', 'on-hold', 'refunded'))); $this->report_data->refunds = (array) $this->get_order_report_data(array('data' => array('_refund_amount' => array('type' => 'meta', 'function' => '', 'name' => 'total_refund'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date'), '_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_count', 'join_type' => 'LEFT')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_status' => false, 'parent_order_status' => array('completed', 'processing', 'on-hold', 'refunded'))); foreach ($this->report_data->refunds as $key => $value) { $this->report_data->refunds[$key]->order_item_count = $this->report_data->refunds[$key]->order_item_count * -1; } // All items from orders - even those refunded $this->report_data->order_items = (array) $this->get_order_report_data(array('data' => array('_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_count'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'where' => array(array('key' => 'order_items.order_item_type', 'value' => 'line_item', 'operator' => '=')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'order_status' => array('completed', 'processing', 'on-hold', 'refunded'))); // All items from FULLY refunded orders for the time period $this->report_data->refunded_order_items = (array) $this->get_order_report_data(array('data' => array('_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_count', 'join_type' => 'LEFT'), 'post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date')), 'where' => array(array('key' => 'order_items.order_item_type', 'value' => 'line_item', 'operator' => '=')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'order_status' => array('refunded'))); // All partially refunded items $this->report_data->partially_refunded_order_items = (array) $this->get_order_report_data(array('data' => array('post_date' => array('type' => 'post_data', 'function' => '', 'name' => 'post_date'), '_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_count')), 'group_by' => $this->group_by_query, 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_status' => false, 'parent_order_status' => array('completed', 'processing', 'on-hold'))); // Combine partial and full refund item quantities $this->report_data->refunded_order_items = array_merge($this->report_data->refunded_order_items, $this->report_data->partially_refunded_order_items); // Totals from only refunded orders $this->report_data->total_tax_refunded = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->refunded_orders, 'total_tax')), 2); $this->report_data->total_shipping_refunded = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->refunded_orders, 'total_shipping')), 2); $this->report_data->total_shipping_tax_refunded = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->refunded_orders, 'total_shipping_tax')), 2); // Totals from all orders - including those refunded. Subtract refunded amounts. $this->report_data->total_tax = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->orders, 'total_tax')) - $this->report_data->total_tax_refunded, 2); $this->report_data->total_shipping = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->orders, 'total_shipping')) - $this->report_data->total_shipping_refunded, 2); $this->report_data->total_shipping_tax = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->orders, 'total_shipping_tax')) - $this->report_data->total_shipping_tax_refunded, 2); // Total the refunds and sales amounts. Sales subract refunds. $this->report_data->total_refunds = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->refunds, 'total_refund')), 2); $this->report_data->total_sales = wc_format_decimal(array_sum(wp_list_pluck($this->report_data->orders, 'total_sales')) - $this->report_data->total_refunds, 2); $this->report_data->net_sales = wc_format_decimal($this->report_data->total_sales - $this->report_data->total_shipping - $this->report_data->total_tax - $this->report_data->total_shipping_tax, 2); // Calculate average based on net $this->report_data->average_sales = wc_format_decimal($this->report_data->net_sales / ($this->chart_interval + 1), 2); // Total orders and discounts also includes those which have been refunded at some point $this->report_data->total_orders = absint(array_sum(wp_list_pluck($this->report_data->order_counts, 'count'))); $this->report_data->total_coupons = number_format(array_sum(wp_list_pluck($this->report_data->coupons, 'discount_amount')), 2); $this->report_data->total_refunded_orders = absint(array_sum(wp_list_pluck($this->report_data->refunded_orders, 'count'))); // Item counts $this->report_data->total_item_refunds = array_sum(wp_list_pluck($this->report_data->refunded_order_items, 'order_item_count')); $this->report_data->total_items = absint(array_sum(wp_list_pluck($this->report_data->order_items, 'order_item_count'))); }
/** * Show status widget */ public function status_widget() { global $wpdb; include_once 'reports/class-wc-admin-report.php'; $reports = new WC_Admin_Report(); // Sales $query = array(); $query['fields'] = "SELECT SUM( postmeta.meta_value ) FROM {$wpdb->posts} as posts"; $query['join'] = "INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id LEFT JOIN {$wpdb->posts} AS parent ON posts.post_parent = parent.ID"; $query['where'] = "WHERE posts.post_type IN ( '" . implode("','", array_merge(wc_get_order_types('sales-reports'), array('shop_order_refund'))) . "' ) "; $query['where'] .= "AND posts.post_status IN ( 'wc-" . implode("','wc-", apply_filters('woocommerce_reports_order_statuses', array('completed', 'processing', 'on-hold'))) . "' ) "; $query['where'] .= "AND ( parent.post_status IN ( 'wc-" . implode("','wc-", apply_filters('woocommerce_reports_order_statuses', array('completed', 'processing', 'on-hold'))) . "' ) OR parent.ID IS NULL ) "; $query['where'] .= "AND postmeta.meta_key = '_order_total' "; $query['where'] .= "AND posts.post_date >= '" . date('Y-m-01', current_time('timestamp')) . "' "; $query['where'] .= "AND posts.post_date <= '" . date('Y-m-d H:i:s', current_time('timestamp')) . "' "; $sales = $wpdb->get_var(implode(' ', apply_filters('woocommerce_dashboard_status_widget_sales_query', $query))); // Get top seller $query = array(); $query['fields'] = "SELECT SUM( order_item_meta.meta_value ) as qty, order_item_meta_2.meta_value as product_id\n\t\t\tFROM {$wpdb->posts} as posts"; $query['join'] = "INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON posts.ID = order_id "; $query['join'] .= "INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id "; $query['join'] .= "INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta_2 ON order_items.order_item_id = order_item_meta_2.order_item_id "; $query['where'] = "WHERE posts.post_type IN ( '" . implode("','", wc_get_order_types('order-count')) . "' ) "; $query['where'] .= "AND posts.post_status IN ( 'wc-" . implode("','wc-", apply_filters('woocommerce_reports_order_statuses', array('completed', 'processing', 'on-hold'))) . "' ) "; $query['where'] .= "AND order_item_meta.meta_key = '_qty' "; $query['where'] .= "AND order_item_meta_2.meta_key = '_product_id' "; $query['where'] .= "AND posts.post_date >= '" . date('Y-m-01', current_time('timestamp')) . "' "; $query['where'] .= "AND posts.post_date <= '" . date('Y-m-d H:i:s', current_time('timestamp')) . "' "; $query['groupby'] = "GROUP BY product_id"; $query['orderby'] = "ORDER BY qty DESC"; $query['limits'] = "LIMIT 1"; $top_seller = $wpdb->get_row(implode(' ', apply_filters('woocommerce_dashboard_status_widget_top_seller_query', $query))); // Counts $on_hold_count = 0; $processing_count = 0; foreach (wc_get_order_types('order-count') as $type) { $counts = (array) wp_count_posts($type); $on_hold_count += isset($counts['wc-on-hold']) ? $counts['wc-on-hold'] : 0; $processing_count += isset($counts['wc-processing']) ? $counts['wc-processing'] : 0; } // Get products using a query - this is too advanced for get_posts :( $stock = absint(max(get_option('woocommerce_notify_low_stock_amount'), 1)); $nostock = absint(max(get_option('woocommerce_notify_no_stock_amount'), 0)); $transient_name = 'wc_low_stock_count'; if (false === ($lowinstock_count = get_transient($transient_name))) { $query_from = apply_filters('woocommerce_report_low_in_stock_query_from', "FROM {$wpdb->posts} as posts\n\t\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id\n\t\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id\n\t\t\t\tWHERE 1=1\n\t\t\t\tAND posts.post_type IN ( 'product', 'product_variation' )\n\t\t\t\tAND posts.post_status = 'publish'\n\t\t\t\tAND postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes'\n\t\t\t\tAND postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$stock}'\n\t\t\t\tAND postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) > '{$nostock}'\n\t\t\t"); $lowinstock_count = absint($wpdb->get_var("SELECT COUNT( DISTINCT posts.ID ) {$query_from};")); set_transient($transient_name, $lowinstock_count, DAY_IN_SECONDS * 30); } $transient_name = 'wc_outofstock_count'; if (false === ($outofstock_count = get_transient($transient_name))) { $query_from = apply_filters('woocommerce_report_out_of_stock_query_from', "FROM {$wpdb->posts} as posts\n\t\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id\n\t\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id\n\t\t\t\tWHERE 1=1\n\t\t\t\tAND posts.post_type IN ( 'product', 'product_variation' )\n\t\t\t\tAND posts.post_status = 'publish'\n\t\t\t\tAND postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes'\n\t\t\t\tAND postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$nostock}'\n\t\t\t"); $outofstock_count = absint($wpdb->get_var("SELECT COUNT( DISTINCT posts.ID ) {$query_from};")); set_transient($transient_name, $outofstock_count, DAY_IN_SECONDS * 30); } ?> <ul class="wc_status_list"> <li class="sales-this-month"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=orders&range=month'); ?> "> <?php echo $reports->sales_sparkline('', max(7, date('d', current_time('timestamp')))); ?> <?php printf(__("<strong>%s</strong> sales this month", 'woocommerce'), wc_price($sales)); ?> </a> </li> <?php if ($top_seller && $top_seller->qty) { ?> <li class="best-seller-this-month"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=orders&report=sales_by_product&range=month&product_ids=' . $top_seller->product_id); ?> "> <?php echo $reports->sales_sparkline($top_seller->product_id, max(7, date('d', current_time('timestamp'))), 'count'); ?> <?php printf(__("%s top seller this month (sold %d)", 'woocommerce'), "<strong>" . get_the_title($top_seller->product_id) . "</strong>", $top_seller->qty); ?> </a> </li> <?php } ?> <li class="processing-orders"> <a href="<?php echo admin_url('edit.php?post_status=wc-processing&post_type=shop_order'); ?> "> <?php printf(_n("<strong>%s order</strong> awaiting processing", "<strong>%s orders</strong> awaiting processing", $processing_count, 'woocommerce'), $processing_count); ?> </a> </li> <li class="on-hold-orders"> <a href="<?php echo admin_url('edit.php?post_status=wc-on-hold&post_type=shop_order'); ?> "> <?php printf(_n("<strong>%s order</strong> on-hold", "<strong>%s orders</strong> on-hold", $on_hold_count, 'woocommerce'), $on_hold_count); ?> </a> </li> <li class="low-in-stock"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=stock&report=low_in_stock'); ?> "> <?php printf(_n("<strong>%s product</strong> low in stock", "<strong>%s products</strong> low in stock", $lowinstock_count, 'woocommerce'), $lowinstock_count); ?> </a> </li> <li class="out-of-stock"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=stock&report=out_of_stock'); ?> "> <?php printf(_n("<strong>%s product</strong> out of stock", "<strong>%s products</strong> out of stock", $outofstock_count, 'woocommerce'), $outofstock_count); ?> </a> </li> <?php do_action('woocommerce_after_dashboard_status_widget', $reports); ?> </ul> <?php }
/** * Get total orders by customer. * @param int $user_id * @return int */ function wc_get_customer_order_count($user_id) { if (!($count = get_user_meta($user_id, '_order_count', true))) { global $wpdb; $count = $wpdb->get_var("SELECT COUNT(*)\n\t\t\tFROM {$wpdb->posts} as posts\n\n\t\t\tLEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id\n\n\t\t\tWHERE meta.meta_key = '_customer_user'\n\t\t\tAND posts.post_type IN ('" . implode("','", wc_get_order_types('order-count')) . "')\n\t\t\tAND posts.post_status IN ('" . implode("','", array_keys(wc_get_order_statuses())) . "')\n\t\t\tAND meta_value = {$user_id}\n\t\t"); update_user_meta($user_id, '_order_count', absint($count)); } return absint($count); }
/** * Return the count of processing orders. * * @access public * @return int */ function wc_processing_order_count() { $count = 0; foreach (wc_get_order_types('order-count') as $type) { $this_count = wp_count_posts($type, 'readable'); $count += isset($this_count->{'wc-processing'}) ? $this_count->{'wc-processing'} : 0; } return $count; }
/** * Helper to check if the webhook should be delivered, as some hooks * (like `wp_trash_post`) will fire for every post type, not just ours. * * @since 2.2 * @param mixed $arg first hook argument * @return bool true if webhook should be delivered, false otherwise */ private function should_deliver($arg) { // only active webhooks can be delivered if ('active' != $this->get_status()) { return false; } $current_action = current_action(); // only deliver deleted event for coupons, orders, and products if ('delete_post' == $current_action && !in_array($GLOBALS['post_type'], array('shop_coupon', 'shop_order', 'product'))) { return false; } elseif ('delete_user' == $current_action) { $user = get_userdata(absint($arg)); // only deliver deleted customer event for users with customer role if (!$user || !in_array('customer', (array) $user->roles)) { return false; } // check if the custom order type has chosen to exclude order webhooks from triggering along with its own webhooks. } elseif ('order' == $this->get_resource() && !in_array(get_post_type(absint($arg)), wc_get_order_types('order-webhooks'))) { return false; } elseif (0 === strpos($current_action, 'woocommerce_process_shop')) { // the `woocommerce_process_shop_*` hook fires for both updates // and creation so check the post creation date to determine the actual event $resource = get_post(absint($arg)); // a resource is considered created when the hook is executed within 10 seconds of the post creation date $resource_created = time() - 10 <= strtotime($resource->post_date_gmt); if ('created' == $this->get_event() && !$resource_created) { return false; } elseif ('updated' == $this->get_event() && $resource_created) { return false; } } return true; }
function avada_woocommerce_before_my_account($order_count, $edit_address = false) { global $woocommerce; $edit_address = is_wc_endpoint_url('edit-address'); avada_top_user_container(); ?> <ul class="woocommerce-side-nav avada-myaccount-nav"> <?php if ($downloads = WC()->customer->get_downloadable_products()) { ?> <li <?php if (!$edit_address) { echo 'class="active"'; } ?> > <a class="downloads" href="#"> <?php _e('View Downloads', 'Avada'); ?> </a> </li> <?php } if (function_exists('wc_get_order_types') && function_exists('wc_get_order_statuses')) { $customer_orders = get_posts(apply_filters('woocommerce_my_account_my_orders_query', array('numberposts' => $order_count, 'meta_key' => '_customer_user', 'meta_value' => get_current_user_id(), 'post_type' => wc_get_order_types('view-orders'), 'post_status' => array_keys(wc_get_order_statuses())))); } else { $customer_orders = get_posts(apply_filters('woocommerce_my_account_my_orders_query', array('numberposts' => $order_count, 'meta_key' => '_customer_user', 'meta_value' => get_current_user_id(), 'post_type' => 'shop_order', 'post_status' => 'publish'))); } if ($customer_orders) { ?> <li <?php if (!$edit_address && !WC()->customer->get_downloadable_products()) { echo 'class="active"'; } ?> > <a class="orders" href="#"> <?php _e('View Orders', 'Avada'); ?> </a> </li> <?php } ?> <li <?php if ($edit_address || !WC()->customer->get_downloadable_products() && !$customer_orders) { echo 'class="active"'; } ?> > <a class="address" href="#"> <?php _e('Change Address', 'Avada'); ?> </a> </li> <li> <a class="account" href="#"> <?php _e('Edit Account', 'Avada'); ?> </a> </li> </ul> <div class="woocommerce-content-box avada-myaccount-data"> <?php }
/** * Admin filters */ public function request_query($vars) { global $typenow, $wp_query, $wp_post_statuses; if (in_array($typenow, wc_get_order_types('order-meta-boxes'))) { if (isset($_GET['post_parent']) && $_GET['post_parent'] > 0) { $vars['post_parent'] = absint($_GET['post_parent']); } } return $vars; }
/** * Check if we're saving, the trigger an action based on the post type * * @param int $post_id * @param object $post */ public function save_meta_boxes($post_id, $post) { // $post_id and $post are required if (empty($post_id) || empty($post)) { return; } // Dont' save meta boxes for revisions or autosaves if (defined('DOING_AUTOSAVE') || is_int(wp_is_post_revision($post)) || is_int(wp_is_post_autosave($post))) { return; } // Check the nonce if (empty($_POST['woocommerce_meta_nonce']) || !wp_verify_nonce($_POST['woocommerce_meta_nonce'], 'woocommerce_save_data')) { return; } // Check the post being saved == the $post_id to prevent triggering this call for other save_post events if (empty($_POST['post_ID']) || $_POST['post_ID'] != $post_id) { return; } // Check user has permission to edit if (!current_user_can('edit_post', $post_id)) { return; } // Check the post type if (in_array($post->post_type, wc_get_order_types('order-meta-boxes'))) { do_action('woocommerce_process_shop_order_meta', $post_id, $post); } elseif (in_array($post->post_type, array('product', 'shop_coupon'))) { do_action('woocommerce_process_' . $post->post_type . '_meta', $post_id, $post); } }
/** * Get past orders (by email) and update them * * @param int $customer_id * @return int */ function wc_update_new_customer_past_orders($customer_id) { $customer = get_user_by('id', absint($customer_id)); $customer_orders = get_posts(array('numberposts' => -1, 'post_type' => wc_get_order_types(), 'post_status' => array_keys(wc_get_order_statuses()), 'fields' => 'ids', 'meta_query' => array(array('key' => '_customer_user', 'value' => array(0, ''), 'compare' => 'IN'), array('key' => '_billing_email', 'value' => $customer->user_email)))); $linked = 0; $complete = 0; if ($customer_orders) { foreach ($customer_orders as $order_id) { update_post_meta($order_id, '_customer_user', $customer->ID); $order_status = get_post_status($order_id); if ($order_status) { $order_status = current($order_status); $order_status = sanitize_title($order_status->slug); } if ($order_status === 'completed') { $complete++; } $linked++; } } if ($complete) { update_user_meta($customer_id, 'paying_customer', 1); update_user_meta($customer_id, '_order_count', ''); update_user_meta($customer_id, '_money_spent', ''); } return $linked; }
/** * Exclude order comments from queries and RSS. * @param string $where * @return string */ public static function exclude_order_comments_from_feed_where($where) { global $wpdb; if ($where) { $where .= ' AND '; } $where .= " {$wpdb->posts}.post_type NOT IN ('" . implode("','", wc_get_order_types()) . "') "; return $where; }
/** * Ensure floats are correctly converted to strings based on PHP locale * * @param null $check * @param int $object_id * @param string $meta_key * @param mixed $meta_value * @param mixed $prev_value * @return null|bool */ public static function update_post_metadata($check, $object_id, $meta_key, $meta_value, $prev_value) { if (!empty($meta_value) && is_float($meta_value) && in_array(get_post_type($object_id), array_merge(wc_get_order_types(), array('shop_coupon', 'product', 'product_variation')))) { // Convert float to string $meta_value = wc_float_to_string($meta_value); // Update meta value with new string update_metadata('post', $object_id, $meta_key, $meta_value, $prev_value); // Return return true; } return $check; }
/** * Get column value. * * @param WP_User $user * @param string $column_name * @return string */ public function column_default($user, $column_name) { global $wpdb; switch ($column_name) { case 'customer_name': if ($user->last_name && $user->first_name) { return $user->last_name . ', ' . $user->first_name; } else { return '-'; } case 'username': return $user->user_login; case 'location': $state_code = get_user_meta($user->ID, 'billing_state', true); $country_code = get_user_meta($user->ID, 'billing_country', true); $state = isset(WC()->countries->states[$country_code][$state_code]) ? WC()->countries->states[$country_code][$state_code] : $state_code; $country = isset(WC()->countries->countries[$country_code]) ? WC()->countries->countries[$country_code] : $country_code; $value = ''; if ($state) { $value .= $state . ', '; } $value .= $country; if ($value) { return $value; } else { return '-'; } case 'email': return '<a href="mailto:' . $user->user_email . '">' . $user->user_email . '</a>'; case 'spent': return wc_price(wc_get_customer_total_spent($user->ID)); case 'orders': return wc_get_customer_order_count($user->ID); case 'last_order': $order_ids = get_posts(array('posts_per_page' => 1, 'post_type' => 'shop_order', 'orderby' => 'date', 'order' => 'desc', 'post_status' => array('wc-completed', 'wc-processing'), 'meta_query' => array(array('key' => '_customer_user', 'value' => $user->ID)), 'fields' => 'ids')); if ($order_ids) { $order = wc_get_order($order_ids[0]); return '<a href="' . admin_url('post.php?post=' . $order->id . '&action=edit') . '">' . _x('#', 'hash before order number', 'woocommerce') . $order->get_order_number() . '</a> – ' . date_i18n(get_option('date_format'), strtotime($order->order_date)); } else { return '-'; } break; case 'user_actions': ob_start(); ?> <p> <?php do_action('woocommerce_admin_user_actions_start', $user); $actions = array(); $actions['refresh'] = array('url' => wp_nonce_url(add_query_arg('refresh', $user->ID), 'refresh'), 'name' => __('Refresh stats', 'woocommerce'), 'action' => "refresh"); $actions['edit'] = array('url' => admin_url('user-edit.php?user_id=' . $user->ID), 'name' => __('Edit', 'woocommerce'), 'action' => "edit"); $actions['view'] = array('url' => admin_url('edit.php?post_type=shop_order&_customer_user='******'name' => __('View orders', 'woocommerce'), 'action' => "view"); $order_ids = get_posts(array('posts_per_page' => 1, 'post_type' => wc_get_order_types(), 'post_status' => array_keys(wc_get_order_statuses()), 'meta_query' => array(array('key' => '_customer_user', 'value' => array(0, ''), 'compare' => 'IN'), array('key' => '_billing_email', 'value' => $user->user_email)), 'fields' => 'ids')); if ($order_ids) { $actions['link'] = array('url' => wp_nonce_url(add_query_arg('link_orders', $user->ID), 'link_orders'), 'name' => __('Link previous orders', 'woocommerce'), 'action' => "link"); } $actions = apply_filters('woocommerce_admin_user_actions', $actions, $user); foreach ($actions as $action) { printf('<a class="button tips %s" href="%s" data-tip="%s">%s</a>', esc_attr($action['action']), esc_url($action['url']), esc_attr($action['name']), esc_attr($action['name'])); } do_action('woocommerce_admin_user_actions_end', $user); ?> </p><?php $user_actions = ob_get_contents(); ob_end_clean(); return $user_actions; } return ''; }
/** * Test wc_get_account_orders_query_args(). * * @since 2.6.0 */ public function test_wc_get_account_orders_query_args() { $this->assertEquals(array('posts_per_page' => 15, 'meta_key' => '_customer_user', 'meta_value' => get_current_user_id(), 'post_type' => wc_get_order_types('view-orders'), 'post_status' => array_keys(wc_get_order_statuses())), wc_get_account_orders_query_args()); }
/** * Change label for insert buttons. * * @param array $strings * @return array */ public function change_insert_into_post($strings) { global $post_type; if (in_array($post_type, array('product', 'shop_coupon')) || in_array($post_type, wc_get_order_types())) { $obj = get_post_type_object($post_type); $strings['insertIntoPost'] = sprintf(__('Insert into %s', 'woocommerce'), $obj->labels->singular_name); $strings['uploadedToThisPost'] = sprintf(__('Uploaded to this %s', 'woocommerce'), $obj->labels->singular_name); } return $strings; }
/** * column_default function. * * @param mixed $user * @param string $column_name * @return int|string * @todo Inconsistent return types, and void return at the end. Needs a rewrite. */ function column_default($user, $column_name) { global $wpdb; switch ($column_name) { case 'customer_name': if ($user->last_name && $user->first_name) { return $user->last_name . ', ' . $user->first_name; } else { return '-'; } case 'username': return $user->user_login; break; case 'location': $state_code = get_user_meta($user->ID, 'billing_state', true); $country_code = get_user_meta($user->ID, 'billing_country', true); $state = isset(WC()->countries->states[$country_code][$state_code]) ? WC()->countries->states[$country_code][$state_code] : $state_code; $country = isset(WC()->countries->countries[$country_code]) ? WC()->countries->countries[$country_code] : $country_code; $value = ''; if ($state) { $value .= $state . ', '; } $value .= $country; if ($value) { return $value; } else { return '-'; } break; case 'email': return '<a href="mailto:' . $user->user_email . '">' . $user->user_email . '</a>'; case 'spent': if (!($spent = get_user_meta($user->ID, '_money_spent', true))) { $spent = $wpdb->get_var("SELECT SUM(meta2.meta_value)\n\t\t\t\t\t\tFROM {$wpdb->posts} as posts\n\n\t\t\t\t\t\tLEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id\n\t\t\t\t\t\tLEFT JOIN {$wpdb->postmeta} AS meta2 ON posts.ID = meta2.post_id\n\n\t\t\t\t\t\tWHERE meta.meta_key = '_customer_user'\n\t\t\t\t\t\tAND meta.meta_value = {$user->ID}\n\t\t\t\t\t\tAND posts.post_type IN ('" . implode("','", wc_get_order_types('reports')) . "')\n\t\t\t\t\t\tAND posts.post_status = 'wc-completed'\n\t\t\t\t\t\tAND meta2.meta_key = '_order_total'\n\t\t\t\t\t"); update_user_meta($user->ID, '_money_spent', $spent); } return wc_price($spent); break; case 'orders': if (!($count = get_user_meta($user->ID, '_order_count', true))) { $count = $wpdb->get_var("SELECT COUNT(*)\n\t\t\t\t\t\tFROM {$wpdb->posts} as posts\n\n\t\t\t\t\t\tLEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id\n\n\t\t\t\t\t\tWHERE meta.meta_key = '_customer_user'\n\t\t\t\t\t\tAND posts.post_type IN ('" . implode("','", wc_get_order_types('order-count')) . "')\n\t\t\t\t\t\tAND posts.post_status = 'wc-completed'\n\t\t\t\t\t\tAND meta_value = {$user->ID}\n\t\t\t\t\t"); update_user_meta($user->ID, '_order_count', $count); } return absint($count); break; case 'last_order': $order_ids = get_posts(array('posts_per_page' => 1, 'post_type' => 'shop_order', 'orderby' => 'date', 'order' => 'desc', 'post_status' => array_keys(wc_get_order_statuses()), 'meta_query' => array(array('key' => '_customer_user', 'value' => $user->ID)), 'fields' => 'ids')); if ($order_ids) { $order = wc_get_order($order_ids[0]); echo '<a href="' . admin_url('post.php?post=' . $order->id . '&action=edit') . '">' . $order->get_order_number() . '</a> – ' . date_i18n(get_option('date_format'), strtotime($order->order_date)); } else { echo '-'; } break; case 'user_actions': ?> <p> <?php do_action('woocommerce_admin_user_actions_start', $user); $actions = array(); $actions['edit'] = array('url' => admin_url('user-edit.php?user_id=' . $user->ID), 'name' => __('Edit', 'woocommerce'), 'action' => "edit"); $actions['view'] = array('url' => admin_url('edit.php?post_type=shop_order&_customer_user='******'name' => __('View orders', 'woocommerce'), 'action' => "view"); $order_ids = get_posts(array('posts_per_page' => 1, 'post_type' => wc_get_order_types(), 'post_status' => array_keys(wc_get_order_statuses()), 'meta_query' => array(array('key' => '_customer_user', 'value' => array(0, ''), 'compare' => 'IN'), array('key' => '_billing_email', 'value' => $user->user_email)), 'fields' => 'ids')); if ($order_ids) { $actions['link'] = array('url' => wp_nonce_url(add_query_arg('link_orders', $user->ID), 'link_orders'), 'name' => __('Link previous orders', 'woocommerce'), 'action' => "link"); } $actions = apply_filters('woocommerce_admin_user_actions', $actions, $user); foreach ($actions as $action) { printf('<a class="button tips %s" href="%s" data-tip="%s">%s</a>', esc_attr($action['action']), esc_url($action['url']), esc_attr($action['name']), esc_attr($action['name'])); } do_action('woocommerce_admin_user_actions_end', $user); ?> </p><?php break; } }
/** * Return the orders count of a specific order status. * * @access public * @return int */ function wc_orders_count($status) { $count = 0; $order_statuses = array_keys(wc_get_order_statuses()); if (!in_array('wc-' . $status, $order_statuses)) { return 0; } foreach (wc_get_order_types('order-count') as $type) { $this_count = wp_count_posts($type, 'readable'); $count += isset($this_count->{'wc-' . $status}) ? $this_count->{'wc-' . $status} : 0; } return $count; }
<?php /** * My Orders * * Shows recent orders on the account page * * @author WooThemes * @package WooCommerce/Templates * @version 2.2.0 */ if (!defined('ABSPATH')) { exit; // Exit if accessed directly } $customer_orders = get_posts(apply_filters('woocommerce_my_account_my_orders_query', array('numberposts' => $order_count, 'meta_key' => '_customer_user', 'meta_value' => get_current_user_id(), 'post_type' => wc_get_order_types('view-orders'), 'post_status' => array_keys(wc_get_order_statuses())))); if ($customer_orders) { ?> <h2><?php echo apply_filters('woocommerce_my_account_my_orders_title', __('Recent Quote Requests', 'woocommerce')); ?> </h2> <table class="shop_table shop_table_responsive my_account_orders"> <thead> <tr> <th class="order-number"><span class="nobr"><?php _e('Order', 'woocommerce'); ?>
/** * Check if we're saving, the trigger an action based on the post type * * @param int $post_id * @param object $post */ public function save_meta_boxes($post_id, $post) { // $post_id and $post are required if (empty($post_id) || empty($post) || self::$saved_meta_boxes) { return; } // Dont' save meta boxes for revisions or autosaves if (defined('DOING_AUTOSAVE') || is_int(wp_is_post_revision($post)) || is_int(wp_is_post_autosave($post))) { return; } // Check the nonce if (empty($_POST['woocommerce_meta_nonce']) || !wp_verify_nonce($_POST['woocommerce_meta_nonce'], 'woocommerce_save_data')) { return; } // Check the post being saved == the $post_id to prevent triggering this call for other save_post events if (empty($_POST['post_ID']) || $_POST['post_ID'] != $post_id) { return; } // Check user has permission to edit if (!current_user_can('edit_post', $post_id)) { return; } // We need this save event to run once to avoid potential endless loops. This would have been perfect: // remove_action( current_filter(), __METHOD__ ); // But cannot be used due to https://github.com/woothemes/woocommerce/issues/6485 // When that is patched in core we cna use the above. For now: self::$saved_meta_boxes = true; // Check the post type if (in_array($post->post_type, wc_get_order_types('order-meta-boxes'))) { do_action('woocommerce_process_shop_order_meta', $post_id, $post); } elseif (in_array($post->post_type, array('product', 'shop_coupon'))) { do_action('woocommerce_process_' . $post->post_type . '_meta', $post_id, $post); } }
/** * Looks through the cart to check each item is in stock. If not, add an error. * * @return bool|WP_Error */ public function check_cart_item_stock() { global $wpdb; $error = new WP_Error(); $product_qty_in_cart = $this->get_cart_item_quantities(); // First stock check loop foreach ($this->get_cart() as $cart_item_key => $values) { $_product = $values['data']; /** * Check stock based on stock-status. */ if (!$_product->is_in_stock()) { $error->add('out-of-stock', sprintf(__('Sorry, "%s" is not in stock. Please edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce'), $_product->get_title())); return $error; } if (!$_product->managing_stock()) { continue; } $check_qty = $_product->is_type('variation') && true === $_product->managing_stock() ? $product_qty_in_cart[$values['variation_id']] : $product_qty_in_cart[$values['product_id']]; /** * Check stock based on all items in the cart. */ if (!$_product->has_enough_stock($check_qty)) { $error->add('out-of-stock', sprintf(__('Sorry, we do not have enough "%s" in stock to fulfill your order (%s in stock). Please edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce'), $_product->get_title(), $_product->get_stock_quantity())); return $error; } /** * Finally consider any held stock, from pending orders. */ if (get_option('woocommerce_hold_stock_minutes') > 0 && !$_product->backorders_allowed()) { $order_id = isset(WC()->session->order_awaiting_payment) ? absint(WC()->session->order_awaiting_payment) : 0; $held_stock = $wpdb->get_var($wpdb->prepare("\n\t\t\t\t\t\t\tSELECT SUM( order_item_meta.meta_value ) AS held_qty\n\t\t\t\t\t\t\tFROM {$wpdb->posts} AS posts\n\t\t\t\t\t\t\tLEFT JOIN {$wpdb->prefix}woocommerce_order_items as order_items ON posts.ID = order_items.order_id\n\t\t\t\t\t\t\tLEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta as order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id\n\t\t\t\t\t\t\tLEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta as order_item_meta2 ON order_items.order_item_id = order_item_meta2.order_item_id\n\t\t\t\t\t\t\tWHERE \torder_item_meta.meta_key = '_qty'\n\t\t\t\t\t\t\tAND \torder_item_meta2.meta_key = %s AND order_item_meta2.meta_value = %d\n\t\t\t\t\t\t\tAND \tposts.post_type IN ( '" . implode("','", wc_get_order_types()) . "' )\n\t\t\t\t\t\t\tAND \tposts.post_status = 'wc-pending'\n\t\t\t\t\t\t\tAND\t\tposts.ID != %d;", $_product->is_type('variation') && true === $_product->managing_stock() ? '_variation_id' : '_product_id', $_product->is_type('variation') && true === $_product->managing_stock() ? $values['variation_id'] : $values['product_id'], $order_id)); $not_enough_stock = false; if ($_product->is_type('variation') && 'parent' === $_product->managing_stock() && $_product->parent->get_stock_quantity() < $held_stock + $check_qty) { $not_enough_stock = true; } elseif ($_product->get_stock_quantity() < $held_stock + $check_qty) { $not_enough_stock = true; } if ($not_enough_stock) { $error->add('out-of-stock', sprintf(__('Sorry, we do not have enough "%s" in stock to fulfill your order right now. Please try again in %d minutes or edit your cart and try again. We apologise for any inconvenience caused.', 'woocommerce'), $_product->get_title(), get_option('woocommerce_hold_stock_minutes'))); return $error; } } } return true; }
/** * Get the main chart. * * @return string */ public function get_main_chart() { global $wpdb; $query_data = array('order_item_name' => array('type' => 'order_item', 'function' => '', 'name' => 'tax_rate'), 'tax_amount' => array('type' => 'order_item_meta', 'order_item_type' => 'tax', 'function' => '', 'name' => 'tax_amount'), 'shipping_tax_amount' => array('type' => 'order_item_meta', 'order_item_type' => 'tax', 'function' => '', 'name' => 'shipping_tax_amount'), 'rate_id' => array('type' => 'order_item_meta', 'order_item_type' => 'tax', 'function' => '', 'name' => 'rate_id'), 'ID' => array('type' => 'post_data', 'function' => '', 'name' => 'post_id')); $query_where = array(array('key' => 'order_item_type', 'value' => 'tax', 'operator' => '='), array('key' => 'order_item_name', 'value' => '', 'operator' => '!=')); $tax_rows_orders = $this->get_order_report_data(array('data' => $query_data, 'where' => $query_where, 'order_by' => 'posts.post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => array_merge(wc_get_order_types('sales-reports'), array('shop_order_refund')), 'order_status' => array('completed', 'processing', 'on-hold'), 'parent_order_status' => array('completed', 'processing', 'on-hold'))); // Merge $tax_rows = array(); foreach ($tax_rows_orders as $tax_row) { $key = $tax_row->rate_id; $tax_rows[$key] = isset($tax_rows[$key]) ? $tax_rows[$key] : (object) array('tax_amount' => 0, 'shipping_tax_amount' => 0, 'total_orders' => 0); if ('shop_order_refund' !== get_post_type($tax_row->post_id)) { $tax_rows[$key]->total_orders += 1; } $tax_rows[$key]->tax_rate = $tax_row->tax_rate; $tax_rows[$key]->tax_amount += wc_round_tax_total($tax_row->tax_amount); $tax_rows[$key]->shipping_tax_amount += wc_round_tax_total($tax_row->shipping_tax_amount); } ?> <table class="widefat"> <thead> <tr> <th><?php _e('Tax', 'woocommerce'); ?> </th> <th><?php _e('Rate', 'woocommerce'); ?> </th> <th class="total_row"><?php _e('Number of Orders', 'woocommerce'); ?> </th> <th class="total_row"><?php _e('Tax Amount', 'woocommerce'); ?> <?php echo wc_help_tip(__('This is the sum of the "Tax Rows" tax amount within your orders.', 'woocommerce')); ?> </th> <th class="total_row"><?php _e('Shipping Tax Amount', 'woocommerce'); ?> <?php echo wc_help_tip(__('This is the sum of the "Tax Rows" shipping tax amount within your orders.', 'woocommerce')); ?> </th> <th class="total_row"><?php _e('Total Tax', 'woocommerce'); ?> <?php echo wc_help_tip(__('This is the total tax for the rate (shipping tax + product tax).', 'woocommerce')); ?> </th> </tr> </thead> <?php if ($tax_rows) { ?> <tbody> <?php foreach ($tax_rows as $rate_id => $tax_row) { $rate = $wpdb->get_var($wpdb->prepare("SELECT tax_rate FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %d;", $rate_id)); ?> <tr> <th scope="row"><?php echo apply_filters('woocommerce_reports_taxes_tax_rate', $tax_row->tax_rate, $rate_id, $tax_row); ?> </th> <td><?php echo apply_filters('woocommerce_reports_taxes_rate', $rate, $rate_id, $tax_row); ?> %</td> <td class="total_row"><?php echo $tax_row->total_orders; ?> </td> <td class="total_row"><?php echo wc_price($tax_row->tax_amount); ?> </td> <td class="total_row"><?php echo wc_price($tax_row->shipping_tax_amount); ?> </td> <td class="total_row"><?php echo wc_price($tax_row->tax_amount + $tax_row->shipping_tax_amount); ?> </td> </tr> <?php } ?> </tbody> <tfoot> <tr> <th scope="row" colspan="3"><?php _e('Total', 'woocommerce'); ?> </th> <th class="total_row"><?php echo wc_price(wc_round_tax_total(array_sum(wp_list_pluck((array) $tax_rows, 'tax_amount')))); ?> </th> <th class="total_row"><?php echo wc_price(wc_round_tax_total(array_sum(wp_list_pluck((array) $tax_rows, 'shipping_tax_amount')))); ?> </th> <th class="total_row"><strong><?php echo wc_price(wc_round_tax_total(array_sum(wp_list_pluck((array) $tax_rows, 'tax_amount')) + array_sum(wp_list_pluck((array) $tax_rows, 'shipping_tax_amount')))); ?> </strong></th> </tr> </tfoot> <?php } else { ?> <tbody> <tr> <td><?php _e('No taxes found in this period', 'woocommerce'); ?> </td> </tr> </tbody> <?php } ?> </table> <?php }
/** * Product selection */ public function products_widget() { ?> <h4 class="section_title"><span><?php _e('Product Search', 'woocommerce'); ?> </span></h4> <div class="section"> <form method="GET"> <div> <input type="hidden" class="wc-product-search" style="width:203px;" name="product_ids[]" data-placeholder="<?php _e('Search for a product…', 'woocommerce'); ?> " data-action="woocommerce_json_search_products_and_variations" /> <input type="submit" class="submit button" value="<?php _e('Show', 'woocommerce'); ?> " /> <input type="hidden" name="range" value="<?php if (!empty($_GET['range'])) { echo esc_attr($_GET['range']); } ?> " /> <input type="hidden" name="start_date" value="<?php if (!empty($_GET['start_date'])) { echo esc_attr($_GET['start_date']); } ?> " /> <input type="hidden" name="end_date" value="<?php if (!empty($_GET['end_date'])) { echo esc_attr($_GET['end_date']); } ?> " /> <input type="hidden" name="page" value="<?php if (!empty($_GET['page'])) { echo esc_attr($_GET['page']); } ?> " /> <input type="hidden" name="tab" value="<?php if (!empty($_GET['tab'])) { echo esc_attr($_GET['tab']); } ?> " /> <input type="hidden" name="report" value="<?php if (!empty($_GET['report'])) { echo esc_attr($_GET['report']); } ?> " /> </div> </form> </div> <h4 class="section_title"><span><?php _e('Top Sellers', 'woocommerce'); ?> </span></h4> <div class="section"> <table cellspacing="0"> <?php $top_sellers = $this->get_order_report_data(array('data' => array('_product_id' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => '', 'name' => 'product_id'), '_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_qty')), 'where_meta' => array(array('type' => 'order_item_meta', 'meta_key' => '_line_subtotal', 'meta_value' => '0', 'operator' => '>')), 'order_by' => 'order_item_qty DESC', 'group_by' => 'product_id', 'limit' => 12, 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'))); if ($top_sellers) { foreach ($top_sellers as $product) { echo '<tr class="' . (in_array($product->product_id, $this->product_ids) ? 'active' : '') . '"> <td class="count">' . $product->order_item_qty . '</td> <td class="name"><a href="' . esc_url(add_query_arg('product_ids', $product->product_id)) . '">' . get_the_title($product->product_id) . '</a></td> <td class="sparkline">' . $this->sales_sparkline($product->product_id, 7, 'count') . '</td> </tr>'; } } else { echo '<tr><td colspan="3">' . __('No products found in range', 'woocommerce') . '</td></tr>'; } ?> </table> </div> <h4 class="section_title"><span><?php _e('Top Freebies', 'woocommerce'); ?> </span></h4> <div class="section"> <table cellspacing="0"> <?php $top_freebies = $this->get_order_report_data(array('data' => array('_product_id' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => '', 'name' => 'product_id'), '_qty' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_qty')), 'where_meta' => array(array('type' => 'order_item_meta', 'meta_key' => '_line_subtotal', 'meta_value' => '0', 'operator' => '=')), 'order_by' => 'order_item_qty DESC', 'group_by' => 'product_id', 'limit' => 12, 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types('order-count'), 'nocache' => true)); if ($top_freebies) { foreach ($top_freebies as $product) { echo '<tr class="' . (in_array($product->product_id, $this->product_ids) ? 'active' : '') . '"> <td class="count">' . $product->order_item_qty . '</td> <td class="name"><a href="' . esc_url(add_query_arg('product_ids', $product->product_id)) . '">' . get_the_title($product->product_id) . '</a></td> <td class="sparkline">' . $this->sales_sparkline($product->product_id, 7, 'count') . '</td> </tr>'; } } else { echo '<tr><td colspan="3">' . __('No products found in range', 'woocommerce') . '</td></tr>'; } ?> </table> </div> <h4 class="section_title"><span><?php _e('Top Earners', 'woocommerce'); ?> </span></h4> <div class="section"> <table cellspacing="0"> <?php $top_earners = $this->get_order_report_data(array('data' => array('_product_id' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => '', 'name' => 'product_id'), '_line_total' => array('type' => 'order_item_meta', 'order_item_type' => 'line_item', 'function' => 'SUM', 'name' => 'order_item_total')), 'order_by' => 'order_item_total DESC', 'group_by' => 'product_id', 'limit' => 12, 'query_type' => 'get_results', 'filter_range' => true)); if ($top_earners) { foreach ($top_earners as $product) { echo '<tr class="' . (in_array($product->product_id, $this->product_ids) ? 'active' : '') . '"> <td class="count">' . wc_price($product->order_item_total) . '</td> <td class="name"><a href="' . esc_url(add_query_arg('product_ids', $product->product_id)) . '">' . get_the_title($product->product_id) . '</a></td> <td class="sparkline">' . $this->sales_sparkline($product->product_id, 7, 'sales') . '</td> </tr>'; } } else { echo '<tr><td colspan="3">' . __('No products found in range', 'woocommerce') . '</td></tr>'; } ?> </table> </div> <script type="text/javascript"> jQuery('.section_title').click(function(){ var next_section = jQuery(this).next('.section'); if ( jQuery(next_section).is(':visible') ) return false; jQuery('.section:visible').slideUp(); jQuery('.section_title').removeClass('open'); jQuery(this).addClass('open').next('.section').slideDown(); return false; }); jQuery('.section').slideUp( 100, function() { <?php if (empty($this->product_ids)) { ?> jQuery('.section_title:eq(1)').click(); <?php } ?> }); </script> <?php }
/** * Get report totals such as order totals and discount amounts. * * Data example: * * '_order_total' => array( * 'type' => 'meta', * 'function' => 'SUM', * 'name' => 'total_sales' * ) * * @param array $args * @return mixed depending on query_type */ public function get_order_report_data($args = array()) { global $wpdb; $default_args = array('data' => array(), 'where' => array(), 'where_meta' => array(), 'query_type' => 'get_row', 'group_by' => '', 'order_by' => '', 'limit' => '', 'filter_range' => false, 'nocache' => false, 'debug' => false, 'order_types' => wc_get_order_types('reports'), 'order_status' => array('completed', 'processing', 'on-hold'), 'parent_order_status' => false); $args = apply_filters('woocommerce_reports_get_order_report_data_args', $args); $args = wp_parse_args($args, $default_args); extract($args); if (empty($data)) { return ''; } $order_status = apply_filters('woocommerce_reports_order_statuses', $order_status); $query = array(); $select = array(); foreach ($data as $key => $value) { $distinct = ''; if (isset($value['distinct'])) { $distinct = 'DISTINCT'; } switch ($value['type']) { case 'meta': $get_key = "meta_{$key}.meta_value"; break; case 'parent_meta': $get_key = "parent_meta_{$key}.meta_value"; break; case 'post_data': $get_key = "posts.{$key}"; break; case 'order_item_meta': $get_key = "order_item_meta_{$key}.meta_value"; break; case 'order_item': $get_key = "order_items.{$key}"; break; default: continue; } if ($value['function']) { $get = "{$value['function']}({$distinct} {$get_key})"; } else { $get = "{$distinct} {$get_key}"; } $select[] = "{$get} as {$value['name']}"; } $query['select'] = "SELECT " . implode(',', $select); $query['from'] = "FROM {$wpdb->posts} AS posts"; // Joins $joins = array(); foreach ($data + $where as $key => $value) { $join_type = isset($value['join_type']) ? $value['join_type'] : 'INNER'; $type = isset($value['type']) ? $value['type'] : false; switch ($type) { case 'meta': $joins["meta_{$key}"] = "{$join_type} JOIN {$wpdb->postmeta} AS meta_{$key} ON ( posts.ID = meta_{$key}.post_id AND meta_{$key}.meta_key = '{$key}' )"; break; case 'parent_meta': $joins["parent_meta_{$key}"] = "{$join_type} JOIN {$wpdb->postmeta} AS parent_meta_{$key} ON (posts.post_parent = parent_meta_{$key}.post_id) AND (parent_meta_{$key}.meta_key = '{$key}')"; break; case 'order_item_meta': $joins["order_items"] = "{$join_type} JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON (posts.ID = order_items.order_id)"; if (!empty($value['order_item_type'])) { $joins["order_items"] .= " AND (order_items.order_item_type = '{$value['order_item_type']}')"; } $joins["order_item_meta_{$key}"] = "{$join_type} JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta_{$key} ON " . "(order_items.order_item_id = order_item_meta_{$key}.order_item_id) " . " AND (order_item_meta_{$key}.meta_key = '{$key}')"; break; case 'order_item': $joins["order_items"] = "{$join_type} JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON posts.ID = order_items.order_id"; break; } } if (!empty($where_meta)) { foreach ($where_meta as $value) { if (!is_array($value)) { continue; } $join_type = isset($value['join_type']) ? $value['join_type'] : 'INNER'; $type = isset($value['type']) ? $value['type'] : false; $key = is_array($value['meta_key']) ? $value['meta_key'][0] . '_array' : $value['meta_key']; if ('order_item_meta' === $type) { $joins["order_items"] = "{$join_type} JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON posts.ID = order_items.order_id"; $joins["order_item_meta_{$key}"] = "{$join_type} JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta_{$key} ON order_items.order_item_id = order_item_meta_{$key}.order_item_id"; } else { // If we have a where clause for meta, join the postmeta table $joins["meta_{$key}"] = "{$join_type} JOIN {$wpdb->postmeta} AS meta_{$key} ON posts.ID = meta_{$key}.post_id"; } } } if (!empty($parent_order_status)) { $joins["parent"] = "LEFT JOIN {$wpdb->posts} AS parent ON posts.post_parent = parent.ID"; } $query['join'] = implode(' ', $joins); $query['where'] = "\n\t\t\tWHERE \tposts.post_type \tIN ( '" . implode("','", $order_types) . "' )\n\t\t\t"; if (!empty($order_status)) { $query['where'] .= "\n\t\t\t\tAND \tposts.post_status \tIN ( 'wc-" . implode("','wc-", $order_status) . "')\n\t\t\t"; } if (!empty($parent_order_status)) { if (!empty($order_status)) { $query['where'] .= " AND ( parent.post_status IN ( 'wc-" . implode("','wc-", $parent_order_status) . "') OR parent.ID IS NULL ) "; } else { $query['where'] .= " AND parent.post_status IN ( 'wc-" . implode("','wc-", $parent_order_status) . "') "; } } if ($filter_range) { $query['where'] .= "\n\t\t\t\tAND \tposts.post_date >= '" . date('Y-m-d', $this->start_date) . "'\n\t\t\t\tAND \tposts.post_date < '" . date('Y-m-d', strtotime('+1 DAY', $this->end_date)) . "'\n\t\t\t"; } if (!empty($where_meta)) { $relation = isset($where_meta['relation']) ? $where_meta['relation'] : 'AND'; $query['where'] .= " AND ("; foreach ($where_meta as $index => $value) { if (!is_array($value)) { continue; } $key = is_array($value['meta_key']) ? $value['meta_key'][0] . '_array' : $value['meta_key']; if (strtolower($value['operator']) == 'in') { if (is_array($value['meta_value'])) { $value['meta_value'] = implode("','", $value['meta_value']); } if (!empty($value['meta_value'])) { $where_value = "IN ('{$value['meta_value']}')"; } } else { $where_value = "{$value['operator']} '{$value['meta_value']}'"; } if (!empty($where_value)) { if ($index > 0) { $query['where'] .= ' ' . $relation; } if (isset($value['type']) && $value['type'] == 'order_item_meta') { if (is_array($value['meta_key'])) { $query['where'] .= " ( order_item_meta_{$key}.meta_key IN ('" . implode("','", $value['meta_key']) . "')"; } else { $query['where'] .= " ( order_item_meta_{$key}.meta_key = '{$value['meta_key']}'"; } $query['where'] .= " AND order_item_meta_{$key}.meta_value {$where_value} )"; } else { if (is_array($value['meta_key'])) { $query['where'] .= " ( meta_{$key}.meta_key IN ('" . implode("','", $value['meta_key']) . "')"; } else { $query['where'] .= " ( meta_{$key}.meta_key = '{$value['meta_key']}'"; } $query['where'] .= " AND meta_{$key}.meta_value {$where_value} )"; } } } $query['where'] .= ")"; } if (!empty($where)) { foreach ($where as $value) { if (strtolower($value['operator']) == 'in') { if (is_array($value['value'])) { $value['value'] = implode("','", $value['value']); } if (!empty($value['value'])) { $where_value = "IN ('{$value['value']}')"; } } else { $where_value = "{$value['operator']} '{$value['value']}'"; } if (!empty($where_value)) { $query['where'] .= " AND {$value['key']} {$where_value}"; } } } if ($group_by) { $query['group_by'] = "GROUP BY {$group_by}"; } if ($order_by) { $query['order_by'] = "ORDER BY {$order_by}"; } if ($limit) { $query['limit'] = "LIMIT {$limit}"; } $query = apply_filters('woocommerce_reports_get_order_report_query', $query); $query = implode(' ', $query); $query_hash = md5($query_type . $query); $cached_results = get_transient(strtolower(get_class($this))); if ($debug) { echo '<pre>'; print_r($query); echo '</pre>'; } if ($debug || $nocache || false === $cached_results || !isset($cached_results[$query_hash])) { // Enable big selects for reports $wpdb->query('SET SESSION SQL_BIG_SELECTS=1'); $cached_results[$query_hash] = apply_filters('woocommerce_reports_get_order_report_data', $wpdb->{$query_type}($query), $data); set_transient(strtolower(get_class($this)), $cached_results, DAY_IN_SECONDS); } $result = $cached_results[$query_hash]; return $result; }