302 lines
12 KiB
PHP
302 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* Reports functions.
|
|
*
|
|
* @package EDD
|
|
* @subpackage Admin/Reports
|
|
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
|
* @since 1.0
|
|
* @since 3.0 Full refactor of Reports.
|
|
*/
|
|
|
|
use EDD\Reports;
|
|
|
|
// Exit if accessed directly.
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
/**
|
|
* The callback function which fetches the data for the overview_sales_earnings_chart reports endpoint.
|
|
*
|
|
* @since 3.0
|
|
*/
|
|
function edd_overview_sales_earnings_chart() {
|
|
global $wpdb;
|
|
|
|
$dates = Reports\get_dates_filter( 'objects' );
|
|
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
|
|
$day_by_day = Reports\get_dates_filter_day_by_day();
|
|
$hour_by_hour = Reports\get_dates_filter_hour_by_hour();
|
|
$column = Reports\get_taxes_excluded_filter() ? '(total - tax)' : 'total';
|
|
$currency = Reports\get_filter_value( 'currencies' );
|
|
|
|
if ( empty( $currency ) || 'convert' === $currency ) {
|
|
$column .= ' / rate';
|
|
}
|
|
|
|
$sql_clauses = array(
|
|
'select' => 'DATE_FORMAT(date_created, "%%Y-%%m") AS date',
|
|
'where' => '',
|
|
'groupby' => '',
|
|
);
|
|
|
|
// Default to 'monthly'.
|
|
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'MONTH', 'date_created' );
|
|
$sql_clauses['orderby'] = 'MONTH(date_created)';
|
|
|
|
// Now drill down to the smallest unit.
|
|
if ( $hour_by_hour ) {
|
|
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'date_created' );
|
|
$sql_clauses['orderby'] = 'HOUR(date_created)';
|
|
$sql_clauses['select'] = 'DATE_FORMAT(date_created, "%%Y-%%m-%%d %%H:00:00") AS date';
|
|
} elseif ( $day_by_day ) {
|
|
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'date_created' );
|
|
$sql_clauses['orderby'] = 'DATE(date_created)';
|
|
$sql_clauses['select'] = 'DATE_FORMAT(date_created, "%%Y-%%m-%%d") AS date';
|
|
}
|
|
|
|
if ( ! empty( $currency ) && array_key_exists( strtoupper( $currency ), edd_get_currencies() ) ) {
|
|
$sql_clauses['where'] = $wpdb->prepare( " AND currency = %s ", strtoupper( $currency ) );
|
|
}
|
|
|
|
// Revenue calculations should include gross statuses to negate refunds properly.
|
|
$statuses = edd_get_gross_order_statuses();
|
|
$statuses = apply_filters( 'edd_payment_stats_post_statuses', $statuses );
|
|
$statuses = "'" . implode( "', '", $statuses ) . "'";
|
|
|
|
$earnings_results = $wpdb->get_results(
|
|
$wpdb->prepare(
|
|
"SELECT SUM({$column}) AS earnings, {$sql_clauses['select']}
|
|
FROM {$wpdb->edd_orders} edd_o
|
|
WHERE date_created >= %s AND date_created <= %s
|
|
AND status IN( {$statuses} )
|
|
AND type IN ( 'sale', 'refund' )
|
|
{$sql_clauses['where']}
|
|
GROUP BY {$sql_clauses['groupby']}
|
|
ORDER BY {$sql_clauses['orderby']} ASC",
|
|
$dates['start']->copy()->format( 'mysql' ),
|
|
$dates['end']->copy()->format( 'mysql' )
|
|
)
|
|
);
|
|
|
|
// Sales counts should count by 'net' statuses, which excludes refunds.
|
|
$statuses = edd_get_net_order_statuses();
|
|
$statuses = apply_filters( 'edd_payment_stats_post_statuses', $statuses );
|
|
$statuses = "'" . implode( "', '", $statuses ) . "'";
|
|
|
|
$sales_results = $wpdb->get_results(
|
|
$wpdb->prepare(
|
|
"SELECT COUNT(id) AS sales, {$sql_clauses['select']}
|
|
FROM {$wpdb->edd_orders} edd_o
|
|
WHERE date_created >= %s AND date_created <= %s
|
|
AND status IN( {$statuses} )
|
|
AND type = 'sale'
|
|
{$sql_clauses['where']}
|
|
GROUP BY {$sql_clauses['groupby']}
|
|
ORDER BY {$sql_clauses['orderby']} ASC",
|
|
$dates['start']->copy()->format( 'mysql' ),
|
|
$dates['end']->copy()->format( 'mysql' )
|
|
)
|
|
);
|
|
|
|
$sales = array();
|
|
$earnings = array();
|
|
|
|
/**
|
|
* Initialise all arrays with timestamps and set values to 0.
|
|
*
|
|
* We use the Chart based dates for this loop, so the graph shows in the proper date ranges while the actual DB queries are all UTC based.
|
|
*/
|
|
while ( strtotime( $chart_dates['start']->copy()->format( 'mysql' ) ) <= strtotime( $chart_dates['end']->copy()->format( 'mysql' ) ) ) {
|
|
$timestamp = $chart_dates['start']->copy()->format( 'U' );
|
|
$date_on_chart = $chart_dates['start'];
|
|
|
|
$sales[ $timestamp ][0] = $date_on_chart->format( 'Y-m-d H:i:s' );
|
|
$sales[ $timestamp ][1] = 0;
|
|
|
|
$earnings[ $timestamp ][0] = $date_on_chart->format( 'Y-m-d H:i:s' );
|
|
$earnings[ $timestamp ][1] = 0.00;
|
|
|
|
// Loop through each date there were sales/earnings, which we queried from the database.
|
|
foreach ( $earnings_results as $earnings_result ) {
|
|
$date_of_db_value = EDD()->utils->date( $earnings_result->date );
|
|
|
|
// Add any sales/earnings that happened during this hour.
|
|
if ( $hour_by_hour ) {
|
|
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( $date_of_db_value );
|
|
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
|
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
|
|
$earnings[ $timestamp ][1] += $earnings_result->earnings;
|
|
}
|
|
// Add any sales/earnings that happened during this day.
|
|
} elseif ( $day_by_day ) {
|
|
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
|
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
|
|
$earnings[ $timestamp ][1] += $earnings_result->earnings;
|
|
}
|
|
// Add any sales/earnings that happened during this month.
|
|
} else {
|
|
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
|
if ( $date_of_db_value->format( 'Y-m' ) === $date_on_chart->format( 'Y-m' ) ) {
|
|
$earnings[ $timestamp ][1] += $earnings_result->earnings;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Loop through each date there were sales/earnings, which we queried from the database.
|
|
foreach ( $sales_results as $sales_result ) {
|
|
$date_of_db_value = EDD()->utils->date( $sales_result->date );
|
|
|
|
// Add any sales/earnings that happened during this hour.
|
|
if ( $hour_by_hour ) {
|
|
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( $date_of_db_value );
|
|
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
|
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
|
|
$sales[ $timestamp ][1] += $sales_result->sales;
|
|
}
|
|
// Add any sales/earnings that happened during this day.
|
|
} elseif ( $day_by_day ) {
|
|
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
|
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
|
|
$sales[ $timestamp ][1] += $sales_result->sales;
|
|
}
|
|
// Add any sales/earnings that happened during this month.
|
|
} else {
|
|
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
|
if ( $date_of_db_value->format( 'Y-m' ) === $date_on_chart->format( 'Y-m' ) ) {
|
|
$sales[ $timestamp ][1] += $sales_result->sales;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Move the chart along to the next hour/day/month to get ready for the next loop.
|
|
if ( $hour_by_hour ) {
|
|
$chart_dates['start']->addHour( 1 );
|
|
} elseif ( $day_by_day ) {
|
|
$chart_dates['start']->addDays( 1 );
|
|
} else {
|
|
$chart_dates['start']->addMonth( 1 );
|
|
}
|
|
}
|
|
|
|
return array(
|
|
'sales' => array_values( $sales ),
|
|
'earnings' => array_values( $earnings ),
|
|
);
|
|
|
|
}
|
|
|
|
/**
|
|
* The callback function which fetches the data for the edd_overview_refunds_chart reports endpoint.
|
|
*
|
|
* @since 3.0
|
|
*/
|
|
function edd_overview_refunds_chart() {
|
|
global $wpdb;
|
|
|
|
$dates = Reports\get_dates_filter( 'objects' );
|
|
$chart_dates = Reports\parse_dates_for_range( null, 'now', false );
|
|
$day_by_day = Reports\get_dates_filter_day_by_day();
|
|
$hour_by_hour = Reports\get_dates_filter_hour_by_hour();
|
|
$column = Reports\get_taxes_excluded_filter() ? 'total - tax' : 'total';
|
|
$currency = Reports\get_filter_value( 'currencies' );
|
|
|
|
$sql_clauses = array(
|
|
'select' => 'date_created AS date',
|
|
'where' => '',
|
|
);
|
|
|
|
// Default to 'monthly'.
|
|
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'MONTH', 'date_created' );
|
|
$sql_clauses['orderby'] = 'MONTH(date_created)';
|
|
|
|
// Now drill down to the smallest unit.
|
|
if ( $hour_by_hour ) {
|
|
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'date_created' );
|
|
$sql_clauses['orderby'] = 'HOUR(date_created)';
|
|
} elseif ( $day_by_day ) {
|
|
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'date_created' );
|
|
$sql_clauses['orderby'] = 'DATE(date_created)';
|
|
}
|
|
|
|
if ( empty( $currency ) || 'convert' === $currency ) {
|
|
$column = sprintf( '(%s) / rate', $column );
|
|
} else {
|
|
$sql_clauses['where'] = $wpdb->prepare( " AND currency = %s ", strtoupper( $currency ) );
|
|
}
|
|
|
|
$results = $wpdb->get_results(
|
|
$wpdb->prepare(
|
|
"SELECT COUNT(id) AS number, SUM({$column}) AS amount, {$sql_clauses['select']}
|
|
FROM {$wpdb->edd_orders} edd_o
|
|
WHERE status IN (%s, %s) AND date_created >= %s AND date_created <= %s AND type = 'refund'
|
|
{$sql_clauses['where']}
|
|
GROUP BY {$sql_clauses['groupby']}
|
|
ORDER BY {$sql_clauses['orderby']} ASC",
|
|
esc_sql( 'complete' ),
|
|
esc_sql( 'partially_refunded' ),
|
|
$dates['start']->copy()->format( 'mysql' ),
|
|
$dates['end']->copy()->format( 'mysql' )
|
|
)
|
|
);
|
|
|
|
$number = array();
|
|
$amount = array();
|
|
|
|
// Initialise all arrays with timestamps and set values to 0.
|
|
while ( strtotime( $chart_dates['start']->copy()->format( 'mysql' ) ) <= strtotime( $chart_dates['end']->copy()->format( 'mysql' ) ) ) {
|
|
$timestamp = $chart_dates['start']->copy()->format( 'U' );
|
|
$date_on_chart = $chart_dates['start'];
|
|
|
|
$number[ $timestamp ][0] = $date_on_chart->format( 'Y-m-d H:i:s' );
|
|
$number[ $timestamp ][1] = 0;
|
|
|
|
$amount[ $timestamp ][0] = $date_on_chart->format( 'Y-m-d H:i:s' );
|
|
$amount[ $timestamp ][1] = 0.00;
|
|
|
|
// Loop through each date there were refunds, which we queried from the database.
|
|
foreach ( $results as $result ) {
|
|
$date_of_db_value = EDD()->utils->date( $result->date );
|
|
|
|
// Add any refunds that happened during this hour.
|
|
if ( $hour_by_hour ) {
|
|
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( $date_of_db_value );
|
|
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
|
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
|
|
$number[ $timestamp ][1] += $result->number;
|
|
$amount[ $timestamp ][1] += abs( $result->amount );
|
|
}
|
|
// Add any refunds that happened during this day.
|
|
} elseif ( $day_by_day ) {
|
|
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
|
if ( $date_of_db_value->format( 'Y-m-d' ) === $date_on_chart->format( 'Y-m-d' ) ) {
|
|
$number[ $timestamp ][1] += $result->number;
|
|
$amount[ $timestamp ][1] += abs( $result->amount );
|
|
}
|
|
// Add any refunds that happened during this month.
|
|
} else {
|
|
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
|
if ( $date_of_db_value->format( 'Y-m' ) === $date_on_chart->format( 'Y-m' ) ) {
|
|
$number[ $timestamp ][1] += $result->number;
|
|
$amount[ $timestamp ][1] += abs( $result->amount );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Move the chart along to the next hour/day/month to get ready for the next loop.
|
|
if ( $hour_by_hour ) {
|
|
$chart_dates['start']->addHour( 1 );
|
|
} elseif ( $day_by_day ) {
|
|
$chart_dates['start']->addDays( 1 );
|
|
} else {
|
|
$chart_dates['start']->addMonth( 1 );
|
|
}
|
|
}
|
|
|
|
return array(
|
|
'number' => array_values( $number ),
|
|
'amount' => array_values( $amount ),
|
|
);
|
|
|
|
}
|