WC_Report_Sales_By_Location

WC_Report_Sales_By_Location.

Defined (1)

The class is defined in the following location(s).

/classes/class-wc-report-sales-by-location.php  
  1. class WC_Report_Sales_By_Location extends WC_Admin_Report { 
  2.  
  3. public $chart_colours = array(); 
  4.  
  5. public $location_data; 
  6. public $location_by; 
  7. public $totals_by; 
  8.  
  9. private $report_data; 
  10.  
  11.  
  12. /** 
  13. * Get report data 
  14. * @return array 
  15. */ 
  16. public function get_report_data() { 
  17. if ( empty( $this->report_data ) ) { 
  18. $this->query_report_data(); 
  19. return $this->report_data; 
  20.  
  21. /** 
  22. * Get all data needed for this report and store in the class 
  23. */ 
  24. private function query_report_data() { 
  25.  
  26. $this->report_data = new stdClass; 
  27.  
  28. $this->report_data->orders = (array) $this->get_order_report_data( 
  29. array( 
  30. 'data' => array( 
  31. '_' . $this->location_by . '_country' => array( 
  32. 'type' => 'meta',  
  33. 'name' => 'countries_data',  
  34. 'function' => null,  
  35. ),  
  36. '_order_total' => array( 
  37. 'type' => 'meta',  
  38. 'function' => 'SUM',  
  39. 'name' => 'total_sales',  
  40. ),  
  41. 'post_date' => array( 
  42. 'type' => 'post_data',  
  43. 'function' => '',  
  44. 'name' => 'post_date',  
  45. ),  
  46. ),  
  47. 'group_by' => 'YEAR(posts.post_date), MONTH(posts.post_date), DAY(posts.post_date), meta__' . $this->location_by . '_country.meta_value',  
  48. 'order_by' => 'post_date ASC',  
  49. 'query_type' => 'get_results',  
  50. 'filter_range' => true,  
  51. 'order_types' => array_merge( array( 'shop_order_refund' ), wc_get_order_types( 'sales-reports' ) ),  
  52. 'order_status' => array( 'completed', 'processing', 'on-hold' ),  
  53. 'parent_order_status' => array( 'completed', 'processing', 'on-hold' ),  
  54. ); 
  55.  
  56. $this->report_data->order_counts = (array) $this->get_order_report_data( 
  57. array( 
  58. 'data' => array( 
  59. '_' . $this->location_by . '_country' => array( 
  60. 'type' => 'meta',  
  61. 'name' => 'countries_data',  
  62. 'function' => null,  
  63. ),  
  64. 'ID' => array( 
  65. 'type' => 'post_data',  
  66. 'function' => 'COUNT',  
  67. 'name' => 'count',  
  68. 'distinct' => true,  
  69. ),  
  70. 'post_date' => array( 
  71. 'type' => 'post_data',  
  72. 'function' => '',  
  73. 'name' => 'post_date',  
  74. ),  
  75. ),  
  76. 'group_by' => 'YEAR(posts.post_date), MONTH(posts.post_date), DAY(posts.post_date), meta__' . $this->location_by . '_country.meta_value',  
  77. 'order_by' => 'post_date ASC',  
  78. 'query_type' => 'get_results',  
  79. 'filter_range' => true,  
  80. 'order_types' => wc_get_order_types( 'order-count' ),  
  81. 'order_status' => array( 'completed', 'processing', 'on-hold' ),  
  82. ); 
  83.  
  84.  
  85. /** 
  86. * Get the legend for the main chart sidebar 
  87. * @return array Array of report legend data 
  88. * @since 1.0 
  89. */ 
  90. public function get_chart_legend() { 
  91.  
  92. $this->location_by = ( isset( $_REQUEST['location_filter'] ) ? $_REQUEST['location_filter'] : 'shipping' ); 
  93. $this->totals_by = ( isset( $_REQUEST['report_by'] ) ? $_REQUEST['report_by'] : 'number-orders' ); 
  94.  
  95. $data = $this->get_report_data(); 
  96.  
  97. add_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'location_report_add_count' ) ); 
  98.  
  99. //Loop through the returned data and set depending on sales or order totals 
  100. $country_data = array(); 
  101. $export_data = array(); 
  102.  
  103. if ( 'number-orders' == $this->totals_by ) { 
  104. foreach ( $data->order_counts as $location_values ) { 
  105. if ( '' == $location_values->countries_data ) { 
  106. $location_values->countries_data = 'UNDEFINED'; 
  107.  
  108. $country_data[ $location_values->countries_data ] = ( isset( $country_data[ $location_values->countries_data ] ) ) ? $location_values->count + $country_data[ $location_values->countries_data ] : $location_values->count; 
  109.  
  110. $export_data[ $location_values->countries_data ][] = $location_values; 
  111.  
  112. $placeholder = __( 'This is the count of orders during this period.', 'woocommerce-location-report' ); 
  113.  
  114. } elseif ( 'order-total' == $this->totals_by ) { 
  115. foreach ( $data->orders as $location_values ) { 
  116.  
  117. if ( '' == $location_values->countries_data ) { 
  118. $location_values->countries_data = 'UNDEFINED'; 
  119.  
  120. $country_data[ $location_values->countries_data ] = ( isset( $country_data[ $location_values->countries_data ] ) ) ? $location_values->total_sales + $country_data[ $location_values->countries_data ] : $location_values->total_sales; 
  121.  
  122. $export_data[ $location_values->countries_data ][] = $location_values; 
  123.  
  124. $placeholder = __( 'This is the sum of the order totals after any refunds and including shipping and taxes.', 'woocommerce-location-report' ); 
  125.  
  126.  
  127. //Pass the data to the screen. 
  128. $this->location_data = $country_data; 
  129. wp_localize_script( 'jvectormap', 'map_data', $this->location_data ); 
  130.  
  131. //If we are using price, then create another set of data with the price set (map does not like adding with price) 
  132. if ( 'order-total' == $this->totals_by ) { 
  133. $sales_data = $this->location_data; 
  134. array_walk( $sales_data, function( &$value, $index ) { 
  135. $value = strip_tags( wc_price( $value ) ); 
  136. } ); 
  137. wp_localize_script( 'jvectormap', 'map_price_data', $sales_data ); 
  138.  
  139. $legend = array(); 
  140.  
  141. $total = array_sum( $country_data ); 
  142.  
  143. if ( 'order-total' == $this->totals_by ) { 
  144. $total = wc_price( $total ); 
  145.  
  146. $legend[] = array( 
  147. 'title' => sprintf( __( '%s orders in this period', 'woocommerce-location-report' ), '<strong>' . $total . '</strong>' ),  
  148. 'placeholder' => $placeholder,  
  149. 'color' => $this->chart_colours['order_total'],  
  150. 'highlight_series' => 1,  
  151. ); 
  152.  
  153. $legend[] = array( 
  154. 'title' => sprintf( __( '%s countries in this period', 'woocommerce-location-report' ), '<strong>' . ( isset( $country_data['UNDEFINED'] ) ? count( $country_data ) - 1 :count( $country_data ) ) . '</strong>' ),  
  155. 'placeholder' => __( 'This is the total number of countries represented in this report.', 'woocommerce-location-report' ),  
  156. 'color' => $this->chart_colours['individual_total'],  
  157. 'highlight_series' => 2,  
  158. ); 
  159.  
  160. /** Export Code */ 
  161. $export_array = array(); 
  162. $report_type = ( 'number-orders' == $this->totals_by ) ? 'count' : 'total_sales'; 
  163.  
  164. foreach ( $export_data as $country => $data ) { 
  165. $export_prep = $this->prepare_chart_data( $data, 'post_date', $report_type, $this->chart_interval, $this->start_date, $this->chart_groupby ); 
  166. $export_array[ $country ] = array_values( $export_prep ); 
  167.  
  168. // Move undefined to the end of the data 
  169. if ( isset( $export_array['UNDEFINED'] ) ) { 
  170. $temp = $export_array['UNDEFINED']; 
  171. unset( $export_array['UNDEFINED'] ); 
  172. $export_array['UNDEFINED'] = $temp; 
  173.  
  174. // Encode in json format 
  175. $chart_data = json_encode( $export_array ); 
  176.  
  177. ?> 
  178. <div class="chart-container" style="display:none !important;"> 
  179. <div class="chart-placeholder main" style="display:none !important;"></div> 
  180. </div> 
  181. <script type="text/javascript"> 
  182. var main_chart; 
  183.  
  184. jQuery(function() { 
  185. var order_data = jQuery.parseJSON( '<?php echo $chart_data; ?>' ); 
  186.  
  187. var series = [ 
  188. <?php 
  189. foreach ( $export_array as $country => $data ) { 
  190. echo "{\n label: \"$country\", \n data: order_data.$country\n }, "; 
  191. ?> 
  192. ]; 
  193.  
  194. main_chart = jQuery.plot( 
  195. jQuery('.chart-placeholder.main'),  
  196. series 
  197. ); 
  198. }); 
  199.  
  200. </script> 
  201. <?php 
  202.  
  203. /** / Export Code */ 
  204.  
  205. return $legend; 
  206.  
  207. /** 
  208. * Add our map widgets to the report screen 
  209. * @return array Array of location report widgets 
  210. * @since 1.0 
  211. */ 
  212. public function get_chart_widgets() { 
  213.  
  214. $widgets = array(); 
  215.  
  216. $widgets[] = array( 
  217. 'title' => __( 'Showing reports for:', 'woocommerce-location-report' ),  
  218. 'callback' => array( $this, 'current_filters' ),  
  219. ); 
  220.  
  221. $widgets[] = array( 
  222. 'title' => '',  
  223. 'callback' => array( $this, 'location_widget' ),  
  224. ); 
  225.  
  226. return $widgets; 
  227.  
  228. /** 
  229. * Widget : Show current filters 
  230. * @since 1.0 
  231. */ 
  232. public function current_filters() { 
  233.  
  234. echo '<p><strong>' . ( ($this->location_by == 'billing' ) ? __( 'Billing Address', 'woocommerce-location-report' ) : __( 'Shipping Address', 'woocommerce-location-report' ) ) . '</strong></p>'; 
  235. echo '<p><strong>' . ( ($this->totals_by == 'order-total' ) ? __( 'Order total', 'woocommerce-location-report' ) : __( 'Number of orders', 'woocommerce-location-report' ) ) . '</strong></p>'; 
  236.  
  237.  
  238. /** 
  239. * Widget : Report filter options 
  240. * @since 1.0 
  241. */ 
  242. public function location_widget() { 
  243. ?> 
  244. <h4 class="section_title"><span><?php _e( 'Report By', 'woocommerce' ); ?></span></h4> 
  245. <div class="section"> 
  246. <table cellspacing="0"> 
  247. <?php echo $this->generate_widget_line( 'report_by', 'number-orders', __( 'Number of orders', 'woocommerce-location-report' ), $this->totals_by ); ?> 
  248. <?php echo $this->generate_widget_line( 'report_by', 'order-total', __( 'Order total', 'woocommerce-location-report' ), $this->totals_by ); ?> 
  249. </table> 
  250. </div> 
  251. <h4 class="section_title"><span><?php _e( 'Location Filter', 'woocommerce' ); ?></span></h4> 
  252. <div class="section"> 
  253. <table cellspacing="0"> 
  254. <?php echo $this->generate_widget_line( 'location_filter', 'shipping', __( 'Shipping Address', 'woocommerce-location-report' ), $this->location_by ); ?> 
  255. <?php echo $this->generate_widget_line( 'location_filter', 'billing', __( 'Billing Address', 'woocommerce-location-report' ), $this->location_by ); ?> 
  256. </table> 
  257. </div> 
  258.  
  259. <?php 
  260. do_action( 'wclr_after_filter_widgets' ); 
  261.  
  262.  
  263. /** 
  264. * Widget : Report filter options 
  265. * @since 1.0 
  266. */ 
  267. public function generate_widget_line( $query_type, $query_value, $query_name, $current_val ) { 
  268.  
  269. $return = '<tr class="active"><td class="count"></td><td class="name">'; 
  270. if ( $query_value != $current_val ) { 
  271. $return .= '<a href="' . add_query_arg( $query_type, $query_value ) . '">' . $query_name . '</a>'; 
  272. } else { 
  273. $return .= $query_name; 
  274. $return .= '</td><td class="sparkline"></td></tr>'; 
  275.  
  276. return $return; 
  277.  
  278.  
  279. /** 
  280. * Output the report 
  281. * @since 1.0 
  282. */ 
  283. public function output_report() { 
  284.  
  285. $ranges = array( 
  286. 'year' => __( 'Year', 'woocommerce' ),  
  287. 'last_month' => __( 'Last Month', 'woocommerce' ),  
  288. 'month' => __( 'This Month', 'woocommerce' ),  
  289. '7day' => __( 'Last 7 Days', 'woocommerce' ),  
  290. ); 
  291.  
  292. $this->chart_colours = array( 
  293. 'order_total' => '#3498db',  
  294. 'individual_total' => '#75b9e7',  
  295. ); 
  296.  
  297. $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; 
  298.  
  299. if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) { 
  300. $current_range = '7day'; 
  301.  
  302. $this->calculate_current_range( $current_range ); 
  303.  
  304. include( WC()->plugin_path() . '/includes/admin/views/html-report-by-date.php' ); 
  305.  
  306.  
  307. /** 
  308. * Output an export link 
  309. * @since 1.0 
  310. */ 
  311. public function get_export_button() { 
  312. $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; 
  313. ?> 
  314. <a 
  315. href="#" 
  316. download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo date_i18n( 'Y-m-d', current_time( 'timestamp' ) ); ?>.csv" 
  317. class="export_csv" 
  318. data-export="chart" 
  319. data-xaxes="<?php _e( 'Date', 'woocommerce' ); ?>" 
  320. data-groupby="<?php echo $this->chart_groupby; ?>" 
  321. <?php _e( 'Export CSV', 'woocommerce' ); ?> 
  322. </a> 
  323. <?php 
  324.  
  325. /** 
  326. * Main Chart : Add the placeholder javascript /div for the location report 
  327. * @since 1.0 
  328. */ 
  329. public function get_main_chart() { 
  330. global $wp_locale; 
  331. ?> 
  332.  
  333. <div class="jvectormap jvectormap-mill" id="world-map" style="height: 500px;"> 
  334. <script type="text/javascript"> 
  335. jQuery(function($) { 
  336. $('#world-map').vectorMap( { 
  337. map: 'world_mill',  
  338. backgroundColor: "transparent",  
  339. regionStyle: { 
  340. initial: { fill: "#d2d2d2"} 
  341. },  
  342. onRegionTipShow: function(e, el, code) { 
  343. <?php 
  344. if ( isset( $_REQUEST['report_by'] ) && 'order-total' == $_REQUEST['report_by'] ) { // show formatted price for order totals ?> 
  345. el.html('<strong>'+(map_price_data[code] ? map_price_data[code] : 0)+' - </strong> '+el.html()); 
  346. <?php 
  347. } else { ?> 
  348. el.html('<strong>'+(map_data[code] ? map_data[code] : 0)+' <?php _e( 'orders', 'woocommerce-location-report' ); ?> - '+'</strong> '+el.html()); 
  349. <?php 
  350. } ?> 
  351. },  
  352. series: { 
  353. regions: [{ 
  354. values: map_data,  
  355. scale: ['#F0C7E8', '#A46497'],  
  356. normalizeFunction: 'polynomial' 
  357. }] 
  358. },  
  359. }); 
  360. }); 
  361. </script> 
  362.  
  363. <?php 
  364.  
  365. /** 
  366. * Add the address count to the sql query 
  367. * @return string sql query data 
  368. * @since 1.0 
  369. */ 
  370. public function location_report_add_count( $query ) { 
  371.  
  372. $sql = preg_replace( '/^SELECT /', 'SELECT COUNT(meta__' . $this->location_by . '_country.meta_value) as countries_data_count, ', $query ); 
  373. return $sql; 
  374.