WC_Report_Sales_By_Date

WC_Report_Sales_By_Date.

Defined (1)

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

/includes/admin/reports/class-wc-report-sales-by-date.php  
  1. class WC_Report_Sales_By_Date extends WC_Admin_Report { 
  2.  
  3. /** 
  4. * Chart colors. 
  5. * @var array 
  6. */ 
  7. public $chart_colours = array(); 
  8.  
  9. /** 
  10. * The report data. 
  11. * @var stdClass 
  12. */ 
  13. private $report_data; 
  14.  
  15. /** 
  16. * Get report data. 
  17. * @return stdClass 
  18. */ 
  19. public function get_report_data() { 
  20. if ( empty( $this->report_data ) ) { 
  21. $this->query_report_data(); 
  22. return $this->report_data; 
  23.  
  24. /** 
  25. * Get all data needed for this report and store in the class. 
  26. */ 
  27. private function query_report_data() { 
  28. $this->report_data = new stdClass; 
  29.  
  30. $this->report_data->order_counts = (array) $this->get_order_report_data( array( 
  31. 'data' => array( 
  32. 'ID' => array( 
  33. 'type' => 'post_data',  
  34. 'function' => 'COUNT',  
  35. 'name' => 'count',  
  36. 'distinct' => true,  
  37. ),  
  38. 'post_date' => array( 
  39. 'type' => 'post_data',  
  40. 'function' => '',  
  41. 'name' => 'post_date',  
  42. ),  
  43. ),  
  44. 'group_by' => $this->group_by_query,  
  45. 'order_by' => 'post_date ASC',  
  46. 'query_type' => 'get_results',  
  47. 'filter_range' => true,  
  48. 'order_types' => wc_get_order_types( 'order-count' ),  
  49. 'order_status' => array( 'completed', 'processing', 'on-hold', 'refunded' ),  
  50. ) ); 
  51.  
  52. $this->report_data->coupons = (array) $this->get_order_report_data( array( 
  53. 'data' => array( 
  54. 'order_item_name' => array( 
  55. 'type' => 'order_item',  
  56. 'function' => '',  
  57. 'name' => 'order_item_name',  
  58. ),  
  59. 'discount_amount' => array( 
  60. 'type' => 'order_item_meta',  
  61. 'order_item_type' => 'coupon',  
  62. 'function' => 'SUM',  
  63. 'name' => 'discount_amount',  
  64. ),  
  65. 'post_date' => array( 
  66. 'type' => 'post_data',  
  67. 'function' => '',  
  68. 'name' => 'post_date',  
  69. ),  
  70. ),  
  71. 'where' => array( 
  72. array( 
  73. 'key' => 'order_items.order_item_type',  
  74. 'value' => 'coupon',  
  75. 'operator' => '=',  
  76. ),  
  77. ),  
  78. 'group_by' => $this->group_by_query . ', order_item_name',  
  79. 'order_by' => 'post_date ASC',  
  80. 'query_type' => 'get_results',  
  81. 'filter_range' => true,  
  82. 'order_types' => wc_get_order_types( 'order-count' ),  
  83. 'order_status' => array( 'completed', 'processing', 'on-hold', 'refunded' ),  
  84. ) ); 
  85.  
  86. // All items from orders - even those refunded 
  87. $this->report_data->order_items = (array) $this->get_order_report_data( array( 
  88. 'data' => array( 
  89. '_qty' => array( 
  90. 'type' => 'order_item_meta',  
  91. 'order_item_type' => 'line_item',  
  92. 'function' => 'SUM',  
  93. 'name' => 'order_item_count',  
  94. ),  
  95. 'post_date' => array( 
  96. 'type' => 'post_data',  
  97. 'function' => '',  
  98. 'name' => 'post_date',  
  99. ),  
  100. ),  
  101. 'where' => array( 
  102. array( 
  103. 'key' => 'order_items.order_item_type',  
  104. 'value' => 'line_item',  
  105. 'operator' => '=',  
  106. ),  
  107. ),  
  108. 'group_by' => $this->group_by_query,  
  109. 'order_by' => 'post_date ASC',  
  110. 'query_type' => 'get_results',  
  111. 'filter_range' => true,  
  112. 'order_types' => wc_get_order_types( 'order-count' ),  
  113. 'order_status' => array( 'completed', 'processing', 'on-hold', 'refunded' ),  
  114. ) ); 
  115.  
  116. /** 
  117. * Get total of fully refunded items. 
  118. */ 
  119. $this->report_data->refunded_order_items = absint( $this->get_order_report_data( array( 
  120. 'data' => array( 
  121. '_qty' => array( 
  122. 'type' => 'order_item_meta',  
  123. 'order_item_type' => 'line_item',  
  124. 'function' => 'SUM',  
  125. 'name' => 'order_item_count',  
  126. ),  
  127. ),  
  128. 'where' => array( 
  129. array( 
  130. 'key' => 'order_items.order_item_type',  
  131. 'value' => 'line_item',  
  132. 'operator' => '=',  
  133. ),  
  134. ),  
  135. 'query_type' => 'get_var',  
  136. 'filter_range' => true,  
  137. 'order_types' => wc_get_order_types( 'order-count' ),  
  138. 'order_status' => array( 'refunded' ),  
  139. ) ) ); 
  140.  
  141. /** 
  142. * Order totals by date. Charts should show GROSS amounts to avoid going -ve. 
  143. */ 
  144. $this->report_data->orders = (array) $this->get_order_report_data( array( 
  145. 'data' => array( 
  146. '_order_total' => array( 
  147. 'type' => 'meta',  
  148. 'function' => 'SUM',  
  149. 'name' => 'total_sales',  
  150. ),  
  151. '_order_shipping' => array( 
  152. 'type' => 'meta',  
  153. 'function' => 'SUM',  
  154. 'name' => 'total_shipping',  
  155. ),  
  156. '_order_tax' => array( 
  157. 'type' => 'meta',  
  158. 'function' => 'SUM',  
  159. 'name' => 'total_tax',  
  160. ),  
  161. '_order_shipping_tax' => array( 
  162. 'type' => 'meta',  
  163. 'function' => 'SUM',  
  164. 'name' => 'total_shipping_tax',  
  165. ),  
  166. 'post_date' => array( 
  167. 'type' => 'post_data',  
  168. 'function' => '',  
  169. 'name' => 'post_date',  
  170. ),  
  171. ),  
  172. 'group_by' => $this->group_by_query,  
  173. 'order_by' => 'post_date ASC',  
  174. 'query_type' => 'get_results',  
  175. 'filter_range' => true,  
  176. 'order_types' => wc_get_order_types( 'sales-reports' ),  
  177. 'order_status' => array( 'completed', 'processing', 'on-hold', 'refunded' ),  
  178. ) ); 
  179.  
  180. /** 
  181. * If an order is 100% refunded we should look at the parent's totals, but the refunds dates. 
  182. * We also need to ensure each parent order's values are only counted/summed once. 
  183. */ 
  184. $this->report_data->full_refunds = (array) $this->get_order_report_data( array( 
  185. 'data' => array( 
  186. '_order_total' => array( 
  187. 'type' => 'parent_meta',  
  188. 'function' => '',  
  189. 'name' => 'total_refund',  
  190. ),  
  191. '_order_shipping' => array( 
  192. 'type' => 'parent_meta',  
  193. 'function' => '',  
  194. 'name' => 'total_shipping',  
  195. ),  
  196. '_order_tax' => array( 
  197. 'type' => 'parent_meta',  
  198. 'function' => '',  
  199. 'name' => 'total_tax',  
  200. ),  
  201. '_order_shipping_tax' => array( 
  202. 'type' => 'parent_meta',  
  203. 'function' => '',  
  204. 'name' => 'total_shipping_tax',  
  205. ),  
  206. 'post_date' => array( 
  207. 'type' => 'post_data',  
  208. 'function' => '',  
  209. 'name' => 'post_date',  
  210. ),  
  211. ),  
  212. 'group_by' => 'posts.post_parent',  
  213. 'query_type' => 'get_results',  
  214. 'filter_range' => true,  
  215. 'order_status' => false,  
  216. 'parent_order_status' => array( 'refunded' ),  
  217. ) ); 
  218.  
  219. /** 
  220. * Partial refunds. This includes line items, shipping and taxes. Not grouped by date. 
  221. */ 
  222. $this->report_data->partial_refunds = (array) $this->get_order_report_data( array( 
  223. 'data' => array( 
  224. 'ID' => array( 
  225. 'type' => 'post_data',  
  226. 'function' => '',  
  227. 'name' => 'refund_id',  
  228. ),  
  229. '_refund_amount' => array( 
  230. 'type' => 'meta',  
  231. 'function' => '',  
  232. 'name' => 'total_refund',  
  233. ),  
  234. 'post_date' => array( 
  235. 'type' => 'post_data',  
  236. 'function' => '',  
  237. 'name' => 'post_date',  
  238. ),  
  239. 'order_item_type' => array( 
  240. 'type' => 'order_item',  
  241. 'function' => '',  
  242. 'name' => 'item_type',  
  243. 'join_type' => 'LEFT',  
  244. ),  
  245. '_order_total' => array( 
  246. 'type' => 'meta',  
  247. 'function' => '',  
  248. 'name' => 'total_sales',  
  249. ),  
  250. '_order_shipping' => array( 
  251. 'type' => 'meta',  
  252. 'function' => '',  
  253. 'name' => 'total_shipping',  
  254. 'join_type' => 'LEFT',  
  255. ),  
  256. '_order_tax' => array( 
  257. 'type' => 'meta',  
  258. 'function' => '',  
  259. 'name' => 'total_tax',  
  260. 'join_type' => 'LEFT',  
  261. ),  
  262. '_order_shipping_tax' => array( 
  263. 'type' => 'meta',  
  264. 'function' => '',  
  265. 'name' => 'total_shipping_tax',  
  266. 'join_type' => 'LEFT',  
  267. ),  
  268. '_qty' => array( 
  269. 'type' => 'order_item_meta',  
  270. 'function' => 'SUM',  
  271. 'name' => 'order_item_count',  
  272. 'join_type' => 'LEFT',  
  273. ),  
  274. ),  
  275. 'group_by' => 'refund_id',  
  276. 'order_by' => 'post_date ASC',  
  277. 'query_type' => 'get_results',  
  278. 'filter_range' => true,  
  279. 'order_status' => false,  
  280. 'parent_order_status' => array( 'completed', 'processing', 'on-hold' ),  
  281. ) ); 
  282.  
  283. /** 
  284. * Refund lines - all partial refunds on all order types so we can plot full AND partial refunds on the chart. 
  285. */ 
  286. $this->report_data->refund_lines = (array) $this->get_order_report_data( array( 
  287. 'data' => array( 
  288. 'ID' => array( 
  289. 'type' => 'post_data',  
  290. 'function' => '',  
  291. 'name' => 'refund_id',  
  292. ),  
  293. '_refund_amount' => array( 
  294. 'type' => 'meta',  
  295. 'function' => '',  
  296. 'name' => 'total_refund',  
  297. ),  
  298. 'post_date' => array( 
  299. 'type' => 'post_data',  
  300. 'function' => '',  
  301. 'name' => 'post_date',  
  302. ),  
  303. 'order_item_type' => array( 
  304. 'type' => 'order_item',  
  305. 'function' => '',  
  306. 'name' => 'item_type',  
  307. 'join_type' => 'LEFT',  
  308. ),  
  309. '_order_total' => array( 
  310. 'type' => 'meta',  
  311. 'function' => '',  
  312. 'name' => 'total_sales',  
  313. ),  
  314. '_order_shipping' => array( 
  315. 'type' => 'meta',  
  316. 'function' => '',  
  317. 'name' => 'total_shipping',  
  318. 'join_type' => 'LEFT',  
  319. ),  
  320. '_order_tax' => array( 
  321. 'type' => 'meta',  
  322. 'function' => '',  
  323. 'name' => 'total_tax',  
  324. 'join_type' => 'LEFT',  
  325. ),  
  326. '_order_shipping_tax' => array( 
  327. 'type' => 'meta',  
  328. 'function' => '',  
  329. 'name' => 'total_shipping_tax',  
  330. 'join_type' => 'LEFT',  
  331. ),  
  332. '_qty' => array( 
  333. 'type' => 'order_item_meta',  
  334. 'function' => 'SUM',  
  335. 'name' => 'order_item_count',  
  336. 'join_type' => 'LEFT',  
  337. ),  
  338. ),  
  339. 'group_by' => 'refund_id',  
  340. 'order_by' => 'post_date ASC',  
  341. 'query_type' => 'get_results',  
  342. 'filter_range' => true,  
  343. 'order_status' => false,  
  344. 'parent_order_status' => array( 'completed', 'processing', 'on-hold', 'refunded' ),  
  345. ) ); 
  346.  
  347. /** 
  348. * Total up refunds. Note: when an order is fully refunded, a refund line will be added. 
  349. */ 
  350. $this->report_data->total_tax_refunded = 0; 
  351. $this->report_data->total_shipping_refunded = 0; 
  352. $this->report_data->total_shipping_tax_refunded = 0; 
  353. $this->report_data->total_refunds = 0; 
  354.  
  355. $refunded_orders = array_merge( $this->report_data->partial_refunds, $this->report_data->full_refunds ); 
  356.  
  357. foreach ( $refunded_orders as $key => $value ) { 
  358. $this->report_data->total_tax_refunded += ( $value->total_tax < 0 ? $value->total_tax * -1 : $value->total_tax ); 
  359. $this->report_data->total_refunds += $value->total_refund; 
  360. $this->report_data->total_shipping_tax_refunded += ( $value->total_shipping_tax < 0 ? $value->total_shipping_tax * -1 : $value->total_shipping_tax ); 
  361. $this->report_data->total_shipping_refunded += ( $value->total_shipping < 0 ? $value->total_shipping * -1 : $value->total_shipping ); 
  362.  
  363. // Only applies to parial. 
  364. if ( isset( $value->order_item_count ) ) { 
  365. $this->report_data->refunded_order_items += ( $value->order_item_count < 0 ? $value->order_item_count * -1 : $value->order_item_count ); 
  366.  
  367. // Totals from all orders - including those refunded. Subtract refunded amounts. 
  368. $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 ); 
  369. $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 ); 
  370. $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 ); 
  371.  
  372. // Total the refunds and sales amounts. Sales subract refunds. Note - total_sales also includes shipping costs. 
  373. $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 ); 
  374. $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 ); 
  375.  
  376. // Calculate average based on net 
  377. $this->report_data->average_sales = wc_format_decimal( $this->report_data->net_sales / ( $this->chart_interval + 1 ), 2 ); 
  378. $this->report_data->average_total_sales = wc_format_decimal( $this->report_data->total_sales / ( $this->chart_interval + 1 ), 2 ); 
  379.  
  380. // Total orders and discounts also includes those which have been refunded at some point 
  381. $this->report_data->total_coupons = number_format( array_sum( wp_list_pluck( $this->report_data->coupons, 'discount_amount' ) ), 2, '.', '' ); 
  382. $this->report_data->total_refunded_orders = absint( count( $this->report_data->full_refunds ) ); 
  383. $this->report_data->total_orders = absint( array_sum( wp_list_pluck( $this->report_data->order_counts, 'count' ) ) ) - $this->report_data->total_refunded_orders; 
  384.  
  385. // Item counts 
  386. $this->report_data->total_items = absint( array_sum( wp_list_pluck( $this->report_data->order_items, 'order_item_count' ) ) ) - $this->report_data->refunded_order_items; 
  387.  
  388. // 3rd party filtering of report data 
  389. $this->report_data = apply_filters( 'woocommerce_admin_report_data', $this->report_data ); 
  390.  
  391. /** 
  392. * Get the legend for the main chart sidebar. 
  393. * @return array 
  394. */ 
  395. public function get_chart_legend() { 
  396. $legend = array(); 
  397. $data = $this->get_report_data(); 
  398.  
  399. switch ( $this->chart_groupby ) { 
  400. case 'day' : 
  401. /** translators: %s: average total sales */ 
  402. $average_total_sales_title = sprintf( 
  403. __( '%s average gross daily sales', 'woocommerce' ),  
  404. '<strong>' . wc_price( $data->average_total_sales ) . '</strong>' 
  405. ); 
  406. /** translators: %s: average sales */ 
  407. $average_sales_title = sprintf( 
  408. __( '%s average net daily sales', 'woocommerce' ),  
  409. '<strong>' . wc_price( $data->average_sales ) . '</strong>' 
  410. ); 
  411. break; 
  412. case 'month' : 
  413. default : 
  414. /** translators: %s: average total sales */ 
  415. $average_total_sales_title = sprintf( 
  416. __( '%s average gross monthly sales', 'woocommerce' ),  
  417. '<strong>' . wc_price( $data->average_total_sales ) . '</strong>' 
  418. ); 
  419. /** translators: %s: average sales */ 
  420. $average_sales_title = sprintf( 
  421. __( '%s average net monthly sales', 'woocommerce' ),  
  422. '<strong>' . wc_price( $data->average_sales ) . '</strong>' 
  423. ); 
  424. break; 
  425.  
  426. $legend[] = array( 
  427. /** translators: %s: total sales */ 
  428. 'title' => sprintf( 
  429. __( '%s gross sales in this period', 'woocommerce' ),  
  430. '<strong>' . wc_price( $data->total_sales ) . '</strong>' 
  431. ),  
  432. 'placeholder' => __( 'This is the sum of the order totals after any refunds and including shipping and taxes.', 'woocommerce' ),  
  433. 'color' => $this->chart_colours['sales_amount'],  
  434. 'highlight_series' => 6,  
  435. ); 
  436. if ( $data->average_total_sales > 0 ) { 
  437. $legend[] = array( 
  438. 'title' => $average_total_sales_title,  
  439. 'color' => $this->chart_colours['average'],  
  440. 'highlight_series' => 2,  
  441. ); 
  442.  
  443. $legend[] = array( 
  444. /** translators: %s: net sales */ 
  445. 'title' => sprintf( 
  446. __( '%s net sales in this period', 'woocommerce' ),  
  447. '<strong>' . wc_price( $data->net_sales ) . '</strong>' 
  448. ),  
  449. 'placeholder' => __( 'This is the sum of the order totals after any refunds and excluding shipping and taxes.', 'woocommerce' ),  
  450. 'color' => $this->chart_colours['net_sales_amount'],  
  451. 'highlight_series' => 7,  
  452. ); 
  453. if ( $data->average_sales > 0 ) { 
  454. $legend[] = array( 
  455. 'title' => $average_sales_title,  
  456. 'color' => $this->chart_colours['net_average'],  
  457. 'highlight_series' => 3,  
  458. ); 
  459.  
  460. $legend[] = array( 
  461. /** translators: %s: total orders */ 
  462. 'title' => sprintf( 
  463. __( '%s orders placed', 'woocommerce' ),  
  464. '<strong>' . $data->total_orders . '</strong>' 
  465. ),  
  466. 'color' => $this->chart_colours['order_count'],  
  467. 'highlight_series' => 1,  
  468. ); 
  469.  
  470. $legend[] = array( 
  471. /** translators: %s: total items */ 
  472. 'title' => sprintf( 
  473. __( '%s items purchased', 'woocommerce' ),  
  474. '<strong>' . $data->total_items . '</strong>' 
  475. ),  
  476. 'color' => $this->chart_colours['item_count'],  
  477. 'highlight_series' => 0,  
  478. ); 
  479. $legend[] = array( 
  480. /** translators: 1: total refunds 2: total refunded orders 3: refunded items */ 
  481. 'title' => sprintf( 
  482. _n( '%1$s refunded %2$d order (%3$d item)', '%1$s refunded %2$d orders (%3$d items)', $this->report_data->total_refunded_orders, 'woocommerce' ),  
  483. '<strong>' . wc_price( $data->total_refunds ) . '</strong>',  
  484. $this->report_data->total_refunded_orders,  
  485. $this->report_data->refunded_order_items 
  486. ),  
  487. 'color' => $this->chart_colours['refund_amount'],  
  488. 'highlight_series' => 8,  
  489. ); 
  490. $legend[] = array( 
  491. /** translators: %s: total shipping */ 
  492. 'title' => sprintf( 
  493. __( '%s charged for shipping', 'woocommerce' ),  
  494. '<strong>' . wc_price( $data->total_shipping ) . '</strong>' 
  495. ),  
  496. 'color' => $this->chart_colours['shipping_amount'],  
  497. 'highlight_series' => 5,  
  498. ); 
  499. $legend[] = array( 
  500. /** translators: %s: total coupons */ 
  501. 'title' => sprintf( 
  502. __( '%s worth of coupons used', 'woocommerce' ),  
  503. '<strong>' . wc_price( $data->total_coupons ) . '</strong>' 
  504. ),  
  505. 'color' => $this->chart_colours['coupon_amount'],  
  506. 'highlight_series' => 4,  
  507. ); 
  508.  
  509. return $legend; 
  510.  
  511. /** 
  512. * Output the report. 
  513. */ 
  514. public function output_report() { 
  515. $ranges = array( 
  516. 'year' => __( 'Year', 'woocommerce' ),  
  517. 'last_month' => __( 'Last month', 'woocommerce' ),  
  518. 'month' => __( 'This month', 'woocommerce' ),  
  519. '7day' => __( 'Last 7 days', 'woocommerce' ),  
  520. ); 
  521.  
  522. $this->chart_colours = array( 
  523. 'sales_amount' => '#b1d4ea',  
  524. 'net_sales_amount' => '#3498db',  
  525. 'average' => '#b1d4ea',  
  526. 'net_average' => '#3498db',  
  527. 'order_count' => '#dbe1e3',  
  528. 'item_count' => '#ecf0f1',  
  529. 'shipping_amount' => '#5cc488',  
  530. 'coupon_amount' => '#f1c40f',  
  531. 'refund_amount' => '#e74c3c',  
  532. ); 
  533.  
  534. $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; 
  535.  
  536. if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) { 
  537. $current_range = '7day'; 
  538.  
  539. $this->check_current_range_nonce( $current_range ); 
  540. $this->calculate_current_range( $current_range ); 
  541.  
  542. include( WC()->plugin_path() . '/includes/admin/views/html-report-by-date.php' ); 
  543.  
  544. /** 
  545. * Output an export link. 
  546. */ 
  547. public function get_export_button() { 
  548. $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; 
  549. ?> 
  550. <a 
  551. href="#" 
  552. download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo date_i18n( 'Y-m-d', current_time( 'timestamp' ) ); ?>.csv" 
  553. class="export_csv" 
  554. data-export="chart" 
  555. data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>" 
  556. data-exclude_series="2" 
  557. data-groupby="<?php echo $this->chart_groupby; ?>" 
  558. <?php _e( 'Export CSV', 'woocommerce' ); ?> 
  559. </a> 
  560. <?php 
  561.  
  562. /** 
  563. * Round our totals correctly. 
  564. * @param string $amount 
  565. * @return string 
  566. */ 
  567. private function round_chart_totals( $amount ) { 
  568. if ( is_array( $amount ) ) { 
  569. return array( $amount[0], wc_format_decimal( $amount[1], wc_get_price_decimals() ) ); 
  570. } else { 
  571. return wc_format_decimal( $amount, wc_get_price_decimals() ); 
  572.  
  573. /** 
  574. * Get the main chart. 
  575. * @return string 
  576. */ 
  577. public function get_main_chart() { 
  578. global $wp_locale; 
  579.  
  580. // Prepare data for report 
  581. $data = array( 
  582. 'order_counts' => $this->prepare_chart_data( $this->report_data->order_counts, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby ),  
  583. 'order_item_counts' => $this->prepare_chart_data( $this->report_data->order_items, 'post_date', 'order_item_count', $this->chart_interval, $this->start_date, $this->chart_groupby ),  
  584. 'order_amounts' => $this->prepare_chart_data( $this->report_data->orders, 'post_date', 'total_sales', $this->chart_interval, $this->start_date, $this->chart_groupby ),  
  585. 'coupon_amounts' => $this->prepare_chart_data( $this->report_data->coupons, 'post_date', 'discount_amount', $this->chart_interval, $this->start_date, $this->chart_groupby ),  
  586. 'shipping_amounts' => $this->prepare_chart_data( $this->report_data->orders, 'post_date', 'total_shipping', $this->chart_interval, $this->start_date, $this->chart_groupby ),  
  587. 'refund_amounts' => $this->prepare_chart_data( $this->report_data->refund_lines, 'post_date', 'total_refund', $this->chart_interval, $this->start_date, $this->chart_groupby ),  
  588. 'shipping_tax_amounts' => $this->prepare_chart_data( $this->report_data->orders, 'post_date', 'total_shipping_tax', $this->chart_interval, $this->start_date, $this->chart_groupby ),  
  589. 'tax_amounts' => $this->prepare_chart_data( $this->report_data->orders, 'post_date', 'total_tax', $this->chart_interval, $this->start_date, $this->chart_groupby ),  
  590. 'net_order_amounts' => array(),  
  591. 'gross_order_amounts' => array(),  
  592. ); 
  593.  
  594. foreach ( $data['order_amounts'] as $order_amount_key => $order_amount_value ) { 
  595. $data['gross_order_amounts'][ $order_amount_key ] = $order_amount_value; 
  596. $data['gross_order_amounts'][ $order_amount_key ][1] -= $data['refund_amounts'][ $order_amount_key ][1]; 
  597.  
  598. $data['net_order_amounts'][ $order_amount_key ] = $order_amount_value; 
  599. // subtract the sum of the values from net order amounts 
  600. $data['net_order_amounts'][ $order_amount_key ][1] -= 
  601. $data['refund_amounts'][ $order_amount_key ][1] + 
  602. $data['shipping_amounts'][ $order_amount_key ][1] + 
  603. $data['shipping_tax_amounts'][ $order_amount_key ][1] + 
  604. $data['tax_amounts'][ $order_amount_key ][1]; 
  605.  
  606. // 3rd party filtering of report data 
  607. $data = apply_filters( 'woocommerce_admin_report_chart_data', $data ); 
  608.  
  609. // Encode in json format 
  610. $chart_data = json_encode( array( 
  611. 'order_counts' => array_values( $data['order_counts'] ),  
  612. 'order_item_counts' => array_values( $data['order_item_counts'] ),  
  613. 'order_amounts' => array_map( array( $this, 'round_chart_totals' ), array_values( $data['order_amounts'] ) ),  
  614. 'gross_order_amounts' => array_map( array( $this, 'round_chart_totals' ), array_values( $data['gross_order_amounts'] ) ),  
  615. 'net_order_amounts' => array_map( array( $this, 'round_chart_totals' ), array_values( $data['net_order_amounts'] ) ),  
  616. 'shipping_amounts' => array_map( array( $this, 'round_chart_totals' ), array_values( $data['shipping_amounts'] ) ),  
  617. 'coupon_amounts' => array_map( array( $this, 'round_chart_totals' ), array_values( $data['coupon_amounts'] ) ),  
  618. 'refund_amounts' => array_map( array( $this, 'round_chart_totals' ), array_values( $data['refund_amounts'] ) ),  
  619. ) ); 
  620. ?> 
  621. <div class="chart-container"> 
  622. <div class="chart-placeholder main"></div> 
  623. </div> 
  624. <script type="text/javascript"> 
  625.  
  626. var main_chart; 
  627.  
  628. jQuery(function() { 
  629. var order_data = jQuery.parseJSON( '<?php echo $chart_data; ?>' ); 
  630. var drawGraph = function( highlight ) { 
  631. var series = [ 
  632. label: "<?php echo esc_js( __( 'Number of items sold', 'woocommerce' ) ) ?>",  
  633. data: order_data.order_item_counts,  
  634. color: '<?php echo $this->chart_colours['item_count']; ?>',  
  635. bars: { fillColor: '<?php echo $this->chart_colours['item_count']; ?>', fill: true, show: true, lineWidth: 0, barWidth: <?php echo $this->barwidth; ?> * 0.5, align: 'center' },  
  636. shadowSize: 0,  
  637. hoverable: false 
  638. },  
  639. label: "<?php echo esc_js( __( 'Number of orders', 'woocommerce' ) ) ?>",  
  640. data: order_data.order_counts,  
  641. color: '<?php echo $this->chart_colours['order_count']; ?>',  
  642. bars: { fillColor: '<?php echo $this->chart_colours['order_count']; ?>', fill: true, show: true, lineWidth: 0, barWidth: <?php echo $this->barwidth; ?> * 0.5, align: 'center' },  
  643. shadowSize: 0,  
  644. hoverable: false 
  645. },  
  646. label: "<?php echo esc_js( __( 'Average gross sales amount', 'woocommerce' ) ) ?>",  
  647. data: [ [ <?php echo min( array_keys( $data['order_amounts'] ) ); ?>, <?php echo $this->report_data->average_total_sales; ?> ], [ <?php echo max( array_keys( $data['order_amounts'] ) ); ?>, <?php echo $this->report_data->average_total_sales; ?> ] ],  
  648. yaxis: 2,  
  649. color: '<?php echo $this->chart_colours['average']; ?>',  
  650. points: { show: false },  
  651. lines: { show: true, lineWidth: 2, fill: false },  
  652. shadowSize: 0,  
  653. hoverable: false 
  654. },  
  655. label: "<?php echo esc_js( __( 'Average net sales amount', 'woocommerce' ) ) ?>",  
  656. data: [ [ <?php echo min( array_keys( $data['order_amounts'] ) ); ?>, <?php echo $this->report_data->average_sales; ?> ], [ <?php echo max( array_keys( $data['order_amounts'] ) ); ?>, <?php echo $this->report_data->average_sales; ?> ] ],  
  657. yaxis: 2,  
  658. color: '<?php echo $this->chart_colours['net_average']; ?>',  
  659. points: { show: false },  
  660. lines: { show: true, lineWidth: 2, fill: false },  
  661. shadowSize: 0,  
  662. hoverable: false 
  663. },  
  664. label: "<?php echo esc_js( __( 'Coupon amount', 'woocommerce' ) ) ?>",  
  665. data: order_data.coupon_amounts,  
  666. yaxis: 2,  
  667. color: '<?php echo $this->chart_colours['coupon_amount']; ?>',  
  668. points: { show: true, radius: 5, lineWidth: 2, fillColor: '#fff', fill: true },  
  669. lines: { show: true, lineWidth: 2, fill: false },  
  670. shadowSize: 0,  
  671. <?php echo $this->get_currency_tooltip(); ?> 
  672. },  
  673. label: "<?php echo esc_js( __( 'Shipping amount', 'woocommerce' ) ) ?>",  
  674. data: order_data.shipping_amounts,  
  675. yaxis: 2,  
  676. color: '<?php echo $this->chart_colours['shipping_amount']; ?>',  
  677. points: { show: true, radius: 5, lineWidth: 2, fillColor: '#fff', fill: true },  
  678. lines: { show: true, lineWidth: 2, fill: false },  
  679. shadowSize: 0,  
  680. prepend_tooltip: "<?php echo get_woocommerce_currency_symbol(); ?>" 
  681. },  
  682. label: "<?php echo esc_js( __( 'Gross sales amount', 'woocommerce' ) ) ?>",  
  683. data: order_data.gross_order_amounts,  
  684. yaxis: 2,  
  685. color: '<?php echo $this->chart_colours['sales_amount']; ?>',  
  686. points: { show: true, radius: 5, lineWidth: 2, fillColor: '#fff', fill: true },  
  687. lines: { show: true, lineWidth: 2, fill: false },  
  688. shadowSize: 0,  
  689. <?php echo $this->get_currency_tooltip(); ?> 
  690. },  
  691. label: "<?php echo esc_js( __( 'Net sales amount', 'woocommerce' ) ) ?>",  
  692. data: order_data.net_order_amounts,  
  693. yaxis: 2,  
  694. color: '<?php echo $this->chart_colours['net_sales_amount']; ?>',  
  695. points: { show: true, radius: 6, lineWidth: 4, fillColor: '#fff', fill: true },  
  696. lines: { show: true, lineWidth: 5, fill: false },  
  697. shadowSize: 0,  
  698. <?php echo $this->get_currency_tooltip(); ?> 
  699. },  
  700. label: "<?php echo esc_js( __( 'Refund amount', 'woocommerce' ) ) ?>",  
  701. data: order_data.refund_amounts,  
  702. yaxis: 2,  
  703. color: '<?php echo $this->chart_colours['refund_amount']; ?>',  
  704. points: { show: true, radius: 5, lineWidth: 2, fillColor: '#fff', fill: true },  
  705. lines: { show: true, lineWidth: 2, fill: false },  
  706. shadowSize: 0,  
  707. prepend_tooltip: "<?php echo get_woocommerce_currency_symbol(); ?>" 
  708. },  
  709. ]; 
  710.  
  711. if ( highlight !== 'undefined' && series[ highlight ] ) { 
  712. highlight_series = series[ highlight ]; 
  713.  
  714. highlight_series.color = '#9c5d90'; 
  715.  
  716. if ( highlight_series.bars ) { 
  717. highlight_series.bars.fillColor = '#9c5d90'; 
  718.  
  719. if ( highlight_series.lines ) { 
  720. highlight_series.lines.lineWidth = 5; 
  721.  
  722. main_chart = jQuery.plot( 
  723. jQuery('.chart-placeholder.main'),  
  724. series,  
  725. legend: { 
  726. show: false 
  727. },  
  728. grid: { 
  729. color: '#aaa',  
  730. borderColor: 'transparent',  
  731. borderWidth: 0,  
  732. hoverable: true 
  733. },  
  734. xaxes: [ { 
  735. color: '#aaa',  
  736. position: "bottom",  
  737. tickColor: 'transparent',  
  738. mode: "time",  
  739. timeformat: "<?php echo ( 'day' === $this->chart_groupby ) ? '%d %b' : '%b'; ?>",  
  740. monthNames: <?php echo json_encode( array_values( $wp_locale->month_abbrev ) ) ?>,  
  741. tickLength: 1,  
  742. minTickSize: [1, "<?php echo $this->chart_groupby; ?>"],  
  743. font: { 
  744. color: "#aaa" 
  745. } ],  
  746. yaxes: [ 
  747. min: 0,  
  748. minTickSize: 1,  
  749. tickDecimals: 0,  
  750. color: '#d4d9dc',  
  751. font: { color: "#aaa" } 
  752. },  
  753. position: "right",  
  754. min: 0,  
  755. tickDecimals: 2,  
  756. alignTicksWithAxis: 1,  
  757. color: 'transparent',  
  758. font: { color: "#aaa" } 
  759. ],  
  760. ); 
  761.  
  762. jQuery('.chart-placeholder').resize(); 
  763.  
  764. drawGraph(); 
  765.  
  766. jQuery('.highlight_series').hover( 
  767. function() { 
  768. drawGraph( jQuery(this).data('series') ); 
  769. },  
  770. function() { 
  771. drawGraph(); 
  772. ); 
  773. }); 
  774. </script> 
  775. <?php