REST API: isolate extened info in /reports/products
This commit is contained in:
parent
093b6d9ec0
commit
bf0e025b05
|
@ -91,7 +91,7 @@ export default class ProductsReportTable extends Component {
|
||||||
const {
|
const {
|
||||||
product_id,
|
product_id,
|
||||||
sku = '', // @TODO
|
sku = '', // @TODO
|
||||||
name,
|
extended_info,
|
||||||
items_sold,
|
items_sold,
|
||||||
gross_revenue,
|
gross_revenue,
|
||||||
orders_count,
|
orders_count,
|
||||||
|
@ -100,6 +100,7 @@ export default class ProductsReportTable extends Component {
|
||||||
stock_status = 'outofstock', // @TODO
|
stock_status = 'outofstock', // @TODO
|
||||||
stock_quantity = '0', // @TODO
|
stock_quantity = '0', // @TODO
|
||||||
} = row;
|
} = row;
|
||||||
|
const { name } = extended_info;
|
||||||
const ordersLink = getNewPath( persistedQuery, 'orders', {
|
const ordersLink = getNewPath( persistedQuery, 'orders', {
|
||||||
filter: 'advanced',
|
filter: 'advanced',
|
||||||
product_includes: product_id,
|
product_includes: product_id,
|
||||||
|
@ -209,7 +210,7 @@ export default class ProductsReportTable extends Component {
|
||||||
tableQuery={ {
|
tableQuery={ {
|
||||||
orderby: query.orderby || 'items_sold',
|
orderby: query.orderby || 'items_sold',
|
||||||
order: query.order || 'desc',
|
order: query.order || 'desc',
|
||||||
extended_product_info: true,
|
extended_info: true,
|
||||||
} }
|
} }
|
||||||
title={ __( 'Products', 'wc-admin' ) }
|
title={ __( 'Products', 'wc-admin' ) }
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -127,7 +127,7 @@ export default compose(
|
||||||
const endpoint = NAMESPACE + 'reports/products';
|
const endpoint = NAMESPACE + 'reports/products';
|
||||||
// @TODO We will need to add the date parameters from the Date Picker
|
// @TODO We will need to add the date parameters from the Date Picker
|
||||||
// { after: '2018-04-22', before: '2018-05-06' }
|
// { after: '2018-04-22', before: '2018-05-06' }
|
||||||
const query = { orderby: 'items_sold', per_page: 5, extended_product_info: 1 };
|
const query = { orderby: 'items_sold', per_page: 5, extended_info: 1 };
|
||||||
|
|
||||||
const stats = getReportStats( endpoint, query );
|
const stats = getReportStats( endpoint, query );
|
||||||
const isRequesting = isReportStatsRequesting( endpoint, query );
|
const isRequesting = isReportStatsRequesting( endpoint, query );
|
||||||
|
|
|
@ -68,7 +68,7 @@ describe( 'TopSellingProducts', () => {
|
||||||
const topSellingProducts = topSellingProductsWrapper.root.findByType( TopSellingProducts );
|
const topSellingProducts = topSellingProductsWrapper.root.findByType( TopSellingProducts );
|
||||||
|
|
||||||
const endpoint = '/wc/v3/reports/products';
|
const endpoint = '/wc/v3/reports/products';
|
||||||
const query = { orderby: 'items_sold', per_page: 5, extended_product_info: 1 };
|
const query = { orderby: 'items_sold', per_page: 5, extended_info: 1 };
|
||||||
|
|
||||||
expect( getReportStatsMock.mock.calls[ 0 ][ 1 ] ).toBe( endpoint );
|
expect( getReportStatsMock.mock.calls[ 0 ][ 1 ] ).toBe( endpoint );
|
||||||
expect( getReportStatsMock.mock.calls[ 0 ][ 2 ] ).toEqual( query );
|
expect( getReportStatsMock.mock.calls[ 0 ][ 2 ] ).toEqual( query );
|
||||||
|
|
|
@ -243,7 +243,7 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll
|
||||||
'type' => 'integer',
|
'type' => 'integer',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
$params['extended_product_info'] = array(
|
$params['extended_info'] = array(
|
||||||
'description' => __( 'Add additional piece of info about each product to the report.', 'wc-admin' ),
|
'description' => __( 'Add additional piece of info about each product to the report.', 'wc-admin' ),
|
||||||
'type' => 'boolean',
|
'type' => 'boolean',
|
||||||
'default' => false,
|
'default' => false,
|
||||||
|
|
|
@ -142,18 +142,24 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
* Enriches the product data with attributes specified by the extended_attributes.
|
* Enriches the product data with attributes specified by the extended_attributes.
|
||||||
*
|
*
|
||||||
* @param array $products_data Product data.
|
* @param array $products_data Product data.
|
||||||
|
* @param array $query_args Query parameters.
|
||||||
*/
|
*/
|
||||||
protected function include_extended_product_info( &$products_data ) {
|
protected function include_extended_info( &$products_data, $query_args ) {
|
||||||
foreach ( $products_data as $key => $product_data ) {
|
foreach ( $products_data as $key => $product_data ) {
|
||||||
$product = wc_get_product( $product_data['product_id'] );
|
$extended_info = new ArrayObject();
|
||||||
$extended_attributes = apply_filters( 'woocommerce_rest_reports_products_extended_attributes', $this->extended_attributes, $product_data );
|
if ( $query_args['extended_info'] ) {
|
||||||
foreach ( $extended_attributes as $extended_attribute ) {
|
$product = wc_get_product( $product_data['product_id'] );
|
||||||
$function = 'get_' . $extended_attribute;
|
$extended_attributes = apply_filters( 'woocommerce_rest_reports_products_extended_attributes', $this->extended_attributes, $product_data );
|
||||||
if ( is_callable( array( $product, $function ) ) ) {
|
foreach ( $extended_attributes as $extended_attribute ) {
|
||||||
$value = $product->{$function}();
|
$function = 'get_' . $extended_attribute;
|
||||||
$products_data[ $key ][ $extended_attribute ] = $value;
|
if ( is_callable( array( $product, $function ) ) ) {
|
||||||
|
$value = $product->{$function}();
|
||||||
|
$extended_info[ $extended_attribute ] = $value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
$extended_info = $this->cast_numbers( $extended_info );
|
||||||
}
|
}
|
||||||
|
$products_data[ $key ]['extended_info'] = $extended_info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,18 +178,18 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
|
|
||||||
// These defaults are only partially applied when used via REST API, as that has its own defaults.
|
// These defaults are only partially applied when used via REST API, as that has its own defaults.
|
||||||
$defaults = array(
|
$defaults = array(
|
||||||
'per_page' => get_option( 'posts_per_page' ),
|
'per_page' => get_option( 'posts_per_page' ),
|
||||||
'page' => 1,
|
'page' => 1,
|
||||||
'order' => 'DESC',
|
'order' => 'DESC',
|
||||||
'orderby' => 'date',
|
'orderby' => 'date',
|
||||||
'before' => date( WC_Admin_Reports_Interval::$iso_datetime_format, $now ),
|
'before' => date( WC_Admin_Reports_Interval::$iso_datetime_format, $now ),
|
||||||
'after' => date( WC_Admin_Reports_Interval::$iso_datetime_format, $week_back ),
|
'after' => date( WC_Admin_Reports_Interval::$iso_datetime_format, $week_back ),
|
||||||
'fields' => '*',
|
'fields' => '*',
|
||||||
'categories' => array(),
|
'categories' => array(),
|
||||||
'products' => array(),
|
'products' => array(),
|
||||||
'extended_product_info' => false,
|
'extended_info' => false,
|
||||||
// This is not a parameter for products reports per se, but we want to only take into account selected order types.
|
// This is not a parameter for products reports per se, but we want to only take into account selected order types.
|
||||||
'order_status' => parent::get_report_order_statuses(),
|
'order_status' => parent::get_report_order_statuses(),
|
||||||
|
|
||||||
);
|
);
|
||||||
$query_args = wp_parse_args( $query_args, $defaults );
|
$query_args = wp_parse_args( $query_args, $defaults );
|
||||||
|
@ -192,7 +198,7 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
$data = wp_cache_get( $cache_key, $this->cache_group );
|
$data = wp_cache_get( $cache_key, $this->cache_group );
|
||||||
|
|
||||||
if ( false === $data ) {
|
if ( false === $data ) {
|
||||||
$data = (object) array(
|
$data = (object) array(
|
||||||
'data' => array(),
|
'data' => array(),
|
||||||
'total' => 0,
|
'total' => 0,
|
||||||
'pages' => 0,
|
'pages' => 0,
|
||||||
|
@ -244,9 +250,8 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $query_args['extended_product_info'] ) {
|
$this->include_extended_info( $product_data, $query_args );
|
||||||
$this->include_extended_product_info( $product_data );
|
|
||||||
}
|
|
||||||
$product_data = array_map( array( $this, 'cast_numbers' ), $product_data );
|
$product_data = array_map( array( $this, 'cast_numbers' ), $product_data );
|
||||||
$data = (object) array(
|
$data = (object) array(
|
||||||
'data' => $product_data,
|
'data' => $product_data,
|
||||||
|
|
|
@ -52,6 +52,7 @@ class WC_Tests_Reports_Products extends WC_Unit_Test_Case {
|
||||||
'items_sold' => 4,
|
'items_sold' => 4,
|
||||||
'gross_revenue' => 100.0, // $25 * 4.
|
'gross_revenue' => 100.0, // $25 * 4.
|
||||||
'orders_count' => 1,
|
'orders_count' => 1,
|
||||||
|
'extended_info' => new ArrayObject(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -76,7 +77,7 @@ class WC_Tests_Reports_Products extends WC_Unit_Test_Case {
|
||||||
$product_2->set_regular_price( 20 );
|
$product_2->set_regular_price( 20 );
|
||||||
$product_2->save();
|
$product_2->save();
|
||||||
|
|
||||||
$date_created = time();
|
$date_created = time();
|
||||||
$date_created_2 = $date_created + 5;
|
$date_created_2 = $date_created + 5;
|
||||||
|
|
||||||
$order = WC_Helper_Order::create_order( 1, $product );
|
$order = WC_Helper_Order::create_order( 1, $product );
|
||||||
|
@ -121,12 +122,14 @@ class WC_Tests_Reports_Products extends WC_Unit_Test_Case {
|
||||||
'items_sold' => 4,
|
'items_sold' => 4,
|
||||||
'gross_revenue' => 80.0, // $20 * 4.
|
'gross_revenue' => 80.0, // $20 * 4.
|
||||||
'orders_count' => 1,
|
'orders_count' => 1,
|
||||||
|
'extended_info' => new ArrayObject(),
|
||||||
),
|
),
|
||||||
1 => array(
|
1 => array(
|
||||||
'product_id' => $product->get_id(),
|
'product_id' => $product->get_id(),
|
||||||
'items_sold' => 4,
|
'items_sold' => 4,
|
||||||
'gross_revenue' => 100.0, // $25 * 4.
|
'gross_revenue' => 100.0, // $25 * 4.
|
||||||
'orders_count' => 1,
|
'orders_count' => 1,
|
||||||
|
'extended_info' => new ArrayObject(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -151,12 +154,14 @@ class WC_Tests_Reports_Products extends WC_Unit_Test_Case {
|
||||||
'items_sold' => 4,
|
'items_sold' => 4,
|
||||||
'gross_revenue' => 100.0, // $25 * 4.
|
'gross_revenue' => 100.0, // $25 * 4.
|
||||||
'orders_count' => 1,
|
'orders_count' => 1,
|
||||||
|
'extended_info' => new ArrayObject(),
|
||||||
),
|
),
|
||||||
1 => array(
|
1 => array(
|
||||||
'product_id' => $product_2->get_id(),
|
'product_id' => $product_2->get_id(),
|
||||||
'items_sold' => 4,
|
'items_sold' => 4,
|
||||||
'gross_revenue' => 80.0, // $20 * 4.
|
'gross_revenue' => 80.0, // $20 * 4.
|
||||||
'orders_count' => 1,
|
'orders_count' => 1,
|
||||||
|
'extended_info' => new ArrayObject(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -167,4 +172,56 @@ class WC_Tests_Reports_Products extends WC_Unit_Test_Case {
|
||||||
$this->assertEquals( $expected_data, $query->get_data() );
|
$this->assertEquals( $expected_data, $query->get_data() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the extended info.
|
||||||
|
*
|
||||||
|
* @since 3.5.0
|
||||||
|
*/
|
||||||
|
public function test_extended_info() {
|
||||||
|
WC_Helper_Reports::reset_stats_dbs();
|
||||||
|
// Populate all of the data.
|
||||||
|
$product = new WC_Product_Simple();
|
||||||
|
$product->set_name( 'Test Product' );
|
||||||
|
$product->set_regular_price( 25 );
|
||||||
|
$product->save();
|
||||||
|
$order = WC_Helper_Order::create_order( 1, $product );
|
||||||
|
$order->set_status( 'completed' );
|
||||||
|
$order->set_shipping_total( 10 );
|
||||||
|
$order->set_discount_total( 20 );
|
||||||
|
$order->set_discount_tax( 0 );
|
||||||
|
$order->set_cart_tax( 5 );
|
||||||
|
$order->set_shipping_tax( 2 );
|
||||||
|
$order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax.
|
||||||
|
$order->save();
|
||||||
|
$data_store = new WC_Admin_Reports_Products_Data_Store();
|
||||||
|
$start_time = date( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
|
||||||
|
$end_time = date( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() + HOUR_IN_SECONDS );
|
||||||
|
$args = array(
|
||||||
|
'after' => $start_time,
|
||||||
|
'before' => $end_time,
|
||||||
|
'extended_info' => 1,
|
||||||
|
);
|
||||||
|
// Test retrieving the stats through the data store.
|
||||||
|
$data = $data_store->get_data( $args );
|
||||||
|
$expected_data = (object) array(
|
||||||
|
'total' => 1,
|
||||||
|
'pages' => 1,
|
||||||
|
'page_no' => 1,
|
||||||
|
'data' => array(
|
||||||
|
0 => array(
|
||||||
|
'product_id' => $product->get_id(),
|
||||||
|
'items_sold' => 4,
|
||||||
|
'gross_revenue' => 100.0, // $25 * 4.
|
||||||
|
'orders_count' => 1,
|
||||||
|
'extended_info' => array(
|
||||||
|
'name' => $product->get_name(),
|
||||||
|
'image' => $product->get_image(),
|
||||||
|
'permalink' => $product->get_permalink(),
|
||||||
|
'price' => (float) $product->get_price(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$this->assertEquals( $expected_data, $data );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue