Update activity panels order endpoint (https://github.com/woocommerce/woocommerce-admin/pull/1578)
* Only show customer name if available * Map customer data to extended_info in orders API response * Add gross total and refund total to orders API response * Hook up report orders endpoint to activity panel orders * Add on-hold orders to activity panel orders * Destructure extended_info in case of filtering * Add customer link to orders panel
This commit is contained in:
parent
0ef2dc27f4
commit
73ff2d37e8
|
@ -24,7 +24,7 @@ import {
|
|||
Section,
|
||||
} from '@woocommerce/components';
|
||||
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
|
||||
import { getAdminLink } from '@woocommerce/navigation';
|
||||
import { getAdminLink, getNewPath } from '@woocommerce/navigation';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -32,7 +32,6 @@ import { getAdminLink } from '@woocommerce/navigation';
|
|||
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 'wc-api/constants';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
|
@ -64,28 +63,56 @@ function OrdersPanel( { orders, isRequesting, isError } ) {
|
|||
</EllipsisMenu>
|
||||
);
|
||||
|
||||
const orderCardTitle = ( order, address ) => {
|
||||
const name = `${ address.first_name } ${ address.last_name }`;
|
||||
const getCustomerString = order => {
|
||||
const extended_info = order.extended_info || {};
|
||||
const { first_name, last_name } = extended_info.customer || {};
|
||||
|
||||
if ( ! first_name && ! last_name ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const name = [ first_name, last_name ].join( ' ' );
|
||||
return sprintf(
|
||||
__(
|
||||
/* translators: describes who placed an order, e.g. Order #123 placed by John Doe */
|
||||
'placed by {{customerLink}}%(customerName)s{{/customerLink}}',
|
||||
'wc-admin'
|
||||
),
|
||||
{
|
||||
customerName: name,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const orderCardTitle = order => {
|
||||
const { extended_info, order_id } = order;
|
||||
const { customer } = extended_info || {};
|
||||
const customerUrl = customer.customer_id
|
||||
? getNewPath( {}, '/analytics/customers', {
|
||||
filter: 'single_customer',
|
||||
customer_id: customer.customer_id,
|
||||
} )
|
||||
: null;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{ interpolateComponents( {
|
||||
mixedString: sprintf(
|
||||
__(
|
||||
/* eslint-disable-next-line max-len */
|
||||
'Order {{orderLink}}#%(orderNumber)s{{/orderLink}} placed by {{customerLink}}%(customerName)s{{/customerLink}} {{destinationFlag/}}',
|
||||
'Order {{orderLink}}#%(orderNumber)s{{/orderLink}} %(customerString)s {{destinationFlag/}}',
|
||||
'wc-admin'
|
||||
),
|
||||
{
|
||||
orderNumber: order.number,
|
||||
customerName: name,
|
||||
orderNumber: order_id,
|
||||
customerString: getCustomerString( order ),
|
||||
}
|
||||
),
|
||||
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 } />,
|
||||
orderLink: <Link href={ 'post.php?action=edit&post=' + order_id } type="wp-admin" />,
|
||||
destinationFlag: customer.country ? (
|
||||
<Flag code={ customer.country } round={ false } />
|
||||
) : null,
|
||||
customerLink: customerUrl ? <Link href={ customerUrl } type="wc-admin" /> : <span />,
|
||||
},
|
||||
} ) }
|
||||
</Fragment>
|
||||
|
@ -93,20 +120,20 @@ function OrdersPanel( { orders, isRequesting, isError } ) {
|
|||
};
|
||||
|
||||
const cards = [];
|
||||
orders.forEach( ( order, id ) => {
|
||||
// We want the billing address, but shipping can be used as a fallback.
|
||||
const address = { ...order.shipping, ...order.billing };
|
||||
const productsCount = order.line_items.reduce( ( total, line ) => total + line.quantity, 0 );
|
||||
orders.forEach( order => {
|
||||
const extended_info = order.extended_info || {};
|
||||
const productsCount =
|
||||
extended_info && extended_info.products ? extended_info.products.length : 0;
|
||||
|
||||
const total = order.total;
|
||||
const refundValue = getOrderRefundTotal( order );
|
||||
const remainingTotal = getCurrencyFormatDecimal( order.total ) + refundValue;
|
||||
const total = order.gross_total;
|
||||
const refundValue = order.refund_total;
|
||||
const remainingTotal = getCurrencyFormatDecimal( total ) + refundValue;
|
||||
|
||||
cards.push(
|
||||
<ActivityCard
|
||||
key={ id }
|
||||
key={ order.order_id }
|
||||
className="woocommerce-order-activity-card"
|
||||
title={ orderCardTitle( order, address ) }
|
||||
title={ orderCardTitle( order ) }
|
||||
date={ order.date_created }
|
||||
subtitle={
|
||||
<div>
|
||||
|
@ -118,16 +145,15 @@ function OrdersPanel( { orders, isRequesting, isError } ) {
|
|||
</span>
|
||||
{ refundValue ? (
|
||||
<span>
|
||||
<s>{ formatCurrency( total, order.currency_symbol ) }</s>{' '}
|
||||
{ formatCurrency( remainingTotal, order.currency_symbol ) }
|
||||
<s>{ formatCurrency( total ) }</s> { formatCurrency( remainingTotal ) }
|
||||
</span>
|
||||
) : (
|
||||
<span>{ formatCurrency( total, order.currency_symbol ) }</span>
|
||||
<span>{ formatCurrency( total ) }</span>
|
||||
) }
|
||||
</div>
|
||||
}
|
||||
actions={
|
||||
<Button isDefault href={ getAdminLink( 'post.php?action=edit&post=' + order.id ) }>
|
||||
<Button isDefault href={ getAdminLink( 'post.php?action=edit&post=' + order.order_id ) }>
|
||||
{ __( 'Begin fulfillment' ) }
|
||||
</Button>
|
||||
}
|
||||
|
@ -162,29 +188,30 @@ function OrdersPanel( { orders, isRequesting, isError } ) {
|
|||
}
|
||||
|
||||
OrdersPanel.propTypes = {
|
||||
orders: PropTypes.instanceOf( Map ).isRequired,
|
||||
orders: PropTypes.array.isRequired,
|
||||
isError: PropTypes.bool,
|
||||
isRequesting: PropTypes.bool,
|
||||
};
|
||||
|
||||
OrdersPanel.defaultProps = {
|
||||
orders: new Map(),
|
||||
orders: [],
|
||||
isError: false,
|
||||
isRequesting: false,
|
||||
};
|
||||
|
||||
export default compose(
|
||||
withSelect( select => {
|
||||
const { getItems, getItemsError, isGetItemsRequesting } = select( 'wc-api' );
|
||||
const { getReportItems, getReportItemsError, isReportItemsRequesting } = select( 'wc-api' );
|
||||
const ordersQuery = {
|
||||
page: 1,
|
||||
per_page: QUERY_DEFAULTS.pageSize,
|
||||
status: 'processing',
|
||||
status_is: [ 'processing', 'on-hold' ],
|
||||
extended_info: true,
|
||||
};
|
||||
|
||||
const orders = getItems( 'orders', ordersQuery );
|
||||
const isError = Boolean( getItemsError( 'orders', ordersQuery ) );
|
||||
const isRequesting = isGetItemsRequesting( 'orders', ordersQuery );
|
||||
const orders = getReportItems( 'orders', ordersQuery ).data;
|
||||
const isError = Boolean( getReportItemsError( 'orders', ordersQuery ) );
|
||||
const isRequesting = isReportItemsRequesting( 'orders', ordersQuery );
|
||||
|
||||
return { orders, isError, isRequesting };
|
||||
} )
|
||||
|
|
|
@ -30,6 +30,8 @@ class WC_Admin_Reports_Orders_Data_Store extends WC_Admin_Reports_Data_Store imp
|
|||
'status' => 'strval',
|
||||
'customer_id' => 'intval',
|
||||
'net_total' => 'floatval',
|
||||
'gross_total' => 'floatval',
|
||||
'refund_total' => 'floatval',
|
||||
'num_items_sold' => 'intval',
|
||||
'customer_type' => 'strval',
|
||||
);
|
||||
|
@ -45,6 +47,8 @@ class WC_Admin_Reports_Orders_Data_Store extends WC_Admin_Reports_Data_Store imp
|
|||
'status' => 'REPLACE(status, "wc-", "") as status',
|
||||
'customer_id' => 'customer_id',
|
||||
'net_total' => 'net_total',
|
||||
'gross_total' => 'gross_total',
|
||||
'refund_total' => 'refund_total',
|
||||
'num_items_sold' => 'num_items_sold',
|
||||
'customer_type' => '(CASE WHEN returning_customer <> 0 THEN "returning" ELSE "new" END) as customer_type',
|
||||
);
|
||||
|
@ -243,6 +247,8 @@ class WC_Admin_Reports_Orders_Data_Store extends WC_Admin_Reports_Data_Store imp
|
|||
$mapped_products = $this->map_array_by_key( $products, 'product_id' );
|
||||
$coupons = $this->get_coupons_by_order_ids( array_keys( $mapped_orders ) );
|
||||
$product_categories = $this->get_product_categories_by_product_ids( array_keys( $mapped_products ) );
|
||||
$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 ) {
|
||||
|
@ -280,8 +286,12 @@ class WC_Admin_Reports_Orders_Data_Store extends WC_Admin_Reports_Data_Store imp
|
|||
'products' => array(),
|
||||
'categories' => array(),
|
||||
'coupons' => array(),
|
||||
'customer' => array(),
|
||||
);
|
||||
$orders_data[ $key ]['extended_info'] = isset( $mapped_data[ $order_data['order_id'] ] ) ? array_merge( $defaults, $mapped_data[ $order_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'] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,6 +334,32 @@ class WC_Admin_Reports_Orders_Data_Store extends WC_Admin_Reports_Data_Store imp
|
|||
return $products;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get customer data from order IDs.
|
||||
*
|
||||
* @param array $orders Array of orders.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_customers_by_orders( $orders ) {
|
||||
global $wpdb;
|
||||
$customer_lookup_table = $wpdb->prefix . 'wc_customer_lookup';
|
||||
|
||||
$customer_ids = array();
|
||||
foreach ( $orders as $order ) {
|
||||
if ( $order['customer_id'] ) {
|
||||
$customer_ids[] = $order['customer_id'];
|
||||
}
|
||||
}
|
||||
$customer_ids = implode( ',', $customer_ids );
|
||||
|
||||
$customers = $wpdb->get_results(
|
||||
"SELECT * FROM {$customer_lookup_table} WHERE customer_id IN ({$customer_ids})",
|
||||
ARRAY_A
|
||||
); // WPCS: cache ok, DB call ok, unprepared SQL ok.
|
||||
|
||||
return $customers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get coupon information from order IDs.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue