1 <?php
2 3 4 5 6 7 8 9
10 class WC_Report_Coupon_Usage extends WC_Admin_Report {
11
12 public $chart_colours = array();
13 public $coupon_codes = array();
14
15 16 17
18 public function __construct() {
19 if ( isset( $_GET['coupon_codes'] ) && is_array( $_GET['coupon_codes'] ) ) {
20 $this->coupon_codes = array_filter( array_map( 'sanitize_text_field', $_GET['coupon_codes'] ) );
21 } elseif ( isset( $_GET['coupon_codes'] ) ) {
22 $this->coupon_codes = array_filter( array( sanitize_text_field( $_GET['coupon_codes'] ) ) );
23 }
24 }
25
26 27 28 29
30 public function get_chart_legend() {
31 $legend = array();
32
33 $total_discount = $this->get_order_report_data( array(
34 'data' => array(
35 'discount_amount' => array(
36 'type' => 'order_item_meta',
37 'order_item_type' => 'coupon',
38 'function' => 'SUM',
39 'name' => 'discount_amount'
40 )
41 ),
42 'where' => array(
43 array(
44 'type' => 'order_item',
45 'key' => 'order_item_name',
46 'value' => $this->coupon_codes,
47 'operator' => 'IN'
48 )
49 ),
50 'query_type' => 'get_var',
51 'filter_range' => true
52 ) );
53
54 $total_coupons = absint( $this->get_order_report_data( array(
55 'data' => array(
56 'order_item_name' => array(
57 'type' => 'order_item',
58 'order_item_type' => 'coupon',
59 'function' => 'COUNT',
60 'name' => 'order_coupon_count'
61 )
62 ),
63 'where' => array(
64 array(
65 'type' => 'order_item',
66 'key' => 'order_item_name',
67 'value' => $this->coupon_codes,
68 'operator' => 'IN'
69 )
70 ),
71 'query_type' => 'get_var',
72 'filter_range' => true
73 ) ) );
74
75 $legend[] = array(
76 'title' => sprintf( __( '%s discounts in total', 'woocommerce' ), '<strong>' . wc_price( $total_discount ) . '</strong>' ),
77 'color' => $this->chart_colours['discount_amount'],
78 'highlight_series' => 1
79 );
80
81 $legend[] = array(
82 'title' => sprintf( __( '%s coupons used in total', 'woocommerce' ), '<strong>' . $total_coupons . '</strong>' ),
83 'color' => $this->chart_colours['coupon_count' ],
84 'highlight_series' => 0
85 );
86
87 return $legend;
88 }
89
90 91 92
93 public function output_report() {
94 $ranges = array(
95 'year' => __( 'Year', 'woocommerce' ),
96 'last_month' => __( 'Last Month', 'woocommerce' ),
97 'month' => __( 'This Month', 'woocommerce' ),
98 '7day' => __( 'Last 7 Days', 'woocommerce' )
99 );
100
101 $this->chart_colours = array(
102 'discount_amount' => '#3498db',
103 'coupon_count' => '#d4d9dc',
104 );
105
106 $current_range = ! empty( $_GET['range'] ) ? $_GET['range'] : '7day';
107
108 if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) {
109 $current_range = '7day';
110 }
111
112 $this->calculate_current_range( $current_range );
113
114 include( WC()->plugin_path() . '/includes/admin/views/html-report-by-date.php');
115 }
116
117 118 119 120
121 public function get_chart_widgets() {
122 $widgets = array();
123
124 $widgets[] = array(
125 'title' => '',
126 'callback' => array( $this, 'coupons_widget' )
127 );
128
129 return $widgets;
130 }
131
132 133 134 135
136 public function coupons_widget() {
137 ?>
138 <h4 class="section_title"><span><?php _e( 'Filter by coupon', 'woocommerce' ); ?></span></h4>
139 <div class="section">
140 <form method="GET">
141 <div>
142 <?php
143 $used_coupons = $this->get_order_report_data( array(
144 'data' => array(
145 'order_item_name' => array(
146 'type' => 'order_item',
147 'order_item_type' => 'coupon',
148 'function' => '',
149 'distinct' => true,
150 'name' => 'order_item_name'
151 )
152 ),
153 'where' => array(
154 array(
155 'key' => 'order_item_type',
156 'value' => 'coupon',
157 'operator' => '='
158 )
159 ),
160 'query_type' => 'get_col',
161 'filter_range' => false
162 ) );
163
164 if ( $used_coupons ) :
165 ?>
166 <select id="coupon_codes" name="coupon_codes" class="chosen_select" data-placeholder="<?php _e( 'Choose coupons…', 'woocommerce' ); ?>" style="width:100%;">
167 <option value=""><?php _e( 'All coupons', 'woocommerce' ); ?></option>
168 <?php
169 foreach ( $used_coupons as $coupon ) {
170 echo '<option value="' . esc_attr( $coupon ) . '" ' . selected( in_array( $coupon, $this->coupon_codes ), true, false ) . '>' . $coupon . '</option>';
171 }
172 ?>
173 </select>
174 <input type="submit" class="submit button" value="<?php _e( 'Show', 'woocommerce' ); ?>" />
175 <input type="hidden" name="range" value="<?php if ( ! empty( $_GET['range'] ) ) echo esc_attr( $_GET['range'] ) ?>" />
176 <input type="hidden" name="start_date" value="<?php if ( ! empty( $_GET['start_date'] ) ) echo esc_attr( $_GET['start_date'] ) ?>" />
177 <input type="hidden" name="end_date" value="<?php if ( ! empty( $_GET['end_date'] ) ) echo esc_attr( $_GET['end_date'] ) ?>" />
178 <input type="hidden" name="page" value="<?php if ( ! empty( $_GET['page'] ) ) echo esc_attr( $_GET['page'] ) ?>" />
179 <input type="hidden" name="tab" value="<?php if ( ! empty( $_GET['tab'] ) ) echo esc_attr( $_GET['tab'] ) ?>" />
180 <input type="hidden" name="report" value="<?php if ( ! empty( $_GET['report'] ) ) echo esc_attr( $_GET['report'] ) ?>" />
181 <script type="text/javascript">
182 jQuery(function() {
183 jQuery('select.chosen_select').chosen();
184 });
185 </script>
186 <?php else : ?>
187 <span><?php _e( 'No used coupons found', 'woocommerce' ); ?></span>
188 <?php endif; ?>
189 </div>
190 </form>
191 </div>
192 <h4 class="section_title"><span><?php _e( 'Most Popular', 'woocommerce' ); ?></span></h4>
193 <div class="section">
194 <table cellspacing="0">
195 <?php
196 $most_popular = $this->get_order_report_data( array(
197 'data' => array(
198 'order_item_name' => array(
199 'type' => 'order_item',
200 'order_item_type' => 'coupon',
201 'function' => '',
202 'name' => 'coupon_code'
203 ),
204 'order_item_id' => array(
205 'type' => 'order_item',
206 'order_item_type' => 'coupon',
207 'function' => 'COUNT',
208 'name' => 'coupon_count'
209 ),
210 ),
211 'where' => array(
212 array(
213 'type' => 'order_item',
214 'key' => 'order_item_type',
215 'value' => 'coupon',
216 'operator' => '='
217 )
218 ),
219 'order_by' => 'coupon_count DESC',
220 'group_by' => 'order_item_name',
221 'limit' => 12,
222 'query_type' => 'get_results',
223 'filter_range' => true
224 ) );
225
226 if ( $most_popular ) {
227 foreach ( $most_popular as $coupon ) {
228 echo '<tr class="' . ( in_array( $coupon->coupon_code, $this->coupon_codes ) ? 'active' : '' ) . '">
229 <td class="count" width="1%">' . $coupon->coupon_count . '</td>
230 <td class="name"><a href="' . add_query_arg( 'coupon_codes', $coupon->coupon_code ) . '">' . $coupon->coupon_code . '</a></td>
231 </tr>';
232 }
233 } else {
234 echo '<tr><td colspan="2">' . __( 'No coupons found in range', 'woocommerce' ) . '</td></tr>';
235 }
236 ?>
237 </table>
238 </div>
239 <h4 class="section_title"><span><?php _e( 'Most Discount', 'woocommerce' ); ?></span></h4>
240 <div class="section">
241 <table cellspacing="0">
242 <?php
243 $most_discount = $this->get_order_report_data( array(
244 'data' => array(
245 'order_item_name' => array(
246 'type' => 'order_item',
247 'order_item_type' => 'coupon',
248 'function' => '',
249 'name' => 'coupon_code'
250 ),
251 'discount_amount' => array(
252 'type' => 'order_item_meta',
253 'order_item_type' => 'coupon',
254 'function' => 'SUM',
255 'name' => 'discount_amount'
256 )
257 ),
258 'where' => array(
259 array(
260 'type' => 'order_item',
261 'key' => 'order_item_type',
262 'value' => 'coupon',
263 'operator' => '='
264 )
265 ),
266 'order_by' => 'discount_amount DESC',
267 'group_by' => 'order_item_name',
268 'limit' => 12,
269 'query_type' => 'get_results',
270 'filter_range' => true
271 ) );
272
273 if ( $most_discount ) {
274 foreach ( $most_discount as $coupon ) {
275 echo '<tr class="' . ( in_array( $coupon->coupon_code, $this->coupon_codes ) ? 'active' : '' ) . '">
276 <td class="count" width="1%">' . wc_price( $coupon->discount_amount ) . '</td>
277 <td class="name"><a href="' . add_query_arg( 'coupon_codes', $coupon->coupon_code ) . '">' . $coupon->coupon_code . '</a></td>
278 </tr>';
279 }
280 } else {
281 echo '<tr><td colspan="3">' . __( 'No coupons found in range', 'woocommerce' ) . '</td></tr>';
282 }
283 ?>
284 </table>
285 </div>
286 <script type="text/javascript">
287 jQuery('.section_title').click(function(){
288 var next_section = jQuery(this).next('.section');
289
290 if ( jQuery(next_section).is(':visible') )
291 return false;
292
293 jQuery('.section:visible').slideUp();
294 jQuery('.section_title').removeClass('open');
295 jQuery(this).addClass('open').next('.section').slideDown();
296
297 return false;
298 });
299 jQuery('.section').slideUp( 100, function() {
300 <?php if ( empty( $this->coupon_codes ) ) : ?>
301 jQuery('.section_title:eq(1)').click();
302 <?php else : ?>
303 jQuery('.section_title:eq(0)').click();
304 <?php endif; ?>
305 });
306 </script>
307 <?php
308 }
309
310 311 312
313 public function get_export_button() {
314 $current_range = ! empty( $_GET['range'] ) ? $_GET['range'] : '7day';
315 ?>
316 <a
317 href="#"
318 download="report-<?php echo $current_range; ?>-<?php echo date_i18n( 'Y-m-d', current_time('timestamp') ); ?>.csv"
319 class="export_csv"
320 data-export="chart"
321 data-xaxes="<?php _e( 'Date', 'woocommerce' ); ?>"
322 data-groupby="<?php echo $this->chart_groupby; ?>"
323 >
324 <?php _e( 'Export CSV', 'woocommerce' ); ?>
325 </a>
326 <?php
327 }
328
329 330 331 332
333 public function get_main_chart() {
334 global $wp_locale;
335
336
337 $order_coupon_counts = $this->get_order_report_data( array(
338 'data' => array(
339 'order_item_name' => array(
340 'type' => 'order_item',
341 'order_item_type' => 'coupon',
342 'function' => 'COUNT',
343 'name' => 'order_coupon_count'
344 ),
345 'post_date' => array(
346 'type' => 'post_data',
347 'function' => '',
348 'name' => 'post_date'
349 ),
350 ),
351 'where' => array(
352 array(
353 'type' => 'order_item',
354 'key' => 'order_item_name',
355 'value' => $this->coupon_codes,
356 'operator' => 'IN'
357 )
358 ),
359 'group_by' => $this->group_by_query,
360 'order_by' => 'post_date ASC',
361 'query_type' => 'get_results',
362 'filter_range' => true
363 ) );
364
365 $order_discount_amounts = $this->get_order_report_data( array(
366 'data' => array(
367 'discount_amount' => array(
368 'type' => 'order_item_meta',
369 'order_item_type' => 'coupon',
370 'function' => 'SUM',
371 'name' => 'discount_amount'
372 ),
373 'post_date' => array(
374 'type' => 'post_data',
375 'function' => '',
376 'name' => 'post_date'
377 ),
378 ),
379 'where' => array(
380 array(
381 'type' => 'order_item',
382 'key' => 'order_item_name',
383 'value' => $this->coupon_codes,
384 'operator' => 'IN'
385 )
386 ),
387 'group_by' => $this->group_by_query . ', order_item_name',
388 'order_by' => 'post_date ASC',
389 'query_type' => 'get_results',
390 'filter_range' => true
391 ) );
392
393
394 $order_coupon_counts = $this->prepare_chart_data( $order_coupon_counts, 'post_date', 'order_coupon_count' , $this->chart_interval, $this->start_date, $this->chart_groupby );
395 $order_discount_amounts = $this->prepare_chart_data( $order_discount_amounts, 'post_date', 'discount_amount', $this->chart_interval, $this->start_date, $this->chart_groupby );
396
397
398 $chart_data = json_encode( array(
399 'order_coupon_counts' => array_values( $order_coupon_counts ),
400 'order_discount_amounts' => array_values( $order_discount_amounts )
401 ) );
402 ?>
403 <div class="chart-container">
404 <div class="chart-placeholder main"></div>
405 </div>
406 <script type="text/javascript">
407 var main_chart;
408
409 jQuery(function(){
410 var order_data = jQuery.parseJSON( '<?php echo $chart_data; ?>' );
411
412 var drawGraph = function( highlight ) {
413 var series = [
414 {
415 label: "<?php echo esc_js( __( 'Number of coupons used', 'woocommerce' ) ) ?>",
416 data: order_data.order_coupon_counts,
417 color: '<?php echo $this->chart_colours['coupon_count' ]; ?>',
418 bars: { fillColor: '<?php echo $this->chart_colours['coupon_count' ]; ?>', fill: true, show: true, lineWidth: 0, barWidth: <?php echo $this->barwidth; ?> * 0.5, align: 'center' },
419 shadowSize: 0,
420 hoverable: false
421 },
422 {
423 label: "<?php echo esc_js( __( 'Discount amount', 'woocommerce' ) ) ?>",
424 data: order_data.order_discount_amounts,
425 yaxis: 2,
426 color: '<?php echo $this->chart_colours['discount_amount']; ?>',
427 points: { show: true, radius: 5, lineWidth: 3, fillColor: '#fff', fill: true },
428 lines: { show: true, lineWidth: 4, fill: false },
429 shadowSize: 0,
430 prepend_tooltip: "<?php echo get_woocommerce_currency_symbol(); ?>"
431 }
432 ];
433
434 if ( highlight !== 'undefined' && series[ highlight ] ) {
435 highlight_series = series[ highlight ];
436
437 highlight_series.color = '#9c5d90';
438
439 if ( highlight_series.bars )
440 highlight_series.bars.fillColor = '#9c5d90';
441
442 if ( highlight_series.lines ) {
443 highlight_series.lines.lineWidth = 5;
444 }
445 }
446
447 main_chart = jQuery.plot(
448 jQuery('.chart-placeholder.main'),
449 series,
450 {
451 legend: {
452 show: false
453 },
454 grid: {
455 color: '#aaa',
456 borderColor: 'transparent',
457 borderWidth: 0,
458 hoverable: true
459 },
460 xaxes: [ {
461 color: '#aaa',
462 position: "bottom",
463 tickColor: 'transparent',
464 mode: "time",
465 timeformat: "<?php if ( $this->chart_groupby == 'day' ) echo '%d %b'; else echo '%b'; ?>",
466 monthNames: <?php echo json_encode( array_values( $wp_locale->month_abbrev ) ) ?>,
467 tickLength: 1,
468 minTickSize: [1, "<?php echo $this->chart_groupby; ?>"],
469 font: {
470 color: "#aaa"
471 }
472 } ],
473 yaxes: [
474 {
475 min: 0,
476 minTickSize: 1,
477 tickDecimals: 0,
478 color: '#ecf0f1',
479 font: { color: "#aaa" }
480 },
481 {
482 position: "right",
483 min: 0,
484 tickDecimals: 2,
485 alignTicksWithAxis: 1,
486 color: 'transparent',
487 font: { color: "#aaa" }
488 }
489 ],
490 }
491 );
492
493 jQuery('.chart-placeholder').resize();
494 }
495
496 drawGraph();
497
498 jQuery('.highlight_series').hover(
499 function() {
500 drawGraph( jQuery(this).data('series') );
501 },
502 function() {
503 drawGraph();
504 }
505 );
506 });
507 </script>
508 <?php
509 }
510 }
511