Merge branch 'master' into fix/749
# Conflicts: # includes/data-stores/class-wc-admin-reports-products-data-store.php
This commit is contained in:
commit
1c8459244a
|
@ -61,7 +61,7 @@ class ReportTable extends Component {
|
|||
isLoading={ isRequesting }
|
||||
onQueryChange={ onQueryChange }
|
||||
rows={ rows }
|
||||
rowsPerPage={ query.per_page }
|
||||
rowsPerPage={ parseInt( query.per_page ) }
|
||||
summary={ summary }
|
||||
totalRows={ items.totalCount || 0 }
|
||||
{ ...tableProps }
|
||||
|
|
|
@ -91,7 +91,7 @@ export default class ProductsReportTable extends Component {
|
|||
const {
|
||||
product_id,
|
||||
sku = '', // @TODO
|
||||
name,
|
||||
extended_info,
|
||||
items_sold,
|
||||
gross_revenue,
|
||||
orders_count,
|
||||
|
@ -100,6 +100,7 @@ export default class ProductsReportTable extends Component {
|
|||
stock_status = 'outofstock', // @TODO
|
||||
stock_quantity = '0', // @TODO
|
||||
} = row;
|
||||
const { name } = extended_info;
|
||||
const ordersLink = getNewPath( persistedQuery, 'orders', {
|
||||
filter: 'advanced',
|
||||
product_includes: product_id,
|
||||
|
@ -209,7 +210,7 @@ export default class ProductsReportTable extends Component {
|
|||
tableQuery={ {
|
||||
orderby: query.orderby || 'items_sold',
|
||||
order: query.order || 'desc',
|
||||
extended_product_info: true,
|
||||
extended_info: true,
|
||||
} }
|
||||
title={ __( 'Products', 'wc-admin' ) }
|
||||
/>
|
||||
|
|
|
@ -6,8 +6,7 @@ import { __ } from '@wordpress/i18n';
|
|||
import { Component } from '@wordpress/element';
|
||||
import { format as formatDate } from '@wordpress/date';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { withSelect } from '@wordpress/data';
|
||||
import { get, map } from 'lodash';
|
||||
import { get } from 'lodash';
|
||||
|
||||
/**
|
||||
* WooCommerce dependencies
|
||||
|
@ -18,18 +17,25 @@ import {
|
|||
getDateFormatsForInterval,
|
||||
getIntervalForQuery,
|
||||
} from '@woocommerce/date';
|
||||
import { Link, TableCard } from '@woocommerce/components';
|
||||
import { Link } from '@woocommerce/components';
|
||||
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
|
||||
import { onQueryChange } from '@woocommerce/navigation';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import ReportError from 'analytics/components/report-error';
|
||||
import { QUERY_DEFAULTS } from 'store/constants';
|
||||
import { numberFormat } from 'lib/number';
|
||||
import ReportTable from 'analytics/components/report-table';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
class RevenueReportTable extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.getHeadersContent = this.getHeadersContent.bind( this );
|
||||
this.getRowsContent = this.getRowsContent.bind( this );
|
||||
}
|
||||
|
||||
getHeadersContent() {
|
||||
return [
|
||||
{
|
||||
|
@ -97,7 +103,7 @@ class RevenueReportTable extends Component {
|
|||
const currentInterval = getIntervalForQuery( query );
|
||||
const formats = getDateFormatsForInterval( currentInterval );
|
||||
|
||||
return map( data, row => {
|
||||
return data.map( row => {
|
||||
const {
|
||||
coupons,
|
||||
gross_revenue,
|
||||
|
@ -156,37 +162,16 @@ class RevenueReportTable extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { isTableDataError, isTableDataRequesting, query, tableData } = this.props;
|
||||
|
||||
if ( isTableDataError ) {
|
||||
return <ReportError isError />;
|
||||
}
|
||||
|
||||
const tableQuery = {
|
||||
...query,
|
||||
orderby: query.orderby || 'date',
|
||||
order: query.order || 'asc',
|
||||
};
|
||||
|
||||
const headers = this.getHeadersContent();
|
||||
const rows = this.getRowsContent( get( tableData, [ 'data', 'intervals' ], [] ) );
|
||||
const rowsPerPage =
|
||||
( tableQuery && tableQuery.per_page && parseInt( tableQuery.per_page ) ) ||
|
||||
QUERY_DEFAULTS.pageSize;
|
||||
const totalRows = get( tableData, [ 'totalResults' ], Object.keys( rows ).length );
|
||||
const { query, tableData } = this.props;
|
||||
|
||||
return (
|
||||
<TableCard
|
||||
<ReportTable
|
||||
endpoint="revenue"
|
||||
getHeadersContent={ this.getHeadersContent }
|
||||
getRowsContent={ this.getRowsContent }
|
||||
query={ query }
|
||||
tableData={ tableData }
|
||||
title={ __( 'Revenue', 'wc-admin' ) }
|
||||
rows={ rows }
|
||||
totalRows={ totalRows }
|
||||
rowsPerPage={ rowsPerPage }
|
||||
headers={ headers }
|
||||
isLoading={ isTableDataRequesting }
|
||||
onQueryChange={ onQueryChange }
|
||||
query={ tableQuery }
|
||||
summary={ null }
|
||||
downloadable
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -208,15 +193,20 @@ export default compose(
|
|||
after: appendTimestamp( datesFromQuery.primary.after, 'start' ),
|
||||
before: appendTimestamp( datesFromQuery.primary.before, 'end' ),
|
||||
};
|
||||
const tableData = getReportStats( 'revenue', tableQuery );
|
||||
const isTableDataError = isReportStatsError( 'revenue', tableQuery );
|
||||
const isTableDataRequesting = isReportStatsRequesting( 'revenue', tableQuery );
|
||||
const revenueData = getReportStats( 'revenue', tableQuery );
|
||||
const isError = isReportStatsError( 'revenue', tableQuery );
|
||||
const isRequesting = isReportStatsRequesting( 'revenue', tableQuery );
|
||||
|
||||
return {
|
||||
isTableDataError,
|
||||
isTableDataRequesting,
|
||||
tableQuery,
|
||||
tableData,
|
||||
tableData: {
|
||||
items: {
|
||||
data: get( revenueData, [ 'data', 'intervals' ] ),
|
||||
totalCount: get( revenueData, [ 'totalResults' ] ),
|
||||
},
|
||||
isError,
|
||||
isRequesting,
|
||||
query: tableQuery,
|
||||
},
|
||||
};
|
||||
} )
|
||||
)( RevenueReportTable );
|
||||
|
|
|
@ -127,7 +127,7 @@ export default compose(
|
|||
const endpoint = NAMESPACE + 'reports/products';
|
||||
// @TODO We will need to add the date parameters from the Date Picker
|
||||
// { 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 isRequesting = isReportStatsRequesting( endpoint, query );
|
||||
|
|
|
@ -68,7 +68,7 @@ describe( 'TopSellingProducts', () => {
|
|||
const topSellingProducts = topSellingProductsWrapper.root.findByType( TopSellingProducts );
|
||||
|
||||
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 ][ 2 ] ).toEqual( query );
|
||||
|
|
|
@ -5,33 +5,57 @@
|
|||
import { __, _n, sprintf } from '@wordpress/i18n';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { Fragment } from '@wordpress/element';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import PropTypes from 'prop-types';
|
||||
import { noop } from 'lodash';
|
||||
import interpolateComponents from 'interpolate-components';
|
||||
|
||||
/**
|
||||
* WooCommerce dependencies
|
||||
*/
|
||||
import {
|
||||
EllipsisMenu,
|
||||
Gravatar,
|
||||
EmptyContent,
|
||||
Flag,
|
||||
Link,
|
||||
MenuTitle,
|
||||
MenuItem,
|
||||
OrderStatus,
|
||||
Section,
|
||||
} from '@woocommerce/components';
|
||||
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
|
||||
import { getAdminLink } from '@woocommerce/navigation';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { ActivityCard } from '../activity-card';
|
||||
import { ActivityCard, ActivityCardPlaceholder } from '../activity-card';
|
||||
import ActivityHeader from '../activity-header';
|
||||
import ActivityOutboundLink from '../activity-outbound-link';
|
||||
import { getOrderRefundTotal } from 'lib/order-values';
|
||||
import { QUERY_DEFAULTS } from 'store/constants';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
function OrdersPanel( { orders } ) {
|
||||
const { data = [], isLoading } = orders;
|
||||
function OrdersPanel( { orders, isRequesting, isError } ) {
|
||||
if ( isError ) {
|
||||
const title = __( 'There was an error getting your orders. Please try again.', 'wc-admin' );
|
||||
const actionLabel = __( 'Reload', 'wc-admin' );
|
||||
const actionCallback = () => {
|
||||
// TODO Add tracking for how often an error is displayed, and the reload action is clicked.
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EmptyContent
|
||||
title={ title }
|
||||
actionLabel={ actionLabel }
|
||||
actionURL={ null }
|
||||
actionCallback={ actionCallback }
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
const menu = (
|
||||
<EllipsisMenu label="Demo Menu">
|
||||
|
@ -40,12 +64,31 @@ function OrdersPanel( { orders } ) {
|
|||
</EllipsisMenu>
|
||||
);
|
||||
|
||||
const gravatarWithFlag = ( order, address ) => {
|
||||
const orderCardTitle = ( order, address ) => {
|
||||
const name = `${ address.first_name } ${ address.last_name }`;
|
||||
|
||||
return (
|
||||
<div className="woocommerce-layout__activity-panel-avatar-flag-overlay">
|
||||
<Flag order={ order } />
|
||||
<Gravatar user={ address.email } />
|
||||
</div>
|
||||
<Fragment>
|
||||
{ interpolateComponents( {
|
||||
mixedString: sprintf(
|
||||
__(
|
||||
/* eslint-disable-next-line max-len */
|
||||
'Order {{orderLink}}#%(orderNumber)s{{/orderLink}} placed by {{customerLink}}%(customerName)s{{/customerLink}} {{destinationFlag/}}',
|
||||
'wc-admin'
|
||||
),
|
||||
{
|
||||
orderNumber: order.number,
|
||||
customerName: name,
|
||||
}
|
||||
),
|
||||
components: {
|
||||
orderLink: <Link href={ 'post.php?action=edit&post=' + order.id } type="wp-admin" />,
|
||||
// @TODO: Hook up customer name link
|
||||
customerLink: <Link href={ '#' } type="wp-admin" />,
|
||||
destinationFlag: <Flag order={ order } round={ false } height={ 9 } width={ 12 } />,
|
||||
},
|
||||
} ) }
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -53,14 +96,18 @@ function OrdersPanel( { orders } ) {
|
|||
<Fragment>
|
||||
<ActivityHeader title={ __( 'Orders', 'wc-admin' ) } menu={ menu } />
|
||||
<Section>
|
||||
{ isLoading ? (
|
||||
<p>Loading</p>
|
||||
{ isRequesting ? (
|
||||
<ActivityCardPlaceholder
|
||||
className="woocommerce-order-activity-card"
|
||||
hasAction
|
||||
hasDate
|
||||
lines={ 2 }
|
||||
/>
|
||||
) : (
|
||||
<Fragment>
|
||||
{ data.map( ( order, i ) => {
|
||||
{ orders.map( ( order, i ) => {
|
||||
// We want the billing address, but shipping can be used as a fallback.
|
||||
const address = { ...order.shipping, ...order.billing };
|
||||
const name = `${ address.first_name } ${ address.last_name }`;
|
||||
const productsCount = order.line_items.reduce(
|
||||
( total, line ) => total + line.quantity,
|
||||
0
|
||||
|
@ -74,8 +121,7 @@ function OrdersPanel( { orders } ) {
|
|||
<ActivityCard
|
||||
key={ i }
|
||||
className="woocommerce-order-activity-card"
|
||||
title={ sprintf( __( '%s placed order #%d', 'wc-admin' ), name, order.id ) }
|
||||
icon={ gravatarWithFlag( order, address ) }
|
||||
title={ orderCardTitle( order, address ) }
|
||||
date={ order.date_created }
|
||||
subtitle={
|
||||
<div>
|
||||
|
@ -96,8 +142,11 @@ function OrdersPanel( { orders } ) {
|
|||
</div>
|
||||
}
|
||||
actions={
|
||||
<Button isDefault onClick={ noop }>
|
||||
Begin fulfillment
|
||||
<Button
|
||||
isDefault
|
||||
href={ getAdminLink( 'post.php?action=edit&post=' + order.id ) }
|
||||
>
|
||||
{ __( 'Begin fulfillment' ) }
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
|
@ -116,14 +165,30 @@ function OrdersPanel( { orders } ) {
|
|||
}
|
||||
|
||||
OrdersPanel.propTypes = {
|
||||
orders: PropTypes.object.isRequired,
|
||||
orders: PropTypes.array.isRequired,
|
||||
isError: PropTypes.bool,
|
||||
isRequesting: PropTypes.bool,
|
||||
};
|
||||
|
||||
OrdersPanel.defaultProps = {
|
||||
orders: {
|
||||
data: [],
|
||||
isLoading: false,
|
||||
},
|
||||
orders: [],
|
||||
isError: false,
|
||||
isRequesting: false,
|
||||
};
|
||||
|
||||
export default OrdersPanel;
|
||||
export default compose(
|
||||
withSelect( select => {
|
||||
const { getOrders, isGetOrdersError, isGetOrdersRequesting } = select( 'wc-api' );
|
||||
const ordersQuery = {
|
||||
page: 1,
|
||||
per_page: QUERY_DEFAULTS.pageSize,
|
||||
status: 'processing',
|
||||
};
|
||||
|
||||
const orders = getOrders( ordersQuery );
|
||||
const isError = isGetOrdersError( ordersQuery );
|
||||
const isRequesting = isGetOrdersRequesting( ordersQuery );
|
||||
|
||||
return { orders, isError, isRequesting };
|
||||
} )
|
||||
)( OrdersPanel );
|
||||
|
|
|
@ -239,9 +239,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
.woocommerce-order-activity-card {
|
||||
.woocommerce-activity-card__title {
|
||||
font-weight: normal;
|
||||
// Needs the double-class for specificity
|
||||
.woocommerce-activity-card.woocommerce-order-activity-card {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
'header'
|
||||
'body'
|
||||
'actions';
|
||||
|
||||
.woocommerce-activity-card__icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.woocommerce-flag {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.woocommerce-activity-card__subtitle {
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
/** @format */
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { isNil } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
|
@ -26,7 +32,16 @@ const getOrdersTotalCount = ( getResource, requireResource ) => (
|
|||
const isGetOrdersRequesting = getResource => ( query = {} ) => {
|
||||
const resourceName = getResourceName( 'order-query', query );
|
||||
const { lastRequested, lastReceived } = getResource( resourceName );
|
||||
return lastRequested && lastRequested > lastReceived;
|
||||
|
||||
if ( isNil( lastRequested ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isNil( lastReceived ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return lastRequested > lastReceived;
|
||||
};
|
||||
|
||||
const isGetOrdersError = getResource => ( query = {} ) => {
|
||||
|
|
|
@ -267,7 +267,7 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll
|
|||
),
|
||||
|
||||
);
|
||||
$params['extended_product_info'] = array(
|
||||
$params['extended_info'] = array(
|
||||
'description' => __( 'Add additional piece of info about each product to the report.', 'wc-admin' ),
|
||||
'type' => 'boolean',
|
||||
'default' => false,
|
||||
|
|
|
@ -260,4 +260,14 @@ class WC_Admin_Reports_Categories_Data_Store extends WC_Admin_Reports_Data_Store
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string to be used as cache key for the data.
|
||||
*
|
||||
* @param array $params Query parameters.
|
||||
* @return string
|
||||
*/
|
||||
protected function get_cache_key( $params ) {
|
||||
return 'woocommerce_' . self::TABLE_NAME . '_' . md5( wp_json_encode( $params ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -284,17 +284,6 @@ class WC_Admin_Reports_Data_Store {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string to be used as cache key for the data.
|
||||
*
|
||||
* @param array $params Query parameters.
|
||||
* @return string
|
||||
*/
|
||||
protected function get_cache_key( $params ) {
|
||||
// TODO: this is not working in PHP 5.2 (but revenue class has static methods, so it cannot use object property).
|
||||
return 'woocommerce_' . $this::TABLE_NAME . '_' . md5( wp_json_encode( $params ) ); // phpcs:ignore PHPCompatibility.Syntax.NewDynamicAccessToStatic
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts strings returned from the database to appropriate data types for output.
|
||||
*
|
||||
|
|
|
@ -579,4 +579,14 @@ class WC_Admin_Reports_Orders_Data_Store extends WC_Admin_Reports_Data_Store imp
|
|||
|
||||
return count( $customer_orders ) > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string to be used as cache key for the data.
|
||||
*
|
||||
* @param array $params Query parameters.
|
||||
* @return string
|
||||
*/
|
||||
protected function get_cache_key( $params ) {
|
||||
return 'woocommerce_' . self::TABLE_NAME . '_' . md5( wp_json_encode( $params ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,18 +139,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.
|
||||
*
|
||||
* @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 ) {
|
||||
$extended_info = new ArrayObject();
|
||||
if ( $query_args['extended_info'] ) {
|
||||
$product = wc_get_product( $product_data['product_id'] );
|
||||
$extended_attributes = apply_filters( 'woocommerce_rest_reports_products_extended_attributes', $this->extended_attributes, $product_data );
|
||||
foreach ( $extended_attributes as $extended_attribute ) {
|
||||
$function = 'get_' . $extended_attribute;
|
||||
if ( is_callable( array( $product, $function ) ) ) {
|
||||
$value = $product->{$function}();
|
||||
$products_data[ $key ][ $extended_attribute ] = $value;
|
||||
$extended_info[ $extended_attribute ] = $value;
|
||||
}
|
||||
}
|
||||
$extended_info = $this->cast_numbers( $extended_info );
|
||||
}
|
||||
$products_data[ $key ]['extended_info'] = $extended_info;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +184,7 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
|||
'fields' => '*',
|
||||
'categories' => array(),
|
||||
'product_includes' => 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.
|
||||
'order_status' => parent::get_report_order_statuses(),
|
||||
|
||||
|
@ -243,9 +249,8 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
|||
return $data;
|
||||
}
|
||||
|
||||
if ( $query_args['extended_product_info'] ) {
|
||||
$this->include_extended_product_info( $product_data );
|
||||
}
|
||||
$this->include_extended_info( $product_data, $query_args );
|
||||
|
||||
$product_data = array_map( array( $this, 'cast_numbers' ), $product_data );
|
||||
$data = (object) array(
|
||||
'data' => $product_data,
|
||||
|
@ -260,4 +265,14 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string to be used as cache key for the data.
|
||||
*
|
||||
* @param array $params Query parameters.
|
||||
* @return string
|
||||
*/
|
||||
protected function get_cache_key( $params ) {
|
||||
return 'woocommerce_' . self::TABLE_NAME . '_' . md5( wp_json_encode( $params ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -259,4 +259,14 @@ class WC_Admin_Reports_Variations_Data_Store extends WC_Admin_Reports_Data_Store
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string to be used as cache key for the data.
|
||||
*
|
||||
* @param array $params Query parameters.
|
||||
* @return string
|
||||
*/
|
||||
protected function get_cache_key( $params ) {
|
||||
return 'woocommerce_' . self::TABLE_NAME . '_' . md5( wp_json_encode( $params ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -56,7 +56,7 @@
|
|||
"@wordpress/custom-templated-path-webpack-plugin": "1.1.5",
|
||||
"@wordpress/jest-preset-default": "2.0.6",
|
||||
"@wordpress/postcss-themes": "1.0.4",
|
||||
"ast-types": "0.11.6",
|
||||
"ast-types": "0.11.7",
|
||||
"autoprefixer": "9.3.1",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "10.0.1",
|
||||
|
@ -74,7 +74,7 @@
|
|||
"eslint": "5.9.0",
|
||||
"eslint-config-wpcalypso": "4.0.1",
|
||||
"eslint-loader": "2.1.1",
|
||||
"eslint-plugin-jest": "22.0.0",
|
||||
"eslint-plugin-jest": "22.1.0",
|
||||
"eslint-plugin-jsx-a11y": "6.1.2",
|
||||
"eslint-plugin-react": "7.11.1",
|
||||
"eslint-plugin-wpcalypso": "4.0.2",
|
||||
|
@ -82,7 +82,7 @@
|
|||
"grunt": "1.0.3",
|
||||
"grunt-checktextdomain": "1.0.1",
|
||||
"grunt-wp-i18n": "1.0.2",
|
||||
"husky": "1.1.4",
|
||||
"husky": "1.2.0",
|
||||
"lerna": "3.4.3",
|
||||
"node-sass": "4.10.0",
|
||||
"postcss-color-function": "4.0.1",
|
||||
|
@ -97,9 +97,9 @@
|
|||
"rtlcss": "2.4.0",
|
||||
"sass-loader": "7.1.0",
|
||||
"style-loader": "0.23.1",
|
||||
"stylelint": "9.8.0",
|
||||
"stylelint": "9.9.0",
|
||||
"stylelint-config-wordpress": "13.1.0",
|
||||
"webpack": "4.26.0",
|
||||
"webpack": "4.26.1",
|
||||
"webpack-cli": "3.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -133,7 +133,7 @@
|
|||
"html-to-react": "1.3.3",
|
||||
"interpolate-components": "1.1.1",
|
||||
"lodash": "^4.17.11",
|
||||
"marked": "0.5.1",
|
||||
"marked": "0.5.2",
|
||||
"qs": "^6.5.2",
|
||||
"react-click-outside": "3.0.1",
|
||||
"react-dates": "^18.0.4",
|
||||
|
|
|
@ -52,6 +52,7 @@ class WC_Tests_Reports_Products extends WC_Unit_Test_Case {
|
|||
'items_sold' => 4,
|
||||
'gross_revenue' => 100.0, // $25 * 4.
|
||||
'orders_count' => 1,
|
||||
'extended_info' => new ArrayObject(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -121,12 +122,14 @@ class WC_Tests_Reports_Products extends WC_Unit_Test_Case {
|
|||
'items_sold' => 4,
|
||||
'gross_revenue' => 80.0, // $20 * 4.
|
||||
'orders_count' => 1,
|
||||
'extended_info' => new ArrayObject(),
|
||||
),
|
||||
1 => array(
|
||||
'product_id' => $product->get_id(),
|
||||
'items_sold' => 4,
|
||||
'gross_revenue' => 100.0, // $25 * 4.
|
||||
'orders_count' => 1,
|
||||
'extended_info' => new ArrayObject(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -151,12 +154,14 @@ class WC_Tests_Reports_Products extends WC_Unit_Test_Case {
|
|||
'items_sold' => 4,
|
||||
'gross_revenue' => 100.0, // $25 * 4.
|
||||
'orders_count' => 1,
|
||||
'extended_info' => new ArrayObject(),
|
||||
),
|
||||
1 => array(
|
||||
'product_id' => $product_2->get_id(),
|
||||
'items_sold' => 4,
|
||||
'gross_revenue' => 80.0, // $20 * 4.
|
||||
'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() );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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