Add date sorting configuration for Analytics (#36492)
* Include fields date_paid and date_completed to wp_wc_order_stats TODO: add script to create new columns in the database * Add update script and new columns in get_schema * Add new configuration in Analytics > Settings to configure type of date used in Revenue report * Change date_column_name to date_paid TODO: This will be configurable in future * Add date type config field * Use customizable date field in DataStore * Change label * Fix linter errors * Remove blank line * Put default column name back to date_created * Make date_paid and date_completed nullable to help with unit tests * Remove new table creation in update function and use query method instead of get_var * Extend stats constructor * Improve date type configuration description * Set date column name default to date_created to test if build passes * Fix phpcs issue on constructor * Remove cache bypass added by mistake * Improve changelog * Fill date_paid and date_completed for refunds to avoid problems whem they are being used to sort Fix unit tests when date_paid or date_completed are being used as sort date * Change default to date_created * Bump update script to 7.5.0 * Add prefix and postmeta variables for script
This commit is contained in:
parent
3b58651bd6
commit
9d7e503519
|
@ -118,4 +118,31 @@ export const config = applyFilters( SETTINGS_FILTER, {
|
||||||
),
|
),
|
||||||
defaultValue: DEFAULT_DATE_RANGE,
|
defaultValue: DEFAULT_DATE_RANGE,
|
||||||
},
|
},
|
||||||
|
woocommerce_date_type: {
|
||||||
|
name: 'woocommerce_date_type',
|
||||||
|
label: __( 'Date type:', 'woocommerce' ),
|
||||||
|
inputType: 'select',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: __( 'Date created', 'woocommerce' ),
|
||||||
|
value: 'date_created',
|
||||||
|
key: 'date_created',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Date paid', 'woocommerce' ),
|
||||||
|
value: 'date_paid',
|
||||||
|
key: 'date_paid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Date completed', 'woocommerce' ),
|
||||||
|
value: 'date_completed',
|
||||||
|
key: 'date_completed',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
helpText: __(
|
||||||
|
'Database date field considered for Revenue and Orders reports',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
defaultValue: 'date_created',
|
||||||
|
},
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { Button, CheckboxControl } from '@wordpress/components';
|
import { Button, CheckboxControl, SelectControl } from '@wordpress/components';
|
||||||
import { Component } from '@wordpress/element';
|
import { Component } from '@wordpress/element';
|
||||||
import { compose } from '@wordpress/compose';
|
import { compose } from '@wordpress/compose';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
@ -75,6 +75,22 @@ class Setting extends Component {
|
||||||
{ ...this.props }
|
{ ...this.props }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
case 'select':
|
||||||
|
return (
|
||||||
|
<SelectControl
|
||||||
|
options={ options }
|
||||||
|
value={ value }
|
||||||
|
onChange={ ( newValue ) =>
|
||||||
|
handleChange( {
|
||||||
|
target: {
|
||||||
|
name,
|
||||||
|
type: 'select',
|
||||||
|
value: newValue,
|
||||||
|
},
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
case 'text':
|
case 'text':
|
||||||
default:
|
default:
|
||||||
const id = uniqueId( name );
|
const id = uniqueId( name );
|
||||||
|
@ -188,6 +204,7 @@ Setting.propTypes = {
|
||||||
'checkboxGroup',
|
'checkboxGroup',
|
||||||
'text',
|
'text',
|
||||||
'component',
|
'component',
|
||||||
|
'select',
|
||||||
] ),
|
] ),
|
||||||
/**
|
/**
|
||||||
* Label used for describing the setting.
|
* Label used for describing the setting.
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Add date_paid and date_completed date sorting options for Revenue and Order reports
|
|
@ -350,6 +350,27 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
|
||||||
return $this->get_prop( 'date_modified', $context );
|
return $this->get_prop( 'date_modified', $context );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get date_modified.
|
||||||
|
*
|
||||||
|
* @param string $context View or edit context.
|
||||||
|
* @return WC_DateTime|NULL object if the date is set or null if there is no date.
|
||||||
|
*/
|
||||||
|
public function get_date_paid( $context = 'view' ) {
|
||||||
|
return $this->get_prop( 'date_paid', $context );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get date_modified.
|
||||||
|
*
|
||||||
|
* @param string $context View or edit context.
|
||||||
|
* @return WC_DateTime|NULL object if the date is set or null if there is no date.
|
||||||
|
*/
|
||||||
|
public function get_date_completed( $context = 'view' ) {
|
||||||
|
return $this->get_prop( 'date_completed', $context );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the order statuses without wc- internal prefix.
|
* Return the order statuses without wc- internal prefix.
|
||||||
*
|
*
|
||||||
|
|
|
@ -225,6 +225,9 @@ class WC_Install {
|
||||||
'wc_update_722_adjust_new_zealand_states',
|
'wc_update_722_adjust_new_zealand_states',
|
||||||
'wc_update_722_adjust_ukraine_states',
|
'wc_update_722_adjust_ukraine_states',
|
||||||
),
|
),
|
||||||
|
'7.5.0' => array(
|
||||||
|
'wc_update_750_add_columns_to_order_stats_table',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1312,6 +1315,8 @@ CREATE TABLE {$wpdb->prefix}wc_order_stats (
|
||||||
parent_id bigint(20) unsigned DEFAULT 0 NOT NULL,
|
parent_id bigint(20) unsigned DEFAULT 0 NOT NULL,
|
||||||
date_created datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
date_created datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
||||||
date_created_gmt datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
date_created_gmt datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
||||||
|
date_paid datetime DEFAULT '0000-00-00 00:00:00',
|
||||||
|
date_completed datetime DEFAULT '0000-00-00 00:00:00',
|
||||||
num_items_sold int(11) DEFAULT 0 NOT NULL,
|
num_items_sold int(11) DEFAULT 0 NOT NULL,
|
||||||
total_sales double DEFAULT 0 NOT NULL,
|
total_sales double DEFAULT 0 NOT NULL,
|
||||||
tax_total double DEFAULT 0 NOT NULL,
|
tax_total double DEFAULT 0 NOT NULL,
|
||||||
|
|
|
@ -2558,3 +2558,28 @@ function wc_update_722_adjust_new_zealand_states() {
|
||||||
function wc_update_722_adjust_ukraine_states() {
|
function wc_update_722_adjust_ukraine_states() {
|
||||||
return wc_update_721_adjust_ukraine_states();
|
return wc_update_721_adjust_ukraine_states();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new columns date_paid and date_completed to wp_wc_order_stats table in order to provide the option
|
||||||
|
* of using the dates in the reports
|
||||||
|
*/
|
||||||
|
function wc_update_750_add_columns_to_order_stats_table() {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$wpdb->query(
|
||||||
|
"UPDATE {$wpdb->prefix}wc_order_stats AS order_stats
|
||||||
|
INNER JOIN {$wpdb->postmeta} AS postmeta
|
||||||
|
ON postmeta.post_id = order_stats.order_id
|
||||||
|
and postmeta.meta_key = '_date_paid'
|
||||||
|
SET order_stats.date_paid = IFNULL(FROM_UNIXTIME(postmeta.meta_value), '0000-00-00 00:00:00');"
|
||||||
|
);
|
||||||
|
|
||||||
|
$wpdb->query(
|
||||||
|
"UPDATE {$wpdb->prefix}wc_order_stats AS order_stats
|
||||||
|
INNER JOIN {$wpdb->postmeta} AS postmeta
|
||||||
|
ON postmeta.post_id = order_stats.order_id
|
||||||
|
and postmeta.meta_key = '_date_completed'
|
||||||
|
SET order_stats.date_completed = IFNULL(FROM_UNIXTIME(postmeta.meta_value), '0000-00-00 00:00:00');"
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -69,6 +69,14 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||||
*/
|
*/
|
||||||
protected $context = 'orders_stats';
|
protected $context = 'orders_stats';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically sets the date column name based on configuration
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
$this->date_column_name = get_option( 'woocommerce_date_type', 'date_created' );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign report columns once full table name has been assigned.
|
* Assign report columns once full table name has been assigned.
|
||||||
*/
|
*/
|
||||||
|
@ -517,6 +525,8 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||||
'order_id' => $order->get_id(),
|
'order_id' => $order->get_id(),
|
||||||
'parent_id' => $order->get_parent_id(),
|
'parent_id' => $order->get_parent_id(),
|
||||||
'date_created' => $order->get_date_created()->date( 'Y-m-d H:i:s' ),
|
'date_created' => $order->get_date_created()->date( 'Y-m-d H:i:s' ),
|
||||||
|
'date_paid' => $order->get_date_paid() ? $order->get_date_paid()->date( 'Y-m-d H:i:s' ) : null,
|
||||||
|
'date_completed' => $order->get_date_completed() ? $order->get_date_completed()->date( 'Y-m-d H:i:s' ) : null,
|
||||||
'date_created_gmt' => gmdate( 'Y-m-d H:i:s', $order->get_date_created()->getTimestamp() ),
|
'date_created_gmt' => gmdate( 'Y-m-d H:i:s', $order->get_date_created()->getTimestamp() ),
|
||||||
'num_items_sold' => self::get_num_items_sold( $order ),
|
'num_items_sold' => self::get_num_items_sold( $order ),
|
||||||
'total_sales' => $order->get_total(),
|
'total_sales' => $order->get_total(),
|
||||||
|
@ -535,6 +545,8 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||||
'%d',
|
'%d',
|
||||||
'%s',
|
'%s',
|
||||||
'%s',
|
'%s',
|
||||||
|
'%s',
|
||||||
|
'%s',
|
||||||
'%d',
|
'%d',
|
||||||
'%f',
|
'%f',
|
||||||
'%f',
|
'%f',
|
||||||
|
@ -551,6 +563,12 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||||
$data['parent_id'] = $parent_order->get_id();
|
$data['parent_id'] = $parent_order->get_id();
|
||||||
$data['status'] = self::normalize_order_status( $parent_order->get_status() );
|
$data['status'] = self::normalize_order_status( $parent_order->get_status() );
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Set date_completed and date_paid the same as date_created to avoid problems
|
||||||
|
* when they are being used to sort the data, as refunds don't have them filled
|
||||||
|
*/
|
||||||
|
$data['date_completed'] = $data['date_created'];
|
||||||
|
$data['date_paid'] = $data['date_created'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update or add the information to the DB.
|
// Update or add the information to the DB.
|
||||||
|
|
|
@ -288,6 +288,19 @@ class Settings {
|
||||||
'default' => 'period=month&compare=previous_year',
|
'default' => 'period=month&compare=previous_year',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
);
|
);
|
||||||
|
$settings[] = array(
|
||||||
|
'id' => 'woocommerce_date_type',
|
||||||
|
'option_key' => 'woocommerce_date_type',
|
||||||
|
'label' => __( 'Date Type', 'woocommerce' ),
|
||||||
|
'description' => __( 'Database date field considered for Revenue and Orders reports', 'woocommerce' ),
|
||||||
|
'default' => 'date_created',
|
||||||
|
'type' => 'select',
|
||||||
|
'options' => array(
|
||||||
|
'date_created' => 'date_created',
|
||||||
|
'date_paid' => 'date_paid',
|
||||||
|
'date_completed' => 'date_completed',
|
||||||
|
),
|
||||||
|
);
|
||||||
return $settings;
|
return $settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,10 +195,14 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$time = time();
|
||||||
|
|
||||||
foreach ( $order_types as $order_type ) {
|
foreach ( $order_types as $order_type ) {
|
||||||
$order = WC_Helper_Order::create_order( 1, $product );
|
$order = WC_Helper_Order::create_order( 1, $product );
|
||||||
$order->set_status( $order_type['status'] );
|
$order->set_status( $order_type['status'] );
|
||||||
$order->set_total( $order_type['total'] );
|
$order->set_total( $order_type['total'] );
|
||||||
|
$order->set_date_created( $time );
|
||||||
|
$order->set_date_paid( $time );
|
||||||
$order->set_shipping_total( 0 );
|
$order->set_shipping_total( 0 );
|
||||||
$order->set_cart_tax( 0 );
|
$order->set_cart_tax( 0 );
|
||||||
$order->save();
|
$order->save();
|
||||||
|
@ -352,10 +356,14 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$time = time();
|
||||||
|
|
||||||
foreach ( $order_types as $order_type ) {
|
foreach ( $order_types as $order_type ) {
|
||||||
$order = WC_Helper_Order::create_order( 1, $product );
|
$order = WC_Helper_Order::create_order( 1, $product );
|
||||||
$order->set_status( $order_type['status'] );
|
$order->set_status( $order_type['status'] );
|
||||||
$order->set_total( $order_type['total'] );
|
$order->set_total( $order_type['total'] );
|
||||||
|
$order->set_date_created( $time );
|
||||||
|
$order->set_date_paid( $time );
|
||||||
$order->set_shipping_total( 0 );
|
$order->set_shipping_total( 0 );
|
||||||
$order->set_cart_tax( 0 );
|
$order->set_cart_tax( 0 );
|
||||||
$order->save();
|
$order->save();
|
||||||
|
@ -3946,6 +3954,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
// Order 3: 4 x product 1, done one hour earlier.
|
// Order 3: 4 x product 1, done one hour earlier.
|
||||||
$order_3 = WC_Helper_Order::create_order( $customer_1->get_id(), $product_1 );
|
$order_3 = WC_Helper_Order::create_order( $customer_1->get_id(), $product_1 );
|
||||||
$order_3->set_date_created( $order_3_time );
|
$order_3->set_date_created( $order_3_time );
|
||||||
|
$order_3->set_date_paid( $order_3_time );
|
||||||
$order_3->set_status( $order_status );
|
$order_3->set_status( $order_status );
|
||||||
$order_3->calculate_totals();
|
$order_3->calculate_totals();
|
||||||
$order_3->save();
|
$order_3->save();
|
||||||
|
@ -4526,6 +4535,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
// Order with 1 product.
|
// Order with 1 product.
|
||||||
$order = WC_Helper_Order::create_order( $customer->get_id(), $product );
|
$order = WC_Helper_Order::create_order( $customer->get_id(), $product );
|
||||||
$order->set_date_created( $order_time );
|
$order->set_date_created( $order_time );
|
||||||
|
$order->set_date_paid( $order_time );
|
||||||
$order->set_status( $order_status );
|
$order->set_status( $order_status );
|
||||||
|
|
||||||
$order->calculate_totals();
|
$order->calculate_totals();
|
||||||
|
@ -5309,6 +5319,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
// Order with 1 product.
|
// Order with 1 product.
|
||||||
$order = WC_Helper_Order::create_order( $customer->get_id(), $product );
|
$order = WC_Helper_Order::create_order( $customer->get_id(), $product );
|
||||||
$order->set_date_created( $order_time );
|
$order->set_date_created( $order_time );
|
||||||
|
$order->set_date_paid( $order_time );
|
||||||
$order->set_status( $order_status );
|
$order->set_status( $order_status );
|
||||||
|
|
||||||
$order->calculate_totals();
|
$order->calculate_totals();
|
||||||
|
@ -6078,6 +6089,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
$order_0 = WC_Helper_Order::create_order( 0, $product );
|
$order_0 = WC_Helper_Order::create_order( 0, $product );
|
||||||
$order_0->set_date_created( $order_0_time );
|
$order_0->set_date_created( $order_0_time );
|
||||||
|
$order_0->set_date_paid( $order_0_time );
|
||||||
$order_0->set_status( 'processing' );
|
$order_0->set_status( 'processing' );
|
||||||
$order_0->set_total( 100 );
|
$order_0->set_total( 100 );
|
||||||
$order_0->save();
|
$order_0->save();
|
||||||
|
@ -6097,6 +6109,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
// Place an order 'one hour later', 2 orders, but still just one customer.
|
// Place an order 'one hour later', 2 orders, but still just one customer.
|
||||||
$order_1 = WC_Helper_Order::create_order( 0, $product );
|
$order_1 = WC_Helper_Order::create_order( 0, $product );
|
||||||
$order_1->set_date_created( $order_1_time );
|
$order_1->set_date_created( $order_1_time );
|
||||||
|
$order_1->set_date_paid( $order_1_time );
|
||||||
$order_1->set_status( 'processing' );
|
$order_1->set_status( 'processing' );
|
||||||
$order_1->set_total( 100 );
|
$order_1->set_total( 100 );
|
||||||
$order_1->save();
|
$order_1->save();
|
||||||
|
@ -6135,6 +6148,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
$order_2 = WC_Helper_Order::create_order( 0, $product );
|
$order_2 = WC_Helper_Order::create_order( 0, $product );
|
||||||
$order_2->set_date_created( $order_1_time );
|
$order_2->set_date_created( $order_1_time );
|
||||||
|
$order_2->set_date_paid( $order_1_time );
|
||||||
$order_2->set_status( 'processing' );
|
$order_2->set_status( 'processing' );
|
||||||
$order_2->set_total( 100 );
|
$order_2->set_total( 100 );
|
||||||
$order_2->save();
|
$order_2->save();
|
||||||
|
@ -6185,6 +6199,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
$order_0 = WC_Helper_Order::create_order( $customer_1->get_id(), $product );
|
$order_0 = WC_Helper_Order::create_order( $customer_1->get_id(), $product );
|
||||||
$order_0->set_date_created( $order_0_time );
|
$order_0->set_date_created( $order_0_time );
|
||||||
|
$order_0->set_date_paid( $order_0_time );
|
||||||
$order_0->set_status( 'processing' );
|
$order_0->set_status( 'processing' );
|
||||||
$order_0->set_total( 100 );
|
$order_0->set_total( 100 );
|
||||||
$order_0->save();
|
$order_0->save();
|
||||||
|
@ -6204,6 +6219,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
// Place an order 'one hour later', 2 orders, but still just one customer.
|
// Place an order 'one hour later', 2 orders, but still just one customer.
|
||||||
$order_1 = WC_Helper_Order::create_order( $customer_1->get_id(), $product );
|
$order_1 = WC_Helper_Order::create_order( $customer_1->get_id(), $product );
|
||||||
$order_1->set_date_created( $order_1_time );
|
$order_1->set_date_created( $order_1_time );
|
||||||
|
$order_1->set_date_paid( $order_1_time );
|
||||||
$order_1->set_status( 'processing' );
|
$order_1->set_status( 'processing' );
|
||||||
$order_1->set_total( 100 );
|
$order_1->set_total( 100 );
|
||||||
$order_1->save();
|
$order_1->save();
|
||||||
|
@ -6242,6 +6258,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
$order_2 = WC_Helper_Order::create_order( $customer_1->get_id(), $product );
|
$order_2 = WC_Helper_Order::create_order( $customer_1->get_id(), $product );
|
||||||
$order_2->set_date_created( $order_1_time );
|
$order_2->set_date_created( $order_1_time );
|
||||||
|
$order_2->set_date_paid( $order_1_time );
|
||||||
$order_2->set_status( 'processing' );
|
$order_2->set_status( 'processing' );
|
||||||
$order_2->set_total( 100 );
|
$order_2->set_total( 100 );
|
||||||
$order_2->save();
|
$order_2->save();
|
||||||
|
|
Loading…
Reference in New Issue