mirror of
https://github.com/pronamic/woocommerce-subscriptions.git
synced 2025-10-14 21:32:55 +00:00
1223 lines
46 KiB
PHP
1223 lines
46 KiB
PHP
<?php
|
|
/**
|
|
* Subscriptions Admin Report - Subscription Events by Date
|
|
*
|
|
* Display important historical data for subscription revenue and events, like switches and cancellations.
|
|
*
|
|
* @package WooCommerce Subscriptions
|
|
* @subpackage WC_Subscriptions_Admin_Reports
|
|
* @category Class
|
|
* @author Prospress
|
|
* @since 2.1
|
|
*/
|
|
class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|
|
|
public $chart_colours = array();
|
|
|
|
private $report_data;
|
|
|
|
private $generating_report;
|
|
|
|
/**
|
|
* Sets the query hash for saving the results to enable listing later.
|
|
*
|
|
* @since 2.6.0
|
|
* @param array $query The report query clause array.
|
|
* @return array $query
|
|
*/
|
|
public function set_query_hash( $query ) {
|
|
|
|
if ( in_array( $this->generating_report, array( 'new_subscriptions', 'renewals', 'resubscribes', 'switches' ) ) ) {
|
|
$this->report_data->{$this->generating_report . '_query_hash'} = md5( 'get_results' . implode( ' ', $query ) );
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
/**
|
|
* Get report data
|
|
* @return array
|
|
*/
|
|
public function get_report_data() {
|
|
|
|
if ( empty( $this->report_data ) ) {
|
|
$this->get_data();
|
|
}
|
|
|
|
return $this->report_data;
|
|
}
|
|
|
|
/**
|
|
* Get all data needed for this report and store in the class
|
|
*/
|
|
public function get_data( $args = array() ) {
|
|
global $wpdb;
|
|
|
|
$update_cache = false;
|
|
$default_args = array(
|
|
'no_cache' => false,
|
|
'order_status' => apply_filters( 'woocommerce_reports_order_statuses', array( 'completed', 'processing', 'on-hold' ) ),
|
|
);
|
|
|
|
$args = apply_filters( 'wcs_reports_subscription_events_args', $args );
|
|
$args = wp_parse_args( $args, $default_args );
|
|
|
|
$query_end_date = date( 'Y-m-d', strtotime( '+1 DAY', $this->end_date ) );
|
|
$offset = get_option( 'gmt_offset' );
|
|
|
|
// Convert from Decimal format(eg. 11.5) to a suitable format(eg. +11:30) for CONVERT_TZ() of SQL query.
|
|
$site_timezone = sprintf( '%+02d:%02d', (int) $offset, ( $offset - floor( $offset ) ) * 60 );
|
|
|
|
$this->report_data = new stdClass;
|
|
|
|
// While generating report data via get_order_report_data(), hook in to set the query hash so we can cache the results.
|
|
add_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'set_query_hash' ) );
|
|
|
|
$this->generating_report = 'new_subscriptions';
|
|
$this->report_data->new_subscriptions_data = (array) $this->get_order_report_data(
|
|
array(
|
|
'data' => array(
|
|
'ID' => array(
|
|
'type' => 'post_data',
|
|
'function' => 'COUNT',
|
|
'name' => 'count',
|
|
'distinct' => true,
|
|
),
|
|
'id' => array(
|
|
'type' => 'post_data',
|
|
'function' => 'GROUP_CONCAT',
|
|
'name' => 'subscription_ids',
|
|
'distinct' => true,
|
|
),
|
|
'post_date' => array(
|
|
'type' => 'post_data',
|
|
'function' => '',
|
|
'name' => 'post_date',
|
|
),
|
|
),
|
|
'where' => array(
|
|
'post_status' => array(
|
|
'key' => 'post_status',
|
|
'operator' => 'NOT IN',
|
|
'value' => array( 'trash', 'auto-draft' ),
|
|
),
|
|
),
|
|
'group_by' => $this->group_by_query,
|
|
'order_status' => array(),
|
|
'order_by' => 'post_date ASC',
|
|
'query_type' => 'get_results',
|
|
'filter_range' => true,
|
|
'order_types' => array( 'shop_subscription' ),
|
|
'nocache' => $args['no_cache'],
|
|
)
|
|
);
|
|
|
|
$this->generating_report = 'renewals';
|
|
$this->report_data->renewal_data = (array) $this->get_order_report_data(
|
|
array(
|
|
'data' => array(
|
|
'ID' => array(
|
|
'type' => 'post_data',
|
|
'function' => 'COUNT',
|
|
'name' => 'count',
|
|
'distinct' => true,
|
|
),
|
|
'id' => array(
|
|
'type' => 'post_data',
|
|
'function' => 'GROUP_CONCAT',
|
|
'name' => 'order_ids',
|
|
'distinct' => true,
|
|
),
|
|
'post_date' => array(
|
|
'type' => 'post_data',
|
|
'function' => '',
|
|
'name' => 'post_date',
|
|
),
|
|
'_subscription_renewal' => array(
|
|
'type' => 'meta',
|
|
'function' => '',
|
|
'name' => 'renewal_orders',
|
|
),
|
|
'_order_total' => array(
|
|
'type' => 'meta',
|
|
'function' => 'SUM',
|
|
'name' => 'renewal_totals',
|
|
'join_type' => 'LEFT', // To avoid issues if there is no renewal_total meta
|
|
),
|
|
),
|
|
'where' => array(
|
|
'post_status' => array(
|
|
'key' => 'post_status',
|
|
'operator' => 'NOT IN',
|
|
'value' => array( 'trash', 'auto-draft' ),
|
|
),
|
|
),
|
|
'group_by' => $this->group_by_query,
|
|
'order_status' => $args['order_status'],
|
|
'order_by' => 'post_date ASC',
|
|
'query_type' => 'get_results',
|
|
'filter_range' => true,
|
|
'order_types' => wc_get_order_types( 'order-count' ),
|
|
'nocache' => $args['no_cache'],
|
|
)
|
|
);
|
|
|
|
$this->generating_report = 'resubscribes';
|
|
$this->report_data->resubscribe_data = (array) $this->get_order_report_data(
|
|
array(
|
|
'data' => array(
|
|
'ID' => array(
|
|
'type' => 'post_data',
|
|
'function' => 'COUNT',
|
|
'name' => 'count',
|
|
'distinct' => true,
|
|
),
|
|
'id' => array(
|
|
'type' => 'post_data',
|
|
'function' => 'GROUP_CONCAT',
|
|
'name' => 'order_ids',
|
|
'distinct' => true,
|
|
),
|
|
'post_date' => array(
|
|
'type' => 'post_data',
|
|
'function' => '',
|
|
'name' => 'post_date',
|
|
),
|
|
'_subscription_resubscribe' => array(
|
|
'type' => 'meta',
|
|
'function' => '',
|
|
'name' => 'resubscribe_orders',
|
|
),
|
|
'_order_total' => array(
|
|
'type' => 'meta',
|
|
'function' => 'SUM',
|
|
'name' => 'resubscribe_totals',
|
|
'join_type' => 'LEFT', // To avoid issues if there is no resubscribe_total meta
|
|
),
|
|
),
|
|
'where' => array(
|
|
'post_status' => array(
|
|
'key' => 'post_status',
|
|
'operator' => 'NOT IN',
|
|
'value' => array( 'trash', 'auto-draft' ),
|
|
),
|
|
),
|
|
'group_by' => $this->group_by_query,
|
|
'order_status' => $args['order_status'],
|
|
'order_by' => 'post_date ASC',
|
|
'query_type' => 'get_results',
|
|
'filter_range' => true,
|
|
'order_types' => wc_get_order_types( 'order-count' ),
|
|
'nocache' => $args['no_cache'],
|
|
)
|
|
);
|
|
|
|
$this->generating_report = 'switches';
|
|
$this->report_data->switch_data = (array) $this->get_order_report_data(
|
|
array(
|
|
'data' => array(
|
|
'ID' => array(
|
|
'type' => 'post_data',
|
|
'function' => 'COUNT',
|
|
'name' => 'count',
|
|
'distinct' => true,
|
|
),
|
|
'id' => array(
|
|
'type' => 'post_data',
|
|
'function' => 'GROUP_CONCAT',
|
|
'name' => 'order_ids',
|
|
'distinct' => true,
|
|
),
|
|
'post_date' => array(
|
|
'type' => 'post_data',
|
|
'function' => '',
|
|
'name' => 'post_date',
|
|
),
|
|
'_subscription_switch' => array(
|
|
'type' => 'meta',
|
|
'function' => '',
|
|
'name' => 'switch_orders',
|
|
),
|
|
'_order_total' => array(
|
|
'type' => 'meta',
|
|
'function' => 'SUM',
|
|
'name' => 'switch_totals',
|
|
'join_type' => 'LEFT', // To avoid issues if there is no switch_total meta
|
|
),
|
|
),
|
|
'where' => array(
|
|
'post_status' => array(
|
|
'key' => 'post_status',
|
|
'operator' => 'NOT IN',
|
|
'value' => array( 'trash', 'auto-draft' ),
|
|
),
|
|
),
|
|
'group_by' => $this->group_by_query,
|
|
'order_status' => $args['order_status'],
|
|
'order_by' => 'post_date ASC',
|
|
'query_type' => 'get_results',
|
|
'filter_range' => true,
|
|
'order_types' => wc_get_order_types( 'order-count' ),
|
|
'nocache' => $args['no_cache'],
|
|
)
|
|
);
|
|
|
|
// We've finished generating report data via get_order_report_data() so unhook our query hash flagging function.
|
|
unset( $this->generating_report );
|
|
remove_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'set_query_hash' ) );
|
|
|
|
$cached_results = get_transient( strtolower( get_class( $this ) ) );
|
|
|
|
// Set a default value for cached results for PHP 8.2+ compatibility.
|
|
if ( empty( $cached_results ) ) {
|
|
$cached_results = [];
|
|
}
|
|
|
|
// Check if we need to update the cache with the query results from the figures generated by get_order_report_data().
|
|
foreach ( array( 'new_subscriptions' => 'new_subscriptions', 'renewals' => 'renewal', 'resubscribes' => 'resubscribe', 'switches' => 'switch' ) as $report => $property_key ) { // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
|
$query_hash = $this->report_data->{"{$report}_query_hash"};
|
|
if ( ! isset( $cached_results[ $query_hash ] ) ) {
|
|
$cached_results[ $query_hash ] = $this->report_data->{"{$property_key}_data"};
|
|
$update_cache = true;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* New subscription orders
|
|
*/
|
|
$query = $wpdb->prepare(
|
|
"SELECT SUM(subscriptions.count) as count,
|
|
order_posts.post_date as post_date,
|
|
SUM(order_total_post_meta.meta_value) as signup_totals,
|
|
GROUP_CONCAT( DISTINCT subscriptions.ids ) as subscription_ids
|
|
FROM {$wpdb->posts} AS order_posts
|
|
INNER JOIN (
|
|
SELECT COUNT(DISTINCT(subscription_posts.ID)) as count,
|
|
subscription_posts.post_parent as order_id,
|
|
GROUP_CONCAT( subscription_posts.ID ) as ids
|
|
FROM {$wpdb->posts} as subscription_posts
|
|
WHERE subscription_posts.post_type = 'shop_subscription'
|
|
AND subscription_posts.post_date >= %s
|
|
AND subscription_posts.post_date < %s
|
|
AND subscription_posts.post_status NOT IN ( 'trash', 'auto-draft' )
|
|
GROUP BY order_id
|
|
) AS subscriptions ON subscriptions.order_id = order_posts.ID
|
|
LEFT JOIN {$wpdb->postmeta} AS order_total_post_meta
|
|
ON order_posts.ID = order_total_post_meta.post_id
|
|
WHERE order_posts.post_type IN ( '" . implode( "','", wc_get_order_types( 'order-count' ) ) . "' )
|
|
AND order_posts.post_status IN ( 'wc-" . implode( "','wc-", $args['order_status'] ) . "' )
|
|
AND order_posts.post_date >= %s
|
|
AND order_posts.post_date < %s
|
|
AND order_total_post_meta.meta_key = '_order_total'
|
|
GROUP BY YEAR(order_posts.post_date), MONTH(order_posts.post_date), DAY(order_posts.post_date)
|
|
ORDER BY post_date ASC",
|
|
date( 'Y-m-d', $this->start_date ),
|
|
$query_end_date,
|
|
date( 'Y-m-d', $this->start_date ),
|
|
$query_end_date
|
|
);
|
|
|
|
$query_hash = md5( $query );
|
|
|
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_sign_up_data', (array) $wpdb->get_results( $query ), $args );
|
|
$update_cache = true;
|
|
}
|
|
|
|
$this->report_data->signup_data = $cached_results[ $query_hash ];
|
|
|
|
$this->report_data->signup_orders_query_hash = $query_hash;
|
|
|
|
/*
|
|
* Subscribers by date
|
|
*/
|
|
$query = $wpdb->prepare(
|
|
"SELECT searchdate.Date as date, COUNT( DISTINCT wcsubs.ID) as count, GROUP_CONCAT( DISTINCT wcsubs.ID ) as subscription_ids
|
|
FROM (
|
|
SELECT DATE(last_thousand_days.Date) as Date
|
|
FROM (
|
|
SELECT DATE(%s) - INTERVAL(units.digit + (10 * tens.digit) + (100 * hundreds.digit)) DAY as Date
|
|
FROM (
|
|
SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2
|
|
UNION ALL SELECT 3 UNION ALL SELECT 4
|
|
UNION ALL SELECT 5 UNION ALL SELECT 6
|
|
UNION ALL SELECT 7 UNION ALL SELECT 8
|
|
UNION ALL SELECT 9
|
|
) as units
|
|
CROSS JOIN (
|
|
SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2
|
|
UNION ALL SELECT 3 UNION ALL SELECT 4
|
|
UNION ALL SELECT 5 UNION ALL SELECT 6
|
|
UNION ALL SELECT 7 UNION ALL SELECT 8
|
|
UNION ALL SELECT 9
|
|
) as tens
|
|
CROSS JOIN (
|
|
SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2
|
|
UNION ALL SELECT 3 UNION ALL SELECT 4
|
|
UNION ALL SELECT 5 UNION ALL SELECT 6
|
|
UNION ALL SELECT 7 UNION ALL SELECT 8
|
|
UNION ALL SELECT 9
|
|
) AS hundreds
|
|
) last_thousand_days
|
|
WHERE last_thousand_days.Date >= %s AND last_thousand_days.Date <= %s
|
|
) searchdate,
|
|
{$wpdb->posts} AS wcsubs,
|
|
{$wpdb->postmeta} AS wcsmeta
|
|
WHERE wcsubs.ID = wcsmeta.post_id AND wcsmeta.meta_key = '%s'
|
|
AND DATE( wcsubs.post_date ) <= searchdate.Date
|
|
AND wcsubs.post_type IN ( 'shop_subscription' )
|
|
AND wcsubs.post_status NOT IN( 'auto-draft' )
|
|
AND (
|
|
DATE( CONVERT_TZ( wcsmeta.meta_value , '+00:00', %s ) ) >= searchdate.Date
|
|
OR wcsmeta.meta_value = 0
|
|
OR wcsmeta.meta_value IS NULL
|
|
)
|
|
GROUP BY searchdate.Date
|
|
ORDER BY searchdate.Date ASC",
|
|
$query_end_date,
|
|
date( 'Y-m-d', $this->start_date ),
|
|
$query_end_date,
|
|
wcs_get_date_meta_key( 'end' ),
|
|
$site_timezone
|
|
);
|
|
|
|
$query_hash = md5( $query );
|
|
|
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_subscriber_count_data', (array) $wpdb->get_results( $query ), $args );
|
|
$update_cache = true;
|
|
}
|
|
|
|
$this->report_data->subscriber_counts = $cached_results[ $query_hash ];
|
|
$this->report_data->current_subscriptions_query_hash = $query_hash;
|
|
|
|
/*
|
|
* Subscription cancellations
|
|
*/
|
|
$query = $wpdb->prepare(
|
|
"SELECT COUNT( DISTINCT wcsubs.ID ) as count, CONVERT_TZ( wcsmeta_cancel.meta_value, '+00:00', '{$site_timezone}' ) as cancel_date, GROUP_CONCAT( DISTINCT wcsubs.ID ) as subscription_ids
|
|
FROM {$wpdb->posts} as wcsubs
|
|
JOIN {$wpdb->postmeta} AS wcsmeta_cancel
|
|
ON wcsubs.ID = wcsmeta_cancel.post_id
|
|
AND wcsmeta_cancel.meta_key = %s
|
|
AND wcsubs.post_status NOT IN ( 'trash', 'auto-draft' )
|
|
GROUP BY YEAR( cancel_date ), MONTH( cancel_date ), DAY( cancel_date )
|
|
HAVING cancel_date BETWEEN %s AND %s
|
|
ORDER BY wcsmeta_cancel.meta_value ASC",
|
|
wcs_get_date_meta_key( 'cancelled' ),
|
|
date( 'Y-m-d', $this->start_date ),
|
|
$query_end_date
|
|
);
|
|
|
|
$query_hash = md5( $query );
|
|
|
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_cancel_count_data', (array) $wpdb->get_results( $query ), $args );
|
|
$update_cache = true;
|
|
}
|
|
|
|
$this->report_data->cancel_counts = $cached_results[ $query_hash ];
|
|
|
|
$this->report_data->cancelled_subscriptions_query_hash = $query_hash;
|
|
|
|
/*
|
|
* Subscriptions ended
|
|
*/
|
|
$query = $wpdb->prepare(
|
|
"SELECT COUNT( DISTINCT wcsubs.ID ) as count, CONVERT_TZ( wcsmeta_end.meta_value, '+00:00', '{$site_timezone}' ) as end_date, GROUP_CONCAT( DISTINCT wcsubs.ID ) as subscription_ids
|
|
FROM {$wpdb->posts} as wcsubs
|
|
JOIN {$wpdb->postmeta} AS wcsmeta_end
|
|
ON wcsubs.ID = wcsmeta_end.post_id
|
|
AND wcsmeta_end.meta_key = %s
|
|
AND wcsubs.post_status NOT IN ( 'trash', 'auto-draft' )
|
|
GROUP BY YEAR( end_date ), MONTH( end_date ), DAY( end_date )
|
|
HAVING end_date BETWEEN %s AND %s
|
|
ORDER BY wcsmeta_end.meta_value ASC",
|
|
wcs_get_date_meta_key( 'end' ),
|
|
date( 'Y-m-d', $this->start_date ),
|
|
$query_end_date
|
|
);
|
|
|
|
$query_hash = md5( $query );
|
|
|
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_ended_count_data', (array) $wpdb->get_results( $query ), $args );
|
|
$update_cache = true;
|
|
}
|
|
|
|
$this->report_data->ended_counts = $cached_results[ $query_hash ];
|
|
|
|
$this->report_data->ended_subscriptions_query_hash = $query_hash;
|
|
|
|
// Total up the query data
|
|
$this->report_data->signup_orders_total_amount = array_sum( wp_list_pluck( $this->report_data->signup_data, 'signup_totals' ) );
|
|
$this->report_data->renewal_orders_total_amount = array_sum( wp_list_pluck( $this->report_data->renewal_data, 'renewal_totals' ) );
|
|
$this->report_data->resubscribe_orders_total_amount = array_sum( wp_list_pluck( $this->report_data->resubscribe_data, 'resubscribe_totals' ) );
|
|
$this->report_data->switch_orders_total_amount = array_sum( wp_list_pluck( $this->report_data->switch_data, 'switch_totals' ) );
|
|
$this->report_data->new_subscription_total_count = absint( array_sum( wp_list_pluck( $this->report_data->new_subscriptions_data, 'count' ) ) );
|
|
$this->report_data->signup_orders_total_count = absint( array_sum( wp_list_pluck( $this->report_data->signup_data, 'count' ) ) );
|
|
$this->report_data->renewal_orders_total_count = absint( array_sum( wp_list_pluck( $this->report_data->renewal_data, 'count' ) ) );
|
|
$this->report_data->resubscribe_orders_total_count = absint( array_sum( wp_list_pluck( $this->report_data->resubscribe_data, 'count' ) ) );
|
|
$this->report_data->switch_orders_total_count = absint( array_sum( wp_list_pluck( $this->report_data->switch_data, 'count' ) ) );
|
|
$this->report_data->total_subscriptions_cancelled = absint( array_sum( wp_list_pluck( $this->report_data->cancel_counts, 'count' ) ) );
|
|
$this->report_data->total_subscriptions_ended = absint( array_sum( wp_list_pluck( $this->report_data->ended_counts, 'count' ) ) );
|
|
$this->report_data->total_subscriptions_at_period_end = $this->report_data->subscriber_counts ? absint( end( $this->report_data->subscriber_counts )->count ) : 0;
|
|
$this->report_data->total_subscriptions_at_period_start = isset( $this->report_data->subscriber_counts[0]->count ) ? absint( $this->report_data->subscriber_counts[0]->count ) : 0;
|
|
|
|
if ( $update_cache ) {
|
|
set_transient( strtolower( get_class( $this ) ), $cached_results, WEEK_IN_SECONDS );
|
|
|
|
// Remove this class from the list of classes WC updates on shutdown. Introduced in WC 3.7
|
|
if ( ! wcs_is_woocommerce_pre( '3.7' ) ) {
|
|
unset( WC_Admin_Report::$transients_to_update[ strtolower( get_class( $this ) ) ] );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the legend for the main chart sidebar
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_chart_legend() {
|
|
$legend = array();
|
|
$data = $this->get_report_data();
|
|
$tracks_id = 'report_subscription_events_by_date_';
|
|
|
|
$legend[] = array(
|
|
// translators: %s: formatted total amount.
|
|
'title' => sprintf( __( '%s signup revenue in this period', 'woocommerce-subscriptions' ), '<strong>' . wc_price( $data->signup_orders_total_amount ) . '</strong>' ),
|
|
'placeholder' => __( 'The sum of all subscription parent orders, including other items, fees, tax and shipping.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['signup_total'],
|
|
'highlight_series' => 8,
|
|
);
|
|
|
|
$legend[] = array(
|
|
// translators: %s: formatted total amount.
|
|
'title' => sprintf( __( '%s renewal revenue in this period', 'woocommerce-subscriptions' ), '<strong>' . wc_price( $data->renewal_orders_total_amount ) . '</strong>' ),
|
|
'placeholder' => __( 'The sum of all renewal orders including tax and shipping.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['renewal_total'],
|
|
'highlight_series' => 10,
|
|
);
|
|
|
|
$legend[] = array(
|
|
// translators: %s: formatted total amount.
|
|
'title' => sprintf( __( '%s resubscribe revenue in this period', 'woocommerce-subscriptions' ), '<strong>' . wc_price( $data->resubscribe_orders_total_amount ) . '</strong>' ),
|
|
'placeholder' => __( 'The sum of all resubscribe orders including tax and shipping.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['resubscribe_total'],
|
|
'highlight_series' => 9,
|
|
);
|
|
|
|
$legend[] = array(
|
|
// translators: %s: formatted total amount.
|
|
'title' => sprintf( __( '%s switch revenue in this period', 'woocommerce-subscriptions' ), '<strong>' . wc_price( $data->switch_orders_total_amount ) . '</strong>' ),
|
|
'placeholder' => __( 'The sum of all switch orders including tax and shipping.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['switch_total'],
|
|
'highlight_series' => 11,
|
|
);
|
|
|
|
$legend[] = array(
|
|
'title' => sprintf(
|
|
// translators: 2: link opening tag, 1: subscription count and closing tag.
|
|
__( '%2$s %1$s new subscriptions', 'woocommerce-subscriptions' ),
|
|
'<strong> <span class="woocommerce-subscriptions-count count">' . $this->report_data->new_subscription_total_count . '</span> </strong> </a>',
|
|
'<a href="' .
|
|
esc_url(
|
|
add_query_arg(
|
|
array(
|
|
'post_type' => 'shop_subscription',
|
|
'_subscriptions_list_key' => $this->report_data->new_subscriptions_query_hash,
|
|
'_report' => strtolower( get_class( $this ) ),
|
|
),
|
|
admin_url( 'edit.php' )
|
|
)
|
|
) . '" id="' . $tracks_id . 'new">'
|
|
),
|
|
'placeholder' => __( 'The number of subscriptions created during this period, either by being manually created, imported or a customer placing an order. This includes orders pending payment.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['new_count'],
|
|
'highlight_series' => 1,
|
|
);
|
|
|
|
$legend[] = array(
|
|
'title' => sprintf(
|
|
// translators: 2: link opening tag, 1: subscription count and closing tag.
|
|
__( '%2$s %1$s subscription signups', 'woocommerce-subscriptions' ),
|
|
'<strong> <span class="woocommerce-subscriptions-count count">' . $this->report_data->signup_orders_total_count . '</strong> </a>',
|
|
'<a href="' .
|
|
esc_url(
|
|
add_query_arg(
|
|
array(
|
|
'post_type' => 'shop_subscription',
|
|
'_subscriptions_list_key' => $this->report_data->signup_orders_query_hash,
|
|
'_report' => strtolower( get_class( $this ) ),
|
|
),
|
|
admin_url( 'edit.php' )
|
|
)
|
|
) . '" id="' . $tracks_id . 'signups">'
|
|
),
|
|
'placeholder' => __( 'The number of subscriptions purchased in parent orders created during this period. This represents the new subscriptions created by customers placing an order via checkout.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['signup_count'],
|
|
'highlight_series' => 2,
|
|
);
|
|
|
|
$legend[] = array(
|
|
'title' => sprintf(
|
|
// translators: 2: link opening tag, 1: subscription count and closing tag.
|
|
__( '%2$s %1$s subscription resubscribes', 'woocommerce-subscriptions' ),
|
|
'<strong> <span class="woocommerce-subscriptions-count count">' . $this->report_data->resubscribe_orders_total_count . '</strong> </a>',
|
|
'<a href="' .
|
|
esc_url(
|
|
add_query_arg(
|
|
array(
|
|
'post_type' => 'shop_order',
|
|
'_orders_list_key' => $this->report_data->resubscribes_query_hash,
|
|
'_report' => strtolower( get_class( $this ) ),
|
|
),
|
|
admin_url( 'edit.php' )
|
|
)
|
|
) . '" id="' . $tracks_id . 'resubscribes">'
|
|
),
|
|
'placeholder' => __( 'The number of resubscribe orders processed during this period.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['resubscribe_count'],
|
|
'highlight_series' => 3,
|
|
);
|
|
|
|
$legend[] = array(
|
|
'title' => sprintf(
|
|
// translators: 2: link opening tag, 1: subscription count and closing tag.
|
|
__( '%2$s %1$s subscription renewals', 'woocommerce-subscriptions' ),
|
|
'<strong> <span class="woocommerce-subscriptions-count count">' . $this->report_data->renewal_orders_total_count . '</strong> </a>',
|
|
'<a href="' .
|
|
esc_url(
|
|
add_query_arg(
|
|
array(
|
|
'post_type' => 'shop_order',
|
|
'_orders_list_key' => $this->report_data->renewals_query_hash,
|
|
'_report' => strtolower( get_class( $this ) ),
|
|
),
|
|
admin_url( 'edit.php' )
|
|
)
|
|
) . '" id="' . $tracks_id . 'renewals">'
|
|
),
|
|
'placeholder' => __( 'The number of renewal orders processed during this period.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['renewal_count'],
|
|
'highlight_series' => 4,
|
|
);
|
|
|
|
$legend[] = array(
|
|
'title' => sprintf(
|
|
// translators: 2: link opening tag, 1: subscription count and closing tag.
|
|
__( '%2$s %1$s subscription switches', 'woocommerce-subscriptions' ),
|
|
'<strong> <span class="woocommerce-subscriptions-count count">' . $this->report_data->switch_orders_total_count . '</strong> </a>',
|
|
'<a href="' .
|
|
esc_url(
|
|
add_query_arg(
|
|
array(
|
|
'post_type' => 'shop_order',
|
|
'_orders_list_key' => $this->report_data->switches_query_hash,
|
|
'_report' => strtolower( get_class( $this ) ),
|
|
),
|
|
admin_url( 'edit.php' )
|
|
)
|
|
) . '" id="' . $tracks_id . 'switches">'
|
|
),
|
|
'placeholder' => __( 'The number of subscriptions upgraded, downgraded or cross-graded during this period.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['switch_count'],
|
|
'highlight_series' => 0,
|
|
);
|
|
|
|
$legend[] = array(
|
|
'title' => sprintf(
|
|
// translators: 2: link opening tag, 1: subscription count and closing tag.
|
|
__( '%2$s %1$s subscription cancellations', 'woocommerce-subscriptions' ),
|
|
'<strong> <span class="woocommerce-subscriptions-count count">' . $this->report_data->total_subscriptions_cancelled . '</strong> </a>',
|
|
'<a href="' .
|
|
esc_url(
|
|
add_query_arg(
|
|
array(
|
|
'post_type' => 'shop_subscription',
|
|
'_subscriptions_list_key' => $this->report_data->cancelled_subscriptions_query_hash,
|
|
'_report' => strtolower( get_class( $this ) ),
|
|
),
|
|
admin_url( 'edit.php' )
|
|
)
|
|
) . '" id="' . $tracks_id . 'cancellations">'
|
|
),
|
|
'placeholder' => __( 'The number of subscriptions cancelled by the customer or store manager during this period. The pre-paid term may not yet have ended during this period.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['cancel_count'],
|
|
'highlight_series' => 7,
|
|
);
|
|
|
|
$legend[] = array(
|
|
'title' => sprintf(
|
|
// translators: 2: link opening tag, 1: subscription count and closing tag.
|
|
__( '%2$s %1$s ended subscriptions', 'woocommerce-subscriptions' ),
|
|
'<strong> <span class="woocommerce-subscriptions-count count">' . $this->report_data->total_subscriptions_ended . '</strong> </a>',
|
|
'<a href="' .
|
|
esc_url(
|
|
add_query_arg(
|
|
array(
|
|
'post_type' => 'shop_subscription',
|
|
'_subscriptions_list_key' => $this->report_data->ended_subscriptions_query_hash,
|
|
'_report' => strtolower( get_class( $this ) ),
|
|
),
|
|
admin_url( 'edit.php' )
|
|
)
|
|
) . '" id="' . $tracks_id . 'ended">'
|
|
),
|
|
'placeholder' => __( 'The number of subscriptions which have either expired or reached the end of the prepaid term if it was previously cancelled.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['ended_count'],
|
|
'highlight_series' => 6,
|
|
);
|
|
|
|
// For the subscriptions count we only need to display the subscriptions included on the last day of the report period so pass the last cache key. The array keys are integers so using max() returns the last array key.
|
|
$data_key = $this->report_data->subscriber_counts ? max( array_keys( $this->report_data->subscriber_counts ) ) : false;
|
|
|
|
$legend[] = array(
|
|
'title' => sprintf(
|
|
// translators: 2: link opening tag, 1: subscription count and closing tag.
|
|
__( '%2$s %1$s current subscriptions', 'woocommerce-subscriptions' ),
|
|
'<strong> <span class="woocommerce-subscriptions-count count">' . $this->report_data->total_subscriptions_at_period_end . '</strong> </a>',
|
|
'<a href="' .
|
|
esc_url(
|
|
add_query_arg(
|
|
array(
|
|
'post_type' => 'shop_subscription',
|
|
'_subscriptions_list_key' => $this->report_data->current_subscriptions_query_hash,
|
|
'_report' => strtolower( get_class( $this ) ),
|
|
'_data_key' => $data_key,
|
|
),
|
|
admin_url( 'edit.php' )
|
|
)
|
|
) . '" id="' . $tracks_id . 'current">'
|
|
),
|
|
'placeholder' => __( 'The number of subscriptions during this period with an end date in the future and a status other than pending.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['subscriber_count'],
|
|
'highlight_series' => 5,
|
|
);
|
|
|
|
$subscription_change_count = ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start > 0 ) ? '+' . ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start ) : ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start );
|
|
|
|
if ( 0 === $data->total_subscriptions_at_period_start ) {
|
|
$subscription_change_percent = '∞%'; // infinite percentage increase if the starting subs is 0.
|
|
} elseif ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start >= 0 ) {
|
|
$subscription_change_percent = '+' . number_format( ( ( ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start ) / $data->total_subscriptions_at_period_start ) * 100 ), 2 ) . '%';
|
|
} else {
|
|
$subscription_change_percent = number_format( ( ( ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start ) / $data->total_subscriptions_at_period_start ) * 100 ), 2 ) . '%';
|
|
}
|
|
|
|
if ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start >= 0 ) {
|
|
// translators: %s: subscription net gain (with percentage).
|
|
$legend_title = __( '%s net subscription gain', 'woocommerce-subscriptions' );
|
|
} else {
|
|
// translators: %s: subscription net loss (with percentage).
|
|
$legend_title = __( '%s net subscription loss', 'woocommerce-subscriptions' );
|
|
}
|
|
|
|
$legend[] = array(
|
|
'title' => sprintf( $legend_title, '<strong>' . $subscription_change_count . ' <span style="font-size:65%;">(' . $subscription_change_percent . ')</span></strong>' ),
|
|
'placeholder' => __( 'Change in subscriptions between the start and end of the period.', 'woocommerce-subscriptions' ),
|
|
'color' => $this->chart_colours['subscriber_change'],
|
|
'highlight_series' => 5,
|
|
);
|
|
|
|
return $legend;
|
|
}
|
|
|
|
/**
|
|
* Output the report
|
|
*/
|
|
public function output_report() {
|
|
|
|
$ranges = array(
|
|
'year' => __( 'Year', 'woocommerce-subscriptions' ),
|
|
'last_month' => __( 'Last Month', 'woocommerce-subscriptions' ),
|
|
'month' => __( 'This Month', 'woocommerce-subscriptions' ),
|
|
'7day' => __( 'Last 7 Days', 'woocommerce-subscriptions' ),
|
|
);
|
|
|
|
$this->chart_colours = array(
|
|
'signup_total' => '#439ad9',
|
|
'renewal_total' => '#b1d4ea',
|
|
'resubscribe_total' => '#7ab7e2',
|
|
'switch_total' => '#a7b7f1',
|
|
'new_count' => '#9adbb5',
|
|
'signup_count' => '#5cc488',
|
|
'resubscribe_count' => '#449163',
|
|
'renewal_count' => '#b9e6cc',
|
|
'switch_count' => '#f1c40f',
|
|
'cancel_count' => '#e74c3c',
|
|
'ended_count' => '#f8ccc7',
|
|
'subscriber_count' => '#ecf0f1',
|
|
'subscriber_change' => '#ecf0f1',
|
|
);
|
|
|
|
$current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day';
|
|
|
|
if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) {
|
|
$current_range = '7day';
|
|
}
|
|
|
|
$this->calculate_current_range( $current_range );
|
|
|
|
include( WC()->plugin_path() . '/includes/admin/views/html-report-by-date.php' );
|
|
}
|
|
|
|
/**
|
|
* Output an export link
|
|
*/
|
|
public function get_export_button() {
|
|
$current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day';
|
|
?>
|
|
<a
|
|
href="#"
|
|
download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo esc_attr( date_i18n( 'Y-m-d', current_time( 'timestamp' ) ) ); ?>.csv"
|
|
class="export_csv"
|
|
data-export="chart"
|
|
data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce-subscriptions' ); ?>"
|
|
data-exclude_series="2"
|
|
data-groupby="<?php echo esc_attr( $this->chart_groupby ); ?>"
|
|
>
|
|
<?php esc_attr_e( 'Export CSV', 'woocommerce-subscriptions' ); ?>
|
|
</a>
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the main chart
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_main_chart() {
|
|
global $wp_locale;
|
|
|
|
// Prepare data for report
|
|
$signup_orders_amount = $this->prepare_chart_data( $this->report_data->signup_data, 'post_date', 'signup_totals', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$renewal_orders_amount = $this->prepare_chart_data( $this->report_data->renewal_data, 'post_date', 'renewal_totals', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$resubscribe_orders_amount = $this->prepare_chart_data( $this->report_data->resubscribe_data, 'post_date', 'resubscribe_totals', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$switch_orders_amount = $this->prepare_chart_data( $this->report_data->switch_data, 'post_date', 'switch_totals', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$new_subscriptions_count = $this->prepare_chart_data( $this->report_data->new_subscriptions_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$signup_orders_count = $this->prepare_chart_data( $this->report_data->signup_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$renewal_orders_count = $this->prepare_chart_data( $this->report_data->renewal_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$resubscribe_orders_count = $this->prepare_chart_data( $this->report_data->resubscribe_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$switch_orders_count = $this->prepare_chart_data( $this->report_data->switch_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$subscriber_count = $this->prepare_chart_data_daily_average( $this->report_data->subscriber_counts, 'date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$cancel_count = $this->prepare_chart_data( $this->report_data->cancel_counts, 'cancel_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
$ended_count = $this->prepare_chart_data( $this->report_data->ended_counts, 'end_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
|
|
|
// Encode in json format
|
|
$chart_data = array(
|
|
'signup_orders_amount' => array_map( array( $this, 'round_chart_totals' ), array_values( $signup_orders_amount ) ),
|
|
'renewal_orders_amount' => array_map( array( $this, 'round_chart_totals' ), array_values( $renewal_orders_amount ) ),
|
|
'resubscribe_orders_amount' => array_map( array( $this, 'round_chart_totals' ), array_values( $resubscribe_orders_amount ) ),
|
|
'switch_orders_amount' => array_map( array( $this, 'round_chart_totals' ), array_values( $switch_orders_amount ) ),
|
|
'new_subscriptions_count' => array_values( $new_subscriptions_count ),
|
|
'signup_orders_count' => array_values( $signup_orders_count ),
|
|
'renewal_orders_count' => array_values( $renewal_orders_count ),
|
|
'resubscribe_orders_count' => array_values( $resubscribe_orders_count ),
|
|
'switch_orders_count' => array_values( $switch_orders_count ),
|
|
'subscriber_count' => array_values( $subscriber_count ),
|
|
'cancel_count' => array_values( $cancel_count ),
|
|
'ended_count' => array_values( $ended_count ),
|
|
);
|
|
|
|
$timeformat = ( $this->chart_groupby == 'day' ? '%d %b' : '%b' );
|
|
|
|
?>
|
|
<div class="chart-container">
|
|
<div class="chart-placeholder main"></div>
|
|
</div>
|
|
<script type="text/javascript">
|
|
|
|
var main_chart;
|
|
|
|
jQuery(function(){
|
|
var order_data = JSON.parse( '<?php echo json_encode( $chart_data ); ?>' );
|
|
var drawGraph = function( highlight ) {
|
|
var series = [
|
|
{
|
|
label: "<?php echo esc_js( __( 'Switched subscriptions', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.switch_orders_count,
|
|
color: '<?php echo esc_js( $this->chart_colours['switch_count'] ); ?>',
|
|
bars: {
|
|
fillColor: '<?php echo esc_js( $this->chart_colours['switch_count'] ); ?>',
|
|
order: 0,
|
|
fill: true,
|
|
show: true,
|
|
lineWidth: 0,
|
|
barWidth: <?php echo esc_js( $this->barwidth ); ?> * 0.25,
|
|
align: 'center'
|
|
},
|
|
shadowSize: 0,
|
|
hoverable: false,
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'New Subscriptions', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.new_subscriptions_count,
|
|
color: '<?php echo esc_js( $this->chart_colours['new_count'] ); ?>',
|
|
bars: {
|
|
fillColor: '<?php echo esc_js( $this->chart_colours['new_count'] ); ?>',
|
|
order: 1,
|
|
fill: true,
|
|
show: true,
|
|
lineWidth: 0,
|
|
barWidth: <?php echo esc_js( $this->barwidth ); ?> * 0.25,
|
|
align: 'center'
|
|
},
|
|
shadowSize: 0,
|
|
hoverable: false,
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Subscriptions signups', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.signup_orders_count,
|
|
color: '<?php echo esc_js( $this->chart_colours['signup_count'] ); ?>',
|
|
bars: {
|
|
order: 1,
|
|
fill: 0.5,
|
|
show: true,
|
|
lineWidth: 0,
|
|
barWidth: <?php echo esc_js( $this->barwidth ); ?> * 0.25,
|
|
align: 'center'
|
|
},
|
|
shadowSize: 0,
|
|
hoverable: false,
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Number of resubscribes', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.resubscribe_orders_count,
|
|
color: '<?php echo esc_js( $this->chart_colours['resubscribe_count'] ); ?>',
|
|
bars: {
|
|
order: 1,
|
|
fill: 0.5,
|
|
show: true,
|
|
lineWidth: 0,
|
|
barWidth: <?php echo esc_js( $this->barwidth ); ?> * 0.25,
|
|
align: 'center'
|
|
},
|
|
shadowSize: 0,
|
|
hoverable: false,
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Number of renewals', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.renewal_orders_count,
|
|
color: '<?php echo esc_js( $this->chart_colours['renewal_count'] ); ?>',
|
|
bars: {
|
|
fillColor: '<?php echo esc_js( $this->chart_colours['renewal_count'] ); ?>',
|
|
order: 2,
|
|
fill: true,
|
|
show: true,
|
|
lineWidth: 0,
|
|
barWidth: <?php echo esc_js( $this->barwidth ); ?> * 0.25,
|
|
align: 'center'
|
|
},
|
|
shadowSize: 0,
|
|
hoverable: false,
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Subscriptions', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.subscriber_count,
|
|
color: '<?php echo esc_js( $this->chart_colours['subscriber_count'] ); ?>',
|
|
bars: {
|
|
fillColor: '<?php echo esc_js( $this->chart_colours['subscriber_count'] ); ?>',
|
|
order: 3,
|
|
fill: true,
|
|
show: true,
|
|
lineWidth: 0,
|
|
barWidth: <?php echo esc_js( $this->barwidth ); ?> * 0.25,
|
|
align: 'center'
|
|
},
|
|
shadowSize: 0,
|
|
hoverable: false,
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Subscriptions Ended', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.ended_count,
|
|
color: '<?php echo esc_js( $this->chart_colours['ended_count'] ); ?>',
|
|
bars: {
|
|
fillColor: '<?php echo esc_js( $this->chart_colours['ended_count'] ); ?>',
|
|
order: 3,
|
|
fill: true,
|
|
show: true,
|
|
lineWidth: 0,
|
|
barWidth: <?php echo esc_js( $this->barwidth ); ?> * 0.25,
|
|
align: 'center'
|
|
},
|
|
shadowSize: 0,
|
|
hoverable: false,
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Cancellations', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.cancel_count,
|
|
color: '<?php echo esc_js( $this->chart_colours['cancel_count'] ); ?>',
|
|
bars: {
|
|
order: 3,
|
|
fill: 0.5,
|
|
show: true,
|
|
lineWidth: 0,
|
|
barWidth: <?php echo esc_js( $this->barwidth ); ?> * 0.25,
|
|
align: 'center'
|
|
},
|
|
shadowSize: 0,
|
|
hoverable: false,
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Signup Totals', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.signup_orders_amount,
|
|
yaxis: 2,
|
|
color: '<?php echo esc_js( $this->chart_colours['signup_total'] ); ?>',
|
|
points: {
|
|
show: true,
|
|
radius: 5,
|
|
lineWidth: 5,
|
|
fillColor: '#fff',
|
|
fill: true
|
|
},
|
|
lines: {
|
|
show: true,
|
|
lineWidth: 4,
|
|
fill: false
|
|
},
|
|
shadowSize: 0,
|
|
<?php echo wp_kses_post( $this->get_currency_tooltip() ); ?>
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Resubscribe Totals', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.resubscribe_orders_amount,
|
|
yaxis: 2,
|
|
color: '<?php echo esc_js( $this->chart_colours['resubscribe_total'] ); ?>',
|
|
points: {
|
|
show: true,
|
|
radius: 5,
|
|
lineWidth: 4,
|
|
fillColor: '#fff',
|
|
fill: true
|
|
},
|
|
lines: {
|
|
show: true,
|
|
lineWidth: 5,
|
|
fill: false
|
|
},
|
|
shadowSize: 0,
|
|
<?php echo wp_kses_post( $this->get_currency_tooltip() ); ?>
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Renewal Totals', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.renewal_orders_amount,
|
|
yaxis: 2,
|
|
color: '<?php echo esc_js( $this->chart_colours['renewal_total'] ); ?>',
|
|
points: {
|
|
show: true,
|
|
radius: 5,
|
|
lineWidth: 4,
|
|
fillColor: '#fff',
|
|
fill: true
|
|
},
|
|
lines: {
|
|
show: true,
|
|
lineWidth: 5,
|
|
fill: false
|
|
},
|
|
shadowSize: 0,
|
|
<?php echo wp_kses_post( $this->get_currency_tooltip() ); ?>
|
|
},
|
|
{
|
|
label: "<?php echo esc_js( __( 'Switch Totals', 'woocommerce-subscriptions' ) ) ?>",
|
|
data: order_data.switch_orders_amount,
|
|
yaxis: 2,
|
|
color: '<?php echo esc_js( $this->chart_colours['switch_total'] ); ?>',
|
|
points: {
|
|
show: true,
|
|
radius: 5,
|
|
lineWidth: 4,
|
|
fillColor: '#fff',
|
|
fill: true
|
|
},
|
|
lines: {
|
|
show: true,
|
|
lineWidth: 5,
|
|
fill: false
|
|
},
|
|
shadowSize: 0,
|
|
<?php echo wp_kses_post( $this->get_currency_tooltip() ); ?>
|
|
},
|
|
];
|
|
|
|
if ( highlight !== 'undefined' && series[ highlight ] ) {
|
|
highlight_series = series[ highlight ];
|
|
|
|
highlight_series.color = '#9c5d90';
|
|
|
|
if ( highlight_series.bars ) {
|
|
highlight_series.bars.fillColor = '#9c5d90';
|
|
}
|
|
|
|
if ( highlight_series.lines ) {
|
|
highlight_series.lines.lineWidth = 5;
|
|
}
|
|
}
|
|
|
|
main_chart = jQuery.plot(
|
|
jQuery('.chart-placeholder.main'),
|
|
series,
|
|
{
|
|
legend: {
|
|
show: false
|
|
},
|
|
grid: {
|
|
color: '#aaa',
|
|
borderColor: 'transparent',
|
|
borderWidth: 0,
|
|
hoverable: true
|
|
},
|
|
xaxes: [ {
|
|
color: '#aaa',
|
|
position: "bottom",
|
|
tickColor: 'transparent',
|
|
mode: "time",
|
|
timeformat: "<?php echo esc_js( $timeformat ) ?>",
|
|
monthNames: <?php echo json_encode( array_values( $wp_locale->month_abbrev ) ) ?>,
|
|
tickLength: 1,
|
|
minTickSize: [1, "<?php echo esc_js( $this->chart_groupby ); ?>"],
|
|
font: {
|
|
color: "#aaa"
|
|
}
|
|
} ],
|
|
yaxes: [
|
|
{
|
|
min: 0,
|
|
minTickSize: 1,
|
|
tickDecimals: 0,
|
|
color: '#d4d9dc',
|
|
font: { color: "#aaa" }
|
|
},
|
|
{
|
|
position: "right",
|
|
min: 0,
|
|
tickDecimals: 2,
|
|
tickFormatter: function (tick) {
|
|
// Localise and format axis labels
|
|
return jQuery.wcs_format_money(tick,0);
|
|
},
|
|
alignTicksWithAxis: 1,
|
|
color: 'transparent',
|
|
font: { color: "#aaa" }
|
|
}
|
|
],
|
|
stack: true,
|
|
}
|
|
);
|
|
|
|
jQuery('.chart-placeholder').trigger( 'resize' );
|
|
}
|
|
|
|
drawGraph();
|
|
|
|
jQuery('.highlight_series').on( 'hover',
|
|
function() {
|
|
drawGraph( jQuery(this).data('series') );
|
|
},
|
|
function() {
|
|
drawGraph();
|
|
}
|
|
);
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Round our totals correctly.
|
|
* @param string $amount
|
|
* @return string
|
|
*/
|
|
private function round_chart_totals( $amount ) {
|
|
if ( is_array( $amount ) ) {
|
|
return array( $amount[0], wc_format_decimal( $amount[1], wc_get_price_decimals() ) );
|
|
} else {
|
|
return wc_format_decimal( $amount, wc_get_price_decimals() );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Put data with post_date's into an array of times averaged by day
|
|
*
|
|
* If the data is grouped by day already, we can just call @see $this->prepare_chart_data() otherwise,
|
|
* we need to figure out how many days in each period and average the aggregate over that count.
|
|
*
|
|
* @param array $data array of your data
|
|
* @param string $date_key key for the 'date' field. e.g. 'post_date'
|
|
* @param string $data_key key for the data you are charting
|
|
* @param int $interval
|
|
* @param string $start_date
|
|
* @param string $group_by
|
|
* @return array
|
|
*/
|
|
private function prepare_chart_data_daily_average( $data, $date_key, $data_key, $interval, $start_date, $group_by ) {
|
|
|
|
$prepared_data = array();
|
|
|
|
if ( 'day' == $group_by ) {
|
|
|
|
$prepared_data = $this->prepare_chart_data( $data, $date_key, $data_key, $interval, $start_date, $group_by );
|
|
|
|
} else {
|
|
|
|
// Ensure all days (or months) have values first in this range
|
|
for ( $i = 0; $i <= $interval; $i ++ ) {
|
|
|
|
$time = strtotime( date( 'Ym', strtotime( "+{$i} MONTH", $start_date ) ) . '01' ) . '000';
|
|
|
|
if ( ! isset( $prepared_data[ $time ] ) ) {
|
|
$prepared_data[ $time ] = array(
|
|
esc_js( $time ),
|
|
0,
|
|
'count' => 0,
|
|
);
|
|
}
|
|
}
|
|
|
|
foreach ( $data as $days_data ) {
|
|
|
|
$time = strtotime( date( 'Ym', strtotime( $days_data->$date_key ) ) . '01' ) . '000';
|
|
|
|
if ( ! isset( $prepared_data[ $time ] ) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( $data_key ) {
|
|
$prepared_data[ $time ][1] += $days_data->$data_key;
|
|
} else {
|
|
$prepared_data[ $time ][1] ++;
|
|
}
|
|
|
|
$prepared_data[ $time ]['count']++;
|
|
}
|
|
|
|
foreach ( $prepared_data as $time => $aggregated_data ) {
|
|
if ( 0 === $aggregated_data['count'] ) {
|
|
$prepared_data[ $time ][1] = 0;
|
|
} else {
|
|
$prepared_data[ $time ][1] = round( $prepared_data[ $time ][1] / $aggregated_data['count'] );
|
|
}
|
|
unset( $prepared_data[ $time ]['count'] );
|
|
}
|
|
}
|
|
|
|
return $prepared_data;
|
|
}
|
|
|
|
/**
|
|
* Clears the cached report data.
|
|
*
|
|
* @since 3.0.10
|
|
*/
|
|
public function clear_cache() {
|
|
delete_transient( strtolower( get_class( $this ) ) );
|
|
}
|
|
}
|