/** @format */ /** * External dependencies */ import { __, _n, sprintf } from '@wordpress/i18n'; import { Button } from '@wordpress/components'; import { Component, Fragment } from '@wordpress/element'; import { compose } from '@wordpress/compose'; import Gridicon from 'gridicons'; import PropTypes from 'prop-types'; import interpolateComponents from 'interpolate-components'; import { keyBy, map, merge } from 'lodash'; /** * WooCommerce dependencies */ import { EmptyContent, Flag, Link, OrderStatus, Section } from '@woocommerce/components'; import { formatCurrency } from '@woocommerce/currency'; import { getAdminLink, getNewPath } from '@woocommerce/navigation'; /** * Internal dependencies */ import { ActivityCard, ActivityCardPlaceholder } from '../activity-card'; import ActivityHeader from '../activity-header'; import ActivityOutboundLink from '../activity-outbound-link'; import { DEFAULT_ACTIONABLE_STATUSES, QUERY_DEFAULTS } from 'wc-api/constants'; import withSelect from 'wc-api/with-select'; class OrdersPanel extends Component { renderEmptyCard() { const { hasNonActionableOrders } = this.props; if ( hasNonActionableOrders ) { return ( } > { __( "Good job, you've fulfilled all of your new orders!", 'woocommerce-admin' ) } ); } return ( } actions={ } > { __( "You're still waiting for your customers to make their first orders. " + 'While you wait why not learn how to manage orders?', 'woocommerce-admin' ) } ); } renderOrders() { const { orders } = this.props; if ( orders.length === 0 ) { return this.renderEmptyCard(); } 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}}', 'woocommerce-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', customers: customer.customer_id, } ) : null; return ( { interpolateComponents( { mixedString: sprintf( __( 'Order {{orderLink}}#%(orderNumber)s{{/orderLink}} %(customerString)s {{destinationFlag/}}', 'woocommerce-admin' ), { orderNumber: order_id, customerString: getCustomerString( order ), } ), components: { orderLink: , destinationFlag: customer.country ? ( ) : null, customerLink: customerUrl ? : , }, } ) } ); }; const cards = []; orders.forEach( order => { const extended_info = order.extended_info || {}; const productsCount = extended_info && extended_info.products ? extended_info.products.length : 0; const total = order.gross_total; cards.push( { sprintf( _n( '%d product', '%d products', productsCount, 'woocommerce-admin' ), productsCount ) } { formatCurrency( total ) } } actions={ } > ); } ); return ( { cards } { __( 'Manage all orders', 'woocommerce-admin' ) } ); } render() { const { orders, isRequesting, isError, orderStatuses } = this.props; if ( isError ) { if ( ! orderStatuses.length ) { return ( ); } const title = __( 'There was an error getting your orders. Please try again.', 'woocommerce-admin' ); const actionLabel = __( 'Reload', 'woocommerce-admin' ); const actionCallback = () => { // @todo Add tracking for how often an error is displayed, and the reload action is clicked. window.location.reload(); }; return ( ); } const title = isRequesting || orders.length ? __( 'Orders', 'woocommerce-admin' ) : __( 'No orders to ship', 'woocommerce-admin' ); return (
{ isRequesting ? ( ) : ( this.renderOrders() ) }
); } } OrdersPanel.propTypes = { orders: PropTypes.array.isRequired, isError: PropTypes.bool, isRequesting: PropTypes.bool, }; OrdersPanel.defaultProps = { orders: [], isError: false, isRequesting: false, }; export default compose( withSelect( ( select, props ) => { const { hasActionableOrders } = props; const { getItems, getItemsTotalCount, getItemsError, isGetItemsRequesting, getReportItems, getReportItemsError, isReportItemsRequesting, } = select( 'wc-api' ); const orderStatuses = wcSettings.wcAdminSettings.woocommerce_actionable_order_statuses || DEFAULT_ACTIONABLE_STATUSES; if ( ! orderStatuses.length ) { return { orders: [], isError: true, isRequesting: false, orderStatuses }; } // Query the core Orders endpoint for the most up-to-date statuses. const allOrdersQuery = { page: 1, per_page: QUERY_DEFAULTS.pageSize, status: orderStatuses, _fields: [ 'id', 'date_created_gmt', 'status' ], }; const actionableOrders = Array.from( getItems( 'orders', allOrdersQuery ).values() ); if ( hasActionableOrders && actionableOrders.length ) { // Retrieve the Order stats data from our reporting table. const ordersQuery = { page: 1, per_page: QUERY_DEFAULTS.pageSize, extended_info: true, order_includes: map( actionableOrders, 'id' ), }; const reportOrders = getReportItems( 'orders', ordersQuery ).data; const isError = Boolean( getReportItemsError( 'orders', ordersQuery ) ); const isRequesting = isReportItemsRequesting( 'orders', ordersQuery ); let orders = []; if ( reportOrders && reportOrders.length ) { // Merge the core endpoint data with our reporting table. const actionableOrdersById = keyBy( actionableOrders, 'id' ); orders = reportOrders.map( order => merge( {}, order, actionableOrdersById[ order.order_id ] || {} ) ); } return { orders, isError, isRequesting, orderStatuses }; } const totalNonActionableOrders = getItemsTotalCount( 'orders', allOrdersQuery ); const isError = Boolean( getItemsError( 'orders', allOrdersQuery ) ); const isRequesting = isGetItemsRequesting( 'orders', allOrdersQuery ); return { hasNonActionableOrders: totalNonActionableOrders > 0, isError, isRequesting, orderStatuses, }; } ) )( OrdersPanel );