'refund-item', 'plural' => 'refund-items', 'ajax' => false, ) ); $this->get_counts(); } /** * Get the base URL for the order item list table. * * @since 3.0 * * @return string Base URL. */ public function get_base_url() {} /** * Retrieve the view types. * * @since 3.0 * * @return array $views All the views available. */ public function get_views() { return array(); } /** * Retrieve the table columns. * * @since 3.0 * * @return array $columns Array of all the list table columns. */ public function get_columns() { $columns = array( 'cb' => '', 'name' => __( 'Product', 'easy-digital-downloads' ), 'amount' => __( 'Unit Price', 'easy-digital-downloads' ), 'quantity' => __( 'Quantity', 'easy-digital-downloads' ), 'subtotal' => __( 'Subtotal', 'easy-digital-downloads' ), ); // Maybe add tax column. $order = $this->get_order(); if ( $order && $order->get_tax_rate() ) { $columns['tax'] = __( 'Tax', 'easy-digital-downloads' ); } // Total at the end. $columns['total'] = __( 'Total', 'easy-digital-downloads' ); // Return columns. return $columns; } /** * Retrieve the sortable columns. * * @since 3.0 * * @return array Array of all the sortable columns. */ public function get_sortable_columns() { return array(); } /** * Gets the name of the primary column. * * @since 2.5 * @access protected * * @return string Name of the primary column. */ protected function get_primary_column_name() { return 'name'; } /** * Generates a unique ID for an item, to be used as HTML IDs. * We cannot simply use `$item->id` because it's possible that an order item and order adjustment * could have the same ID. * * @param Order_Item|Order_Adjustment $item * * @since 3.0 * @return string */ private function get_item_unique_id( $item ) { return $item instanceof Order_Item ? 'order-item-' . $item->id : 'order-adjustment-' . $item->id; } /** * Returns a string that designates the type of object. This is used in HTML `name` attributes. * * @param Order_Item|Order_Adjustment $item * * @since 3.0 * @return string */ private function get_object_type( $item ) { return $item instanceof Order_Item ? 'order_item' : 'order_adjustment'; } /** * Returns the item display name. * * @param Order_Item|Order_Adjustment $item * * @since 3.0 * @return string */ private function get_item_display_name( $item ) { $name = ''; if ( $item instanceof Order_Item ) { return $item->get_order_item_name(); } if ( $item instanceof Order_Adjustment ) { $name = __( 'Order Fee', 'easy-digital-downloads' ); if ( 'credit' === $item->type ) { $name = __( 'Order Credit', 'easy-digital-downloads' ); } if ( ! empty( $item->description ) ) { $name .= ': ' . $item->description; } } return $name; } /** * This function renders most of the columns in the list table. * * @since 3.0 * * @param Order_Item|Order_Adjustment $item Order item or adjustment object. * @param string $column_name The name of the column. * * @return string Column name. */ public function column_default( $item, $column_name ) { $object_type = $this->get_object_type( $item ); $item_id = $this->get_item_unique_id( $item ); switch ( $column_name ) { case 'amount': return $this->format_currency( $item, $column_name ); case 'total': return $this->format_currency( $item, $column_name, 0 ); case 'quantity': return $this->get_quantity_column( $item, $column_name, $item_id, $object_type ); case 'subtotal': case 'tax': return $this->get_adjustable_column( $item, $column_name, $item_id, $object_type ); default: return property_exists( $item, $column_name ) ? $item->{$column_name} : ''; } } /** * This private function formats a column value for currency. * * @since 3.0 * * @param Order_Item|Order_Adjustment $item Item object. * @param string $column_name ID of the column being displayed. * @param false|float $amount_override Amount override, in case it's not in the order item. * * @return string Formatted amount. */ private function format_currency( $item, $column_name, $amount_override = false ) { $symbol = $this->get_currency_symbol( $item->order_id ); $currency_pos = edd_get_option( 'currency_position', 'before' ); $formatted_amount = ''; if ( 'before' === $currency_pos ) { $formatted_amount .= $symbol; } // Order Adjustments do not have an `amount` column. We can use `subtotal` instead. if ( 'amount' === $column_name && $item instanceof Order_Adjustment ) { $column_name = 'subtotal'; } $amount = false !== $amount_override ? $amount_override : $item->{$column_name}; $formatted_amount .= '' . edd_format_amount( $amount, true, $this->get_order_currency_decimals( $item->order_id ) ) . ''; if ( 'after' === $currency_pos ) { $formatted_amount .= $symbol; } return $formatted_amount; } /** * This private function returns the form input for refundable items, * or amounts for items which have already been refunded. * * @param Order_Item $item The item object. * @param string $column_name ID of the column being displayed. * @param string $item_id Unique ID of the order item for the refund modal. * @param string $object_type The item type. * @return string */ private function get_adjustable_column( $item, $column_name, $item_id, $object_type ) { if ( 'refunded' === $item->status ) { return $this->format_currency( $item, $column_name, 0 ); } $currency_pos = edd_get_option( 'currency_position', 'before' ); // Maximum amounts that can be refunded. $refundable_amounts = $item->get_refundable_amounts(); $amount_remaining = array_key_exists( $column_name, $refundable_amounts ) ? $refundable_amounts[ $column_name ] : $item->{$column_name}; /* * Original amount. * For subtotals, we actually do subtotal minus discounts for simplicity so that the end user * doesn't have to juggle that. */ $original_amount = $item->{$column_name}; if ( 'subtotal' === $column_name && ! empty( $item->discount ) ) { $original_amount -= $item->discount; } ob_start(); ?>
'; echo esc_html( $this->get_currency_symbol( $item->order_id ) ); echo ''; } ?> '; echo esc_html( $this->get_currency_symbol( $item->order_id ) ); echo ''; } ?>
format_currency( $item, $column_name, $amount_remaining ); ?>
get_refundable_amounts(); $item_quantity = 'order_item' === $object_type ? $refundable_amounts['quantity'] : 1; ob_start(); ?>
$options, 'name' => 'refund_' . esc_attr( $object_type ) . '[' . esc_attr( $item->id ) . '][quantity]', 'id' => 'edd-order-item-quantity-' . esc_attr( $item_id ), 'class' => 'edd-order-item-refund-quantity edd-order-item-refund-input', 'disabled' => true, 'show_option_all' => false, 'show_option_none' => false, 'chosen' => false, 'selected' => $item_quantity, 'data' => array( 'max' => intval( $item_quantity ), 'original' => intval( $item->quantity ), ), ); ?> html->select( $args ); ?>
currency ); } else { $currency_decimals = 2; } } return $currency_decimals; } /** * Retrieves the currency symbol for a given order item. * * @param int $order_id * * @since 3.0 * @return string|null */ private function get_currency_symbol( $order_id ) { static $symbol = null; if ( is_null( $symbol ) ) { $order = edd_get_order( $order_id ); if ( $order ) { $symbol = edd_currency_symbol( $order->currency ); } } return $symbol; } /** * Render the checkbox column * * @since 3.0 * * @param Order_Item|Order_Adjustment $item Order Item or Order Adjustment object. * * @return string */ public function column_cb( $item ) { $object_type = $this->get_object_type( $item ); $refundable_amounts = $item->get_refundable_amounts(); $total_remaining = array_key_exists( 'total', $refundable_amounts ) ? floatval( $refundable_amounts['total'] ) : 0.00; if ( 'refunded' !== $item->status && 0.00 != $total_remaining ) { return sprintf( '', /*$1%s*/ 'refund_' . esc_attr( $object_type ), /*$2%s*/ esc_attr( $item->id ), /* translators: product name */ esc_html( sprintf( __( 'Select %s', 'easy-digital-downloads' ), $this->get_item_display_name( $item ) ) ) ); } return ''; } /** * Render the Name Column * * @since 3.0 * * @param Order_Item|Order_Adjustment $item Order Item object. * * @return string Data shown in the Name column */ public function column_name( $item ) { $checkbox_id = 'refund_' . $this->get_object_type( $item ) . '-' . $item->id; $display_name = esc_html( $this->get_item_display_name( $item ) ); $status_label = ! empty( $item->status ) && 'complete' !== $item->status ? ' — ' . edd_get_status_label( $item->status ) : ''; if ( 'refunded' === $item->status ) { return '' . $display_name . '' . esc_html( $status_label ); } return '' . $status_label; } /** * Message to be displayed when there are no items * * @since 3.0 */ public function no_items() { esc_html_e( 'No items found.', 'easy-digital-downloads' ); } /** * Retrieve the bulk actions * * @since 3.0 * @return array $actions Array of the bulk actions */ public function get_bulk_actions() { return array(); } /** * Process the bulk actions * * @since 3.0 */ public function process_bulk_action() {} /** * Retrieve the order_item code counts * * @todo Fees aren't included in this count, but where does this actually get used anyway? * * @since 3.0 */ public function get_counts() { // Maybe retrieve counts. if ( ! edd_is_add_order_page() ) { // Check for an order ID $order_id = ! empty( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) // WPCS: CSRF ok. : 0; // Get counts $this->counts = edd_get_order_item_counts( array( 'order_id' => $order_id, ) ); } } /** * Retrieve all order data to be shown on the refund table. * This includes order items and order adjustments. * * @since 3.0 * @return Order[]|Order_Adjustment[] All order items and order adjustments associated with the current order. */ public function get_data() { $order = $this->get_order(); if ( empty( $order ) ) { return array(); } // Get order items. $order_items = edd_get_order_items( array( 'order_id' => $order->id, 'number' => 999, ) ); // Get order fees $order_fees = $order->get_fees(); // Get order credits. $credits = edd_get_order_adjustments( array( 'object_id' => $order->id, 'object_type' => 'order', 'type' => 'credit', ) ); return array_merge( $order_items, $order_fees, $credits ); } /** * Setup the final data for the table * * @since 3.0 */ public function prepare_items() { $this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns(), ); $this->items = $this->get_data(); } /** * Generates content for a single row of the table * * @since 3.0 * * @param Order_Item|Order_Adjustment $item Order item object. */ public function single_row( $item ) { $is_adjustment = $item instanceof Order_Adjustment; $item_class = $is_adjustment ? $item->object_id : $item->order_id; // Status. $classes = array_map( 'sanitize_html_class', array( 'order-' . $item_class, $item->status, 'refunditem', ) ); // Turn into a string. $class = implode( ' ', $classes ); $item_id = $this->get_item_unique_id( $item ); $is_credit = $is_adjustment && 'credit' === $item->type; ?> ="id ); ?>" class=""> single_row_columns( $item ); ?> _args['singular']; wp_nonce_field( 'edd_process_refund', 'edd_process_refund' ); $this->screen->render_screen_reader_content( 'heading_list' ); ?> print_column_headers(); ?> > display_rows_or_placeholder(); ?>
get_order() ); $this->display_tablenav( 'bottom' ); ?>
items as $item ) { if ( empty( $order_id ) ) { $order_id = $item->order_id; } $this->single_row( $item ); } $currency_symbol = $this->get_currency_symbol( $order_id ); // Now we need to add the columns for the totals. ?> %s', $currency_symbol ); $before = 'before' === $currency_position ? $currency_symbol_output : ''; $after = 'after' === $currency_position ? $currency_symbol_output : ''; $amount = edd_format_amount( 0.00, true, $this->get_order_currency_decimals( $order_id ) ); printf( '%1$s%2$s%3$s', $before, // phpcs:ignore esc_attr( $amount ), $after // phpcs:ignore ); ?> get_order(); if ( $order && $order->get_tax_rate() ) : ?> %1$s%2$s%3$s', $before, // phpcs:ignore esc_attr( $amount ), $after // phpcs:ignore ); ?> %1$s%2$s%3$s', $before, // phpcs:ignore esc_attr( $amount ), $after // phpcs:ignore ); ?>