Tweak variation display and reenable bulk editing

This commit is contained in:
Mike Jolley 2016-03-22 17:13:39 +00:00
parent 8d5b9b7b48
commit f73149feaf
11 changed files with 274 additions and 60 deletions

File diff suppressed because one or more lines are too long

View File

@ -917,6 +917,13 @@ ul.wc_coupon_list_block {
}
}
.wc-order-item-bulk-edit {
.cancel-action {
float: left;
margin-left: 0;
}
}
.add_meta {
margin-left: 0 !important;
}
@ -1016,6 +1023,19 @@ ul.wc_coupon_list_block {
}
}
tbody tr {
td {
cursor: pointer;
}
&.selected {
background: #F5EBF3;
td {
border-color: #E6CCE1;
opacity: 0.8;
}
}
}
tbody tr:last-child td {
border-bottom: 1px solid #dfdfdf;
}
@ -1031,6 +1051,7 @@ ul.wc_coupon_list_block {
td.thumb {
text-align: left;
width: 38px;
padding-bottom: 1.5em;
.wc-order-item-thumbnail {
width: 38px;
height: 38px;
@ -1059,9 +1080,11 @@ ul.wc_coupon_list_block {
}
}
td.name {
.wc-order-item-sku {
.wc-order-item-sku, .wc-order-item-variation {
display: block;
margin-top: .5em;
font-size: 0.92em !important;
color: #c8c8c8;
}
}
@ -1212,6 +1235,8 @@ ul.wc_coupon_list_block {
table.meta,
table.display_meta {
margin: .5em 0 0 0;
font-size: 0.92em !important;
color: #c8c8c8;
tr {
th {
@ -1219,7 +1244,6 @@ ul.wc_coupon_list_block {
padding: 0 4px .5em 0;
line-height: 1.5em;
width: 20%;
font-weight: normal;
}
td {
padding: 0 4px .5em 0;
@ -1271,7 +1295,7 @@ ul.wc_coupon_list_block {
&:before {
@include icon( "\e007" );
color: #bbbbbb;
color: #ccc;
}
}
}
@ -1286,7 +1310,7 @@ ul.wc_coupon_list_block {
&:before {
@include icon( "\e014" );
color: #bbbbbb;
color: #ccc;
}
}
}
@ -1301,7 +1325,7 @@ ul.wc_coupon_list_block {
&:before {
@include icon( "\e01a" );
color: #bbbbbb;
color: #ccc;
}
}
.shipping_method_name,

View File

@ -226,13 +226,17 @@ jQuery( function ( $ ) {
.on( 'click', 'button.add-order-fee', this.add_fee )
.on( 'click', 'button.add-order-shipping', this.add_shipping )
.on( 'click', 'button.add-order-tax', this.add_tax )
.on( 'click', 'input.check-column', this.bulk_actions.check_column )
.on( 'click', 'button.calculate-action', this.calculate_totals )
.on( 'click', 'button.save-action', this.save_line_items )
.on( 'click', 'a.delete-order-tax', this.delete_tax )
.on( 'click', 'button.calculate-tax-action', this.calculate_tax )
.on( 'click', 'a.edit-order-item', this.edit_item )
.on( 'click', 'a.delete-order-item', this.delete_item )
.on( 'click', 'tr.item, tr.fee, tr.shipping', this.select_row )
.on( 'click', 'tr.item :input, tr.fee :input, tr.shipping :input, tr.item a, tr.fee a, tr.shipping a', this.select_row_child )
.on( 'click', 'button.bulk-delete-items', this.bulk_actions.do_delete )
.on( 'click', 'button.bulk-increase-stock', this.bulk_actions.do_increase_stock )
.on( 'click', 'button.bulk-decrease-stock', this.bulk_actions.do_reduce_stock )
// Refunds
.on( 'click', '.delete_refund', this.refunds.delete_refund )
@ -355,13 +359,13 @@ jQuery( function ( $ ) {
add_line_item: function() {
$( 'div.wc-order-add-item' ).slideDown();
$( 'div.wc-order-bulk-actions' ).slideUp();
$( 'div.wc-order-data-row-toggle' ).not( 'div.wc-order-add-item' ).slideUp();
return false;
},
refund_items: function() {
$( 'div.wc-order-refund-items' ).slideDown();
$( 'div.wc-order-bulk-actions' ).slideUp();
$( 'div.wc-order-data-row-toggle' ).not( 'div.wc-order-refund-items' ).slideUp();
$( 'div.wc-order-totals-items' ).slideUp();
$( '#woocommerce-order-items' ).find( 'div.refund' ).show();
$( '.wc-order-edit-line-item .wc-order-edit-line-item-actions' ).hide();
@ -369,7 +373,7 @@ jQuery( function ( $ ) {
},
cancel: function() {
$( this ).closest( 'div.wc-order-data-row' ).slideUp();
$( 'div.wc-order-data-row-toggle' ).not( 'div.wc-order-bulk-actions' ).slideUp();
$( 'div.wc-order-bulk-actions' ).slideDown();
$( 'div.wc-order-totals-items' ).slideDown();
$( '#woocommerce-order-items' ).find( 'div.refund' ).hide();
@ -853,21 +857,49 @@ jQuery( function ( $ ) {
}
},
select_row: function() {
var $row = false;
if ( $( this ).is( 'tr' ) ) {
$row = $( this );
} else {
$row = $( this ).closest('tr');
}
var $table = $( this ).closest('table');
if ( $row.is( '.selected' ) ) {
$row.removeClass('selected');
} else {
$row.addClass('selected');
}
var $rows = $table.find('tr.selected');
if ( $rows.length ) {
$( 'div.wc-order-item-bulk-edit' ).slideDown();
} else {
$( 'div.wc-order-item-bulk-edit' ).slideUp();
}
},
select_row_child: function( e ) {
e.stopPropagation();
},
bulk_actions: {
check_column: function() {
if ( $( this ).is( ':checked' ) ) {
$( '#woocommerce-order-items' ).find( '.check-column input' ).attr( 'checked', 'checked' );
} else {
$( '#woocommerce-order-items' ).find( '.check-column input' ).removeAttr( 'checked' );
}
},
do_delete: function( e ) {
e.preventDefault();
var $table = $( 'table.woocommerce_order_items' );
var $rows = $table.find('tr.selected');
do_delete: function( selected_rows, item_ids ) {
if ( window.confirm( woocommerce_admin_meta_boxes.remove_item_notice ) ) {
if ( $rows.length && window.confirm( woocommerce_admin_meta_boxes.remove_item_notice ) ) {
wc_meta_boxes_order_items.block();
var item_ids = $.map( $rows, function( $row ) {
return parseInt( $( $row ).data( 'order_item_id' ), 10 );
});
var data = {
order_item_ids: item_ids,
action: 'woocommerce_remove_order_item',
@ -879,13 +911,85 @@ jQuery( function ( $ ) {
data: data,
type: 'POST',
success: function() {
$( selected_rows ).each(function() {
$( this ).closest( 'tr' ).remove();
$rows.each(function() {
$( this ).remove();
});
wc_meta_boxes_order_items.unblock();
}
});
}
},
do_increase_stock: function( e ) {
e.preventDefault();
wc_meta_boxes_order_items.block();
var $table = $( 'table.woocommerce_order_items' );
var $rows = $table.find('tr.selected');
var quantities = {};
var item_ids = $.map( $rows, function( $row ) {
return parseInt( $( $row ).data( 'order_item_id' ), 10 );
});
$rows.each(function() {
if ( $( this ).find( 'input.quantity' ).length ) {
quantities[ $( this ).attr( 'data-order_item_id' ) ] = $( this ).find( 'input.quantity' ).val();
}
});
var data = {
order_id: woocommerce_admin_meta_boxes.post_id,
order_item_ids: item_ids,
order_item_qty: quantities,
action: 'woocommerce_increase_order_item_stock',
security: woocommerce_admin_meta_boxes.order_item_nonce
};
$.ajax({
url: woocommerce_admin_meta_boxes.ajax_url,
data: data,
type: 'POST',
success: function( response ) {
window.alert( response );
wc_meta_boxes_order_items.unblock();
}
});
},
do_reduce_stock: function( e ) {
e.preventDefault();
wc_meta_boxes_order_items.block();
var $table = $( 'table.woocommerce_order_items' );
var $rows = $table.find('tr.selected');
var quantities = {};
var item_ids = $.map( $rows, function( $row ) {
return parseInt( $( $row ).data( 'order_item_id' ), 10 );
});
$rows.each(function() {
if ( $( this ).find( 'input.quantity' ).length ) {
quantities[ $( this ).attr( 'data-order_item_id' ) ] = $( this ).find( 'input.quantity' ).val();
}
});
var data = {
order_id: woocommerce_admin_meta_boxes.post_id,
order_item_ids: item_ids,
order_item_qty: quantities,
action: 'woocommerce_reduce_order_item_stock',
security: woocommerce_admin_meta_boxes.order_item_nonce
};
$.ajax({
url: woocommerce_admin_meta_boxes.ajax_url,
data: data,
type: 'POST',
success: function( response ) {
window.alert( response );
wc_meta_boxes_order_items.unblock();
}
});
}
},

File diff suppressed because one or more lines are too long

View File

@ -209,8 +209,9 @@ abstract class WC_Shipping_Method extends WC_Settings_API {
/**
* Add a shipping rate. If taxes are not set they will be calculated based on cost.
* @param array $args (default: array())
* @param array $package option to store information about the package in meta.
*/
public function add_rate( $args = array() ) {
public function add_rate( $args = array(), $package = false ) {
$args = wp_parse_args( $args, array(
'id' => '', // ID for the rate
'label' => '', // Label for the rate
@ -246,6 +247,16 @@ abstract class WC_Shipping_Method extends WC_Settings_API {
}
}
// Store package data
if ( $package ) {
$items_in_package = array();
foreach ( $package['contents'] as $item ) {
$product = $item['data'];
$items_in_package[] = $product->get_title() . ' × ' . $item['quantity'];
}
$rate->add_meta_data( __( 'Items', 'woocommerce' ), implode( ', ', $items_in_package ) );
}
$this->rates[ $args['id'] ] = $rate;
}

View File

@ -10,8 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$product_link = $_product ? admin_url( 'post.php?post =' . absint( $_product->id ) . '&action =edit' ) : '';
$thumbnail = $_product ? apply_filters( 'woocommerce_admin_order_item_thumbnail', $_product->get_image( 'shop_thumbnail', array( 'title' => '' ), false ), $item_id, $item ) : '';
$tooltip = _wc_get_order_item_tooltip_content( $item, $_product );
$thumbnail = $_product ? apply_filters( 'woocommerce_admin_order_item_thumbnail', $_product->get_image( 'thumbnail', array( 'title' => '' ), false ), $item_id, $item ) : '';
$tax_data = empty( $legacy_order ) && wc_tax_enabled() ? maybe_unserialize( isset( $item['line_tax_data'] ) ? $item['line_tax_data'] : '' ) : false;
$item_total = ( isset( $item['line_total'] ) ) ? esc_attr( wc_format_localized_price( $item['line_total'] ) ) : '';
$item_subtotal = ( isset( $item['line_subtotal'] ) ) ? esc_attr( wc_format_localized_price( $item['line_subtotal'] ) ) : '';
@ -19,16 +18,27 @@ $item_subtotal = ( isset( $item['line_subtotal'] ) ) ? esc_attr( wc_format_local
<tr class="item <?php echo apply_filters( 'woocommerce_admin_html_order_item_class', ( ! empty( $class ) ? $class : '' ), $item ); ?>" data-order_item_id="<?php echo $item_id; ?>">
<td class="thumb">
<?php
echo $product_link ? '<a href="' . esc_url( $product_link ) . '" class="wc-order-item-thumbnail tips" data-tip="' . esc_attr( $tooltip ) . '">' : '<div class="wc-order-item-thumbnail tips" data-tip="' . esc_attr( $tooltip ) . '">';
echo wp_kses_post( $thumbnail );
echo $product_link ? '</a>' : '</div>';
echo '<div class="wc-order-item-thumbnail">' . wp_kses_post( $thumbnail ) . '</div>';
?>
</td>
<td class="name" data-sort-value="<?php echo esc_attr( $item['name'] ); ?>">
<?php
echo $product_link ? '<a href="' . esc_url( $product_link ) . '" class="wc-order-item-name">' . esc_html( $item['name'] ) . '</a>' : '<div class="class="wc-order-item-name"">' . esc_html( $item['name'] ) . '</div>';
echo $_product && $_product->get_sku() ? '<div class="wc-order-item-sku">' . __( 'SKU:', 'woocommerce' ) . ' ' . esc_html( $_product->get_sku() ) . '</div>' : ''; ?>
if ( $_product && $_product->get_sku() ) {
echo '<div class="wc-order-item-sku"><strong>' . __( 'SKU:', 'woocommerce' ) . '</strong> ' . esc_html( $_product->get_sku() ) . '</div>';
}
if ( ! empty( $item['variation_id'] ) ) {
echo '<div class="wc-order-item-variation"><strong>' . __( 'Variation ID:', 'woocommerce' ) . '</strong> ';
if ( ! empty( $item['variation_id'] ) && 'product_variation' === get_post_type( $item['variation_id'] ) ) {
echo esc_html( $item['variation_id'] );
} elseif ( ! empty( $item['variation_id'] ) ) {
echo esc_html( $item['variation_id'] ) . ' (' . __( 'No longer exists', 'woocommerce' ) . ')';
}
echo '</div>';
}
?>
<input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr( $item_id ); ?>" />
<input type="hidden" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" value="<?php echo isset( $item['tax_class'] ) ? esc_attr( $item['tax_class'] ) : ''; ?>" />

View File

@ -116,6 +116,11 @@ if ( wc_tax_enabled() ) {
</tbody>
</table>
</div>
<div class="wc-order-data-row wc-order-item-bulk-edit" style="display:none;">
<button type="button" class="button bulk-delete-items"><?php _e( 'Delete selected row(s)', 'woocommerce' ); ?></button>
<button type="button" class="button bulk-decrease-stock"><?php _e( 'Reduce stock', 'woocommerce' ); ?></button>
<button type="button" class="button bulk-increase-stock"><?php _e( 'Increase stock', 'woocommerce' ); ?></button>
</div>
<div class="wc-order-data-row wc-order-totals-items wc-order-items-editable">
<?php
$coupons = $order->get_items( array( 'coupon' ) );
@ -210,15 +215,15 @@ if ( wc_tax_enabled() ) {
</table>
<div class="clear"></div>
</div>
<div class="wc-order-data-row wc-order-bulk-actions">
<div class="wc-order-data-row wc-order-bulk-actions wc-order-data-row-toggle">
<p class="add-items">
<?php if ( $order->is_editable() ) : ?>
<button type="button" class="button add-line-item"><?php _e( 'Add line item(s)', 'woocommerce' ); ?></button>
<button type="button" class="button add-line-item"><?php _e( 'Add item(s)', 'woocommerce' ); ?></button>
<?php else : ?>
<span class="description tips" data-tip="<?php esc_attr_e( 'To edit this order change the status back to "Pending"', 'woocommerce' ); ?>"><?php _e( 'This order has been paid for and is no longer editable', 'woocommerce' ); ?></span>
<?php endif; ?>
<?php if ( wc_tax_enabled() && $order->is_editable() ) : ?>
<button type="button" class="button add-order-tax"><?php _e( 'Add Tax', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-tax"><?php _e( 'Add tax', 'woocommerce' ); ?></button>
<?php endif; ?>
<?php if ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?>
<button type="button" class="button refund-items"><?php _e( 'Refund', 'woocommerce' ); ?></button>
@ -233,7 +238,7 @@ if ( wc_tax_enabled() ) {
<?php endif; ?>
</p>
</div>
<div class="wc-order-data-row wc-order-add-item" style="display:none;">
<div class="wc-order-data-row wc-order-add-item wc-order-data-row-toggle" style="display:none;">
<button type="button" class="button add-order-item"><?php _e( 'Add product(s)', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-fee"><?php _e( 'Add fee', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-shipping"><?php _e( 'Add shipping cost', 'woocommerce' ); ?></button>
@ -245,7 +250,7 @@ if ( wc_tax_enabled() ) {
?>
</div>
<?php if ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?>
<div class="wc-order-data-row wc-order-refund-items" style="display: none;">
<div class="wc-order-data-row wc-order-refund-items wc-order-data-row-toggle" style="display: none;">
<table class="wc-order-totals">
<tr style="display:none;">
<td class="label"><label for="restock_refunded_items"><?php _e( 'Restock refunded items', 'woocommerce' ); ?>:</label></td>

View File

@ -117,6 +117,8 @@ class WC_AJAX {
'add_order_tax' => false,
'remove_order_item' => false,
'remove_order_tax' => false,
'reduce_order_item_stock' => false,
'increase_order_item_stock' => false,
'add_order_item_meta' => false,
'remove_order_item_meta' => false,
'calc_line_taxes' => false,
@ -1353,7 +1355,87 @@ class WC_AJAX {
die();
}
/**
* Reduce order item stock.
*/
public static function reduce_order_item_stock() {
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
$order_id = absint( $_POST['order_id'] );
$order_item_ids = isset( $_POST['order_item_ids'] ) ? $_POST['order_item_ids'] : array();
$order_item_qty = isset( $_POST['order_item_qty'] ) ? $_POST['order_item_qty'] : array();
$order = wc_get_order( $order_id );
$order_items = $order->get_items();
$return = array();
if ( $order && ! empty( $order_items ) && sizeof( $order_item_ids ) > 0 ) {
foreach ( $order_items as $item_id => $order_item ) {
// Only reduce checked items
if ( ! in_array( $item_id, $order_item_ids ) ) {
continue;
}
$_product = $order->get_product_from_item( $order_item );
if ( $_product->exists() && $_product->managing_stock() && isset( $order_item_qty[ $item_id ] ) && $order_item_qty[ $item_id ] > 0 ) {
$stock_change = apply_filters( 'woocommerce_reduce_order_stock_quantity', $order_item_qty[ $item_id ], $item_id );
$new_stock = $_product->reduce_stock( $stock_change );
$item_name = $_product->get_sku() ? $_product->get_sku() : $order_item['product_id'];
$note = sprintf( __( 'Item %s stock reduced from %s to %s.', 'woocommerce' ), $item_name, $new_stock + $stock_change, $new_stock );
$return[] = $note;
$order->add_order_note( $note );
$order->send_stock_notifications( $_product, $new_stock, $order_item_qty[ $item_id ] );
}
}
do_action( 'woocommerce_reduce_order_stock', $order );
if ( empty( $return ) ) {
$return[] = __( 'No products had their stock reduced - they may not have stock management enabled.', 'woocommerce' );
}
echo implode( ', ', $return );
}
die();
}
/**
* Increase order item stock.
*/
public static function increase_order_item_stock() {
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
$order_id = absint( $_POST['order_id'] );
$order_item_ids = isset( $_POST['order_item_ids'] ) ? $_POST['order_item_ids'] : array();
$order_item_qty = isset( $_POST['order_item_qty'] ) ? $_POST['order_item_qty'] : array();
$order = wc_get_order( $order_id );
$order_items = $order->get_items();
$return = array();
if ( $order && ! empty( $order_items ) && sizeof( $order_item_ids ) > 0 ) {
foreach ( $order_items as $item_id => $order_item ) {
// Only reduce checked items
if ( ! in_array( $item_id, $order_item_ids ) ) {
continue;
}
$_product = $order->get_product_from_item( $order_item );
if ( $_product->exists() && $_product->managing_stock() && isset( $order_item_qty[ $item_id ] ) && $order_item_qty[ $item_id ] > 0 ) {
$old_stock = $_product->get_stock_quantity();
$stock_change = apply_filters( 'woocommerce_restore_order_stock_quantity', $order_item_qty[ $item_id ], $item_id );
$new_quantity = $_product->increase_stock( $stock_change );
$item_name = $_product->get_sku() ? $_product->get_sku(): $order_item['product_id'];
$note = sprintf( __( 'Item %s stock increased from %s to %s.', 'woocommerce' ), $item_name, $old_stock, $new_quantity );
$return[] = $note;
$order->add_order_note( $note );
}
}
do_action( 'woocommerce_restore_order_stock', $order );
if ( empty( $return ) ) {
$return[] = __( 'No products had their stock increased - they may not have stock management enabled.', 'woocommerce' );
}
echo implode( ', ', $return );
}
die();
}
/**
* Add some meta to a line item.
*/

View File

@ -171,7 +171,7 @@ class WC_Shipping_Flat_Rate extends WC_Shipping_Method {
// Add the rate
if ( $has_costs ) {
$this->add_rate( $rate );
$this->add_rate( $rate, $package );
}
/**

View File

@ -189,7 +189,7 @@ class WC_Shipping_Legacy_Flat_Rate extends WC_Shipping_Method {
// Add the rate
if ( $has_costs ) {
$this->add_rate( $rate );
$this->add_rate( $rate, $package );
}
/**
@ -279,7 +279,7 @@ class WC_Shipping_Legacy_Flat_Rate extends WC_Shipping_Method {
} else {
$extra_rate['cost'] += $extra_cost;
}
$this->add_rate( $extra_rate );
$this->add_rate( $extra_rate, $package );
}
}
}

View File

@ -971,25 +971,3 @@ function wc_order_fully_refunded( $order_id ) {
wc_delete_shop_order_transients( $order_id );
}
add_action( 'woocommerce_order_status_refunded', 'wc_order_fully_refunded' );
/**
* Get tooltip content for admin panel. For internal use only.
* @param object $item
* @return string
*/
function _wc_get_order_item_tooltip_content( $item, $_product ) {
if ( ! empty( $item['product_id'] ) ) {
$tooltip = '<strong>' . __( 'Product ID:', 'woocommerce' ) . '</strong> ' . esc_html( $item['product_id'] );
} else {
$tooltip = __( 'This product has no ID', 'woocommerce' );
}
if ( ! empty( $item['variation_id'] ) && 'product_variation' === get_post_type( $item['variation_id'] ) ) {
$tooltip .= '<br/><strong>' . __( 'Variation ID:', 'woocommerce' ) . '</strong> ' . esc_html( $item['variation_id'] );
} elseif ( ! empty( $item['variation_id'] ) ) {
$tooltip .= '<br/><strong>' . __( 'Variation ID:', 'woocommerce' ) . '</strong> ' . esc_html( $item['variation_id'] ) . ' (' . __( 'No longer exists', 'woocommerce' ) . ')';
}
$tooltip .= isset( $_product->variation_data ) ? '<br/>' . wc_get_formatted_variation( $_product->variation_data, true ) : '';
return $tooltip;
}