756 lines
21 KiB
PHP
756 lines
21 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Refund Items Table Class.
|
||
|
*
|
||
|
* @package EDD
|
||
|
* @subpackage Admin/Orders
|
||
|
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||
|
* @since 3.0
|
||
|
*/
|
||
|
namespace EDD\Admin;
|
||
|
|
||
|
// Exit if accessed directly
|
||
|
use EDD\Orders\Order;
|
||
|
use EDD\Orders\Order_Adjustment;
|
||
|
use EDD\Orders\Order_Item;
|
||
|
|
||
|
defined( 'ABSPATH' ) || exit;
|
||
|
|
||
|
/**
|
||
|
* Order_Items_Table Class.
|
||
|
*
|
||
|
* Renders the Refund Items table on the Refund modal.
|
||
|
*
|
||
|
* @since 3.0
|
||
|
*/
|
||
|
class Refund_Items_Table extends List_Table {
|
||
|
|
||
|
/**
|
||
|
* Constructor.
|
||
|
*
|
||
|
* @since 3.0
|
||
|
* @see WP_List_Table::__construct()
|
||
|
*/
|
||
|
public function __construct() {
|
||
|
global $hook_suffix;
|
||
|
|
||
|
parent::__construct( array(
|
||
|
'singular' => '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' => '<input type="checkbox" />',
|
||
|
'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 .= '<span data-' . $column_name . '="' . edd_sanitize_amount( $amount ) . '">' . edd_format_amount( $amount, true, $this->get_order_currency_decimals( $item->order_id ) ) . '</span>';
|
||
|
|
||
|
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();
|
||
|
?>
|
||
|
<div class="edd-form-group">
|
||
|
<label for="edd-order-item-<?php echo esc_attr( $item_id ); ?>-refund-<?php echo esc_attr( $column_name ); ?>" class="screen-reader-text">
|
||
|
<?php
|
||
|
if ( 'subtotal' === $column_name ) {
|
||
|
esc_html_e( 'Amount to refund, excluding tax', 'easy-digital-downloads' );
|
||
|
} else {
|
||
|
esc_html_e( 'Amount of tax to refund', 'easy-digital-downloads' );
|
||
|
}
|
||
|
?>
|
||
|
</label>
|
||
|
<div class="edd-form-group__control">
|
||
|
<?php
|
||
|
if ( 'before' === $currency_pos ) {
|
||
|
echo '<span class="edd-amount-control__currency is-before">';
|
||
|
echo esc_html( $this->get_currency_symbol( $item->order_id ) );
|
||
|
echo '</span>';
|
||
|
}
|
||
|
?>
|
||
|
<span class="edd-amount-control__input">
|
||
|
<input
|
||
|
type="text"
|
||
|
id="edd-order-item-<?php echo esc_attr( $item_id ); ?>-refund-<?php echo esc_attr( $column_name ); ?>"
|
||
|
class="edd-order-item-refund-<?php echo esc_attr( $column_name ); ?> edd-order-item-refund-input"
|
||
|
name="refund_<?php echo esc_attr( $object_type ); ?>[<?php echo esc_attr( $item->id ); ?>][<?php echo esc_attr( $column_name ); ?>]"
|
||
|
value="<?php echo esc_attr( edd_format_amount( $amount_remaining, true, $this->get_order_currency_decimals( $item->order_id ) ) ); ?>"
|
||
|
placeholder="<?php echo esc_attr( edd_format_amount( 0, true, $this->get_order_currency_decimals( $item->order_id ) ) ); ?>"
|
||
|
data-original="<?php echo esc_attr( $original_amount ); ?>"
|
||
|
data-max="<?php echo esc_attr( $amount_remaining ); ?>"
|
||
|
disabled
|
||
|
/>
|
||
|
</span>
|
||
|
<?php
|
||
|
if ( 'after' === $currency_pos ) {
|
||
|
echo '<span class="edd-amount-control__currency is-after">';
|
||
|
echo esc_html( $this->get_currency_symbol( $item->order_id ) );
|
||
|
echo '</span>';
|
||
|
}
|
||
|
?>
|
||
|
</div>
|
||
|
<small class="edd-order-item-refund-max-amount">
|
||
|
<?php
|
||
|
echo _x( 'Max:', 'Maximum input amount', 'easy-digital-downloads' ) . ' ';
|
||
|
|
||
|
echo $this->format_currency( $item, $column_name, $amount_remaining );
|
||
|
?>
|
||
|
</small>
|
||
|
</div>
|
||
|
<?php
|
||
|
return ob_get_clean();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the quantity column content.
|
||
|
*
|
||
|
* @since 3.0
|
||
|
*
|
||
|
* @param Order_Item|Order_Adjustment $item Order item or adjustment object.
|
||
|
* @param string $column_name The name of the column.
|
||
|
* @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_quantity_column( $item, $column_name, $item_id, $object_type ) {
|
||
|
$refundable_amounts = $item->get_refundable_amounts();
|
||
|
$item_quantity = 'order_item' === $object_type ? $refundable_amounts['quantity'] : 1;
|
||
|
ob_start();
|
||
|
?>
|
||
|
<div class="edd-form-group">
|
||
|
<label for="edd_order_item_quantity_<?php echo esc_attr( $item_id ); ?>" class="screen-reader-text">
|
||
|
<?php esc_html_e( 'Quantity to refund', 'easy-digital-downloads' ); ?>
|
||
|
</label>
|
||
|
<div class="edd-form-group__control">
|
||
|
<?php if ( 'order_item' !== $object_type ) : ?>
|
||
|
<input type="hidden" data-original="<?php echo esc_attr( $item_quantity ); ?>" id="edd_order_item_quantity_<?php echo esc_attr( $item_id ); ?>" class="edd-order-item-refund-quantity edd-order-item-refund-input readonly" name="refund_<?php echo esc_attr( $object_type ); ?>[<?php echo esc_attr( $item->id ); ?>][quantity]" value="<?php echo esc_attr( $item_quantity ); ?>" disabled />
|
||
|
<?php else : ?>
|
||
|
<?php
|
||
|
$options = range( 1, $item_quantity );
|
||
|
array_unshift( $options, '' );
|
||
|
unset( $options[0] );
|
||
|
$args = array(
|
||
|
'options' => $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 ),
|
||
|
),
|
||
|
);
|
||
|
?>
|
||
|
<?php echo EDD()->html->select( $args ); ?>
|
||
|
<?php endif; ?>
|
||
|
</div>
|
||
|
</div>
|
||
|
<?php
|
||
|
|
||
|
return ob_get_clean();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieves the number of decimals for a given order.
|
||
|
*
|
||
|
* @param int $order_id
|
||
|
*
|
||
|
* @since 3.0
|
||
|
* @return int|null
|
||
|
*/
|
||
|
private function get_order_currency_decimals( $order_id ) {
|
||
|
static $currency_decimals = null;
|
||
|
|
||
|
if ( is_null( $currency_decimals ) ) {
|
||
|
$order = edd_get_order( $order_id );
|
||
|
|
||
|
if ( $order ) {
|
||
|
$currency_decimals = edd_currency_decimal_filter( 2, $order->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(
|
||
|
'<input type="checkbox" name="%1$s[]" id="%1$s-%2$s" class="edd-order-item-refund-checkbox" value="%2$s" /><label for="%1$s-%2$s" class="screen-reader-text">%3$s</label>',
|
||
|
/*$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 '<span class="row-title">' . $display_name . '</span>' . esc_html( $status_label );
|
||
|
}
|
||
|
|
||
|
return '<label for="' . esc_attr( $checkbox_id ) . '" class="row-title">' . $display_name . '</label>' . $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;
|
||
|
?>
|
||
|
<tr id="order-item-<?php echo esc_attr( $item_id ); ?>" <?php echo esc_attr( $is_adjustment ? 'data-order-item-adjustment' : 'data-order-item' ); ?>="<?php echo esc_attr( $item->id ); ?>" <?php echo $is_credit ? 'data-credit="1"' : ''; ?> class="<?php echo esc_html( $class ); ?>">
|
||
|
<?php $this->single_row_columns( $item ); ?>
|
||
|
</tr>
|
||
|
<?php
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Displays the table.
|
||
|
*
|
||
|
* @since 3.0
|
||
|
*/
|
||
|
public function display() {
|
||
|
$singular = $this->_args['singular'];
|
||
|
|
||
|
wp_nonce_field( 'edd_process_refund', 'edd_process_refund' );
|
||
|
$this->screen->render_screen_reader_content( 'heading_list' );
|
||
|
?>
|
||
|
<table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<?php $this->print_column_headers(); ?>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
|
||
|
<tbody id="the-list"<?php
|
||
|
if ( $singular ) {
|
||
|
echo " data-wp-lists='list:$singular'";
|
||
|
} ?>>
|
||
|
<?php $this->display_rows_or_placeholder(); ?>
|
||
|
</tbody>
|
||
|
|
||
|
</table>
|
||
|
<div class="edd-submit-refund-actions">
|
||
|
<?php
|
||
|
/**
|
||
|
* Triggers after the table, but before the submit button.
|
||
|
*
|
||
|
* @param Order $order
|
||
|
*
|
||
|
* @since 3.0
|
||
|
*/
|
||
|
do_action( 'edd_after_submit_refund_table', $this->get_order() );
|
||
|
|
||
|
$this->display_tablenav( 'bottom' );
|
||
|
?>
|
||
|
</div>
|
||
|
<?php
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds custom submit button below the refund items table.
|
||
|
*
|
||
|
* @param string $which
|
||
|
* @since 3.0
|
||
|
*/
|
||
|
protected function display_tablenav( $which ) {
|
||
|
if ( 'bottom' !== $which ) {
|
||
|
return;
|
||
|
}
|
||
|
?>
|
||
|
<div class="tablenav bottom">
|
||
|
<button id="edd-submit-refund-submit" class="button button-primary" disabled><?php esc_html_e( 'Submit Refund', 'easy-digital-downloads' ); ?></button>
|
||
|
</div>
|
||
|
<?php
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Displays the rows.
|
||
|
*
|
||
|
* This is overridden in order to add columns for the totals.
|
||
|
*
|
||
|
* @since 3.0
|
||
|
*/
|
||
|
public function display_rows() {
|
||
|
static $currency_symbol = null;
|
||
|
$order_id = false;
|
||
|
$currency_position = edd_get_option( 'currency_position', 'before' );
|
||
|
|
||
|
foreach ( $this->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.
|
||
|
?>
|
||
|
<tr id="edd-refund-submit-subtotal" class="edd-refund-submit-line-total">
|
||
|
<td colspan="<?php echo esc_attr( $this->get_column_count() ); ?>">
|
||
|
<span class="row-title edd-refund-submit-line-total-name"><?php esc_html_e( 'Refund Subtotal:', 'easy-digital-downloads' ); ?></span>
|
||
|
|
||
|
<?php
|
||
|
$currency_symbol_output = sprintf( '<span>%s</span>', $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(
|
||
|
'<span class="edd-refund-submit-line-total-amount">%1$s<span id="edd-refund-submit-subtotal-amount">%2$s</span>%3$s</span>',
|
||
|
$before, // phpcs:ignore
|
||
|
esc_attr( $amount ),
|
||
|
$after // phpcs:ignore
|
||
|
);
|
||
|
?>
|
||
|
</td>
|
||
|
</tr>
|
||
|
|
||
|
<?php
|
||
|
$order = $this->get_order();
|
||
|
if ( $order && $order->get_tax_rate() ) :
|
||
|
?>
|
||
|
<tr id="edd-refund-submit-tax" class="edd-refund-submit-line-total">
|
||
|
<td colspan="<?php echo esc_attr( $this->get_column_count() ); ?>">
|
||
|
<span class="row-title edd-refund-submit-line-total-name"><?php esc_html_e( 'Refund Tax Total:', 'easy-digital-downloads' ); ?></span>
|
||
|
|
||
|
<?php
|
||
|
printf(
|
||
|
'<span class="edd-refund-submit-line-total-amount">%1$s<span id="edd-refund-submit-tax-amount">%2$s</span>%3$s</span>',
|
||
|
$before, // phpcs:ignore
|
||
|
esc_attr( $amount ),
|
||
|
$after // phpcs:ignore
|
||
|
);
|
||
|
?>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<?php endif; ?>
|
||
|
|
||
|
<tr id="edd-refund-submit-total" class="edd-refund-submit-line-total">
|
||
|
<td colspan="<?php echo esc_attr( $this->get_column_count() ); ?>">
|
||
|
<span class="row-title edd-refund-submit-line-total-name"><?php esc_html_e( 'Refund Total:', 'easy-digital-downloads' ); ?></span>
|
||
|
|
||
|
<?php
|
||
|
printf(
|
||
|
'<span class="edd-refund-submit-line-total-amount">%1$s<span id="edd-refund-submit-total-amount">%2$s</span>%3$s</span>',
|
||
|
$before, // phpcs:ignore
|
||
|
esc_attr( $amount ),
|
||
|
$after // phpcs:ignore
|
||
|
);
|
||
|
?>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<?php
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the order object.
|
||
|
*
|
||
|
* @since 3.0
|
||
|
* @return Order|false
|
||
|
*/
|
||
|
private function get_order() {
|
||
|
$order_id = ! empty( $_POST['order_id'] )
|
||
|
? absint( $_POST['order_id'] ) // phpcs:ignore
|
||
|
: 0;
|
||
|
|
||
|
return ! empty( $order_id ) ? edd_get_order( $order_id ) : false;
|
||
|
}
|
||
|
}
|