laipower/wp-content/plugins/easy-digital-downloads/includes/admin/reporting/reports-callbacks.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 ),
);
}