Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display "Origin" column in Orders table in Orders Analytics #46424

Merged
merged 34 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a9d90f3
Display channel column in Orders Analytics UI.
ecgan Apr 10, 2024
1a48761
Set $data to false to not use cache.
ecgan Apr 11, 2024
70a490b
Get channel info from order meta and put into extended_info.
ecgan Apr 11, 2024
d54ba36
Set channel in order item level.
ecgan Apr 11, 2024
ffdef81
Replace channel with get_origin_label in extended_info.
ecgan Apr 12, 2024
2e26c5f
Remove unnneeded channel in orders_data.
ecgan Apr 12, 2024
494e684
Display origin instead of channel in table.
ecgan Apr 12, 2024
46c52cd
Fix lint errors.
ecgan Apr 12, 2024
aaca142
Query order meta table based on HPOS.
ecgan Apr 12, 2024
286f3bd
Remove code for development purpose.
ecgan Apr 12, 2024
0ee9a7a
Add changelog.
ecgan Apr 12, 2024
494b36c
Fix code comment.
ecgan Apr 12, 2024
f5a1557
Merge branch 'trunk' into add/orders-analytics-channel-column
ecgan Apr 15, 2024
ddda7cd
Guard against null values.
ecgan Apr 15, 2024
ff5f4c7
Set default origin label to "Unknown".
ecgan Apr 15, 2024
2ab21c6
Support server side report download.
ecgan Apr 15, 2024
930c23b
Fix failed test.
ecgan Apr 15, 2024
b98ddd1
Fix lint error.
ecgan Apr 16, 2024
d0911a0
Simplify code.
ecgan Apr 16, 2024
9851886
Change "channel" to "attribution" object in controller.
ecgan Apr 17, 2024
f3099a7
Change `origin` string to `attribution` array in Orders DataStore.
ecgan Apr 17, 2024
e1589b7
Change origin string to attribution object.
ecgan Apr 17, 2024
e496387
Fix indexing after changing from origin string to attribution object.
ecgan Apr 17, 2024
d03e47f
Change from origin string to attribution object in table.js.
ecgan Apr 17, 2024
9c82c3f
Simplify code.
ecgan Apr 17, 2024
a84b2fe
Fix lint errors.
ecgan Apr 17, 2024
73361f4
Fix failed test.
ecgan Apr 17, 2024
58ad4b2
Fix lint error.
ecgan Apr 17, 2024
713b653
Fix retrieving origin in CSV export.
ecgan Apr 17, 2024
cc3d0e0
Use $wpdb->postmeta; cosmetic change.
ecgan Apr 18, 2024
ad770ca
Cosmetic change.
ecgan Apr 18, 2024
c787b0c
Sanitize order IDs by using absint.
ecgan Apr 18, 2024
63eeaa6
Merge branch 'trunk' into add/orders-analytics-channel-column
ecgan Apr 18, 2024
79eda32
Merge branch 'trunk' into add/orders-analytics-channel-column
ecgan Apr 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions plugins/woocommerce-admin/client/analytics/report/orders/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ class OrdersReportTable extends Component {
isSortable: true,
isNumeric: true,
},
{
label: __( 'Origin', 'woocommerce' ),
screenReaderLabel: __( 'Origin', 'woocommerce' ),
key: 'origin',
required: false,
isSortable: false,
},
];
}

Expand Down Expand Up @@ -241,6 +248,10 @@ class OrdersReportTable extends Component {
display: renderCurrency( netTotal, currency ),
value: netTotal,
},
{
display: extendedInfo.attribution.origin,
value: extendedInfo.attribution.origin,
},
];
} );
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Add origin column in Orders Analytics report.
14 changes: 11 additions & 3 deletions plugins/woocommerce/src/Admin/API/Reports/Orders/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,24 +211,30 @@ public function get_item_schema() {
'readonly' => true,
),
'extended_info' => array(
'products' => array(
'products' => array(
'type' => 'array',
'readonly' => true,
'context' => array( 'view', 'edit' ),
'description' => __( 'List of order product IDs, names, quantities.', 'woocommerce' ),
),
'coupons' => array(
'coupons' => array(
'type' => 'array',
'readonly' => true,
'context' => array( 'view', 'edit' ),
'description' => __( 'List of order coupons.', 'woocommerce' ),
),
'customer' => array(
'customer' => array(
'type' => 'object',
'readonly' => true,
'context' => array( 'view', 'edit' ),
'description' => __( 'Order customer information.', 'woocommerce' ),
),
'attribution' => array(
'type' => 'object',
'readonly' => true,
'context' => array( 'view', 'edit' ),
'description' => __( 'Order attribution information.', 'woocommerce' ),
),
),
),
);
Expand Down Expand Up @@ -526,6 +532,7 @@ public function get_export_columns() {
'num_items_sold' => __( 'Items sold', 'woocommerce' ),
'coupons' => __( 'Coupon(s)', 'woocommerce' ),
'net_total' => __( 'N. Revenue', 'woocommerce' ),
'origin' => __( 'Origin', 'woocommerce' ),
);

/**
Expand Down Expand Up @@ -558,6 +565,7 @@ public function prepare_item_for_export( $item ) {
'num_items_sold' => $item['num_items_sold'],
'coupons' => isset( $item['extended_info']['coupons'] ) ? $this->get_coupons( $item['extended_info']['coupons'] ) : null,
'net_total' => $item['net_total'],
'origin' => $item['extended_info']['attribution']['origin'],
);

/**
Expand Down
82 changes: 70 additions & 12 deletions plugins/woocommerce/src/Admin/API/Reports/Orders/DataStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

defined( 'ABSPATH' ) || exit;

use Automattic\WooCommerce\Internal\Traits\OrderAttributionMeta;
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
use Automattic\WooCommerce\Utilities\OrderUtil;
use Automattic\WooCommerce\Admin\API\Reports\DataStore as ReportsDataStore;
use Automattic\WooCommerce\Admin\API\Reports\DataStoreInterface;
use Automattic\WooCommerce\Admin\API\Reports\SqlQuery;
Expand All @@ -18,6 +21,7 @@
* API\Reports\Orders\DataStore.
*/
class DataStore extends ReportsDataStore implements DataStoreInterface {
use OrderAttributionMeta;

/**
* Dynamically sets the date column name based on configuration
Expand Down Expand Up @@ -338,13 +342,14 @@ protected function normalize_order_by( $order_by ) {
* @param array $query_args Query parameters.
*/
protected function include_extended_info( &$orders_data, $query_args ) {
$mapped_orders = $this->map_array_by_key( $orders_data, 'order_id' );
$related_orders = $this->get_orders_with_parent_id( $mapped_orders );
$order_ids = array_merge( array_keys( $mapped_orders ), array_keys( $related_orders ) );
$products = $this->get_products_by_order_ids( $order_ids );
$coupons = $this->get_coupons_by_order_ids( array_keys( $mapped_orders ) );
$customers = $this->get_customers_by_orders( $orders_data );
$mapped_customers = $this->map_array_by_key( $customers, 'customer_id' );
$mapped_orders = $this->map_array_by_key( $orders_data, 'order_id' );
$related_orders = $this->get_orders_with_parent_id( $mapped_orders );
$order_ids = array_merge( array_keys( $mapped_orders ), array_keys( $related_orders ) );
$products = $this->get_products_by_order_ids( $order_ids );
$coupons = $this->get_coupons_by_order_ids( array_keys( $mapped_orders ) );
$order_attributions = $this->get_order_attributions_by_order_ids( array_keys( $mapped_orders ) );
$customers = $this->get_customers_by_orders( $orders_data );
$mapped_customers = $this->map_array_by_key( $customers, 'customer_id' );

$mapped_data = array();
foreach ( $products as $product ) {
Expand Down Expand Up @@ -394,15 +399,22 @@ protected function include_extended_info( &$orders_data, $query_args ) {
}

foreach ( $orders_data as $key => $order_data ) {
$defaults = array(
'products' => array(),
'coupons' => array(),
'customer' => array(),
$defaults = array(
'products' => array(),
'coupons' => array(),
'customer' => array(),
'attribution' => array(),
);
$orders_data[ $key ]['extended_info'] = isset( $mapped_data[ $order_data['order_id'] ] ) ? array_merge( $defaults, $mapped_data[ $order_data['order_id'] ] ) : $defaults;
$order_id = $order_data['order_id'];

$orders_data[ $key ]['extended_info'] = isset( $mapped_data[ $order_id ] ) ? array_merge( $defaults, $mapped_data[ $order_id ] ) : $defaults;
if ( $order_data['customer_id'] && isset( $mapped_customers[ $order_data['customer_id'] ] ) ) {
$orders_data[ $key ]['extended_info']['customer'] = $mapped_customers[ $order_data['customer_id'] ];
}

$source_type = $order_attributions[ $order_id ]['_wc_order_attribution_source_type'] ?? '';
$utm_source = $order_attributions[ $order_id ]['_wc_order_attribution_utm_source'] ?? '';
$orders_data[ $key ]['extended_info']['attribution']['origin'] = $this->get_origin_label( $source_type, $utm_source );
}
}

Expand Down Expand Up @@ -534,6 +546,52 @@ protected function get_coupons_by_order_ids( $order_ids ) {
return $coupons;
}

/**
* Get order attributions data from order IDs.
*
* @param array $order_ids Array of order IDs.
* @return array
*/
protected function get_order_attributions_by_order_ids( $order_ids ) {
global $wpdb;
$order_meta_table = OrdersTableDataStore::get_meta_table_name();
$included_order_ids = implode( ',', array_map( 'absint', $order_ids ) );

if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
/* phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared */
$order_attributions_meta = $wpdb->get_results(
"SELECT order_id, meta_key, meta_value
FROM $order_meta_table
WHERE order_id IN ({$included_order_ids})
AND meta_key IN ( '_wc_order_attribution_source_type', '_wc_order_attribution_utm_source' )
",
ARRAY_A
);
/* phpcs:enable */
} else {
/* phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared */
$order_attributions_meta = $wpdb->get_results(
"SELECT post_id as order_id, meta_key, meta_value
FROM $wpdb->postmeta
WHERE post_id IN ({$included_order_ids})
AND meta_key IN ( '_wc_order_attribution_source_type', '_wc_order_attribution_utm_source' )
",
ARRAY_A
);
/* phpcs:enable */
}

$order_attributions = array();
foreach ( $order_attributions_meta as $meta ) {
if ( ! isset( $order_attributions[ $meta['order_id'] ] ) ) {
$order_attributions[ $meta['order_id'] ] = array();
}
$order_attributions[ $meta['order_id'] ][ $meta['meta_key'] ] = $meta['meta_value'];
}

return $order_attributions;
}

/**
* Get all statuses that have been synced.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function test_extended_info() {
'date_created_gmt' => $data->data[0]['date_created_gmt'], // Not under test.
'date' => $data->data[0]['date'], // Not under test.
'extended_info' => array(
'products' => array(
'products' => array(
array(
'id' => $variation->get_id(),
'name' => $variation->get_name(),
Expand All @@ -108,8 +108,11 @@ public function test_extended_info() {
'quantity' => 1,
),
),
'coupons' => array(),
'customer' => $data->data[0]['extended_info']['customer'], // Not under test.
'coupons' => array(),
'customer' => $data->data[0]['extended_info']['customer'], // Not under test.
'attribution' => array(
'origin' => 'Unknown',
),
),
),
),
Expand Down