initial implementation of order items taxes

This commit is contained in:
claudiosmweb 2014-07-19 01:08:02 -03:00
parent 50113fa531
commit 93cf3c88bd
11 changed files with 137 additions and 136 deletions

File diff suppressed because one or more lines are too long

View File

@ -766,6 +766,9 @@ ul.wc_coupon_list_block {
font-size: 1em;
}
}
th.line_tax {
white-space: nowrap;
}
.quantity {
text-align: center;
input {

View File

@ -123,6 +123,17 @@ abstract class WC_Abstract_Order {
wc_add_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( isset( $args['totals']['subtotal_tax'] ) ? $args['totals']['subtotal_tax'] : 0 ) );
wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( isset( $args['totals']['tax'] ) ? $args['totals']['tax'] : 0 ) );
// Save tax data - Since 2.2
if ( isset( $args['totals']['tax_data'] ) ) {
$tax_data = array();
$tax_data['total'] = array_map( 'wc_format_decimal', $args['totals']['tax_data']['total'] );
$tax_data['subtotal'] = array_map( 'wc_format_decimal', $args['totals']['tax_data']['subtotal'] );
wc_add_order_item_meta( $item_id, '_line_tax_data', $tax_data );
} else {
wc_add_order_item_meta( $item_id, '_line_tax_data', array( 'total' => array(), 'subtotal' => array() ) );
}
// Add variation meta
if ( ! empty( $args['variation'] ) ) {
foreach ( $args['variation'] as $key => $value ) {

View File

@ -18,41 +18,6 @@ if ( ! defined( 'ABSPATH' ) ) {
</div>
</td>
<?php if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) :
$tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option( 'woocommerce_tax_classes' ) ) ) );
$classes_options = array();
$classes_options[''] = __( 'Standard', 'woocommerce' );
$tax_class = isset( $item['tax_class'] ) ? sanitize_title( $item['tax_class'] ) : '';
if ( $tax_classes ) {
foreach ( $tax_classes as $class ) {
$classes_options[ sanitize_title( $class ) ] = $class;
}
}
?>
<td class="tax_class" width="1%">
<div class="view">
<?php
$item_value = isset( $classes_options[ $tax_class ] ) ? esc_attr( $classes_options[ $tax_class ] ) : '';
echo $item_value ? $item_value : __( 'Standard', 'woocommerce' );
?>
</div>
<div class="edit" style="display:none">
<select class="tax_class" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" title="<?php _e( 'Tax class', 'woocommerce' ); ?>">
<option value="0" <?php selected( 0, $tax_class ) ?>><?php _e( 'N/A', 'woocommerce' ); ?></option>
<optgroup label="<?php _e( 'Taxable', 'woocommerce' ); ?>">
<?php
foreach ( $classes_options as $value => $name ) {
echo '<option value="' . esc_attr( $value ) . '" ' . selected( $value, $tax_class, false ) . '>'. esc_html( $name ) . '</option>';
}
?>
</optgroup>
</select>
</div>
</td>
<?php endif; ?>
<td class="quantity" width="1%">1</td>
<td class="line_cost" width="1%">
@ -64,6 +29,8 @@ if ( ! defined( 'ABSPATH' ) ) {
</div>
</td>
<?php if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) : ?>
<td class="line_tax" width="1%">

View File

@ -95,7 +95,7 @@ if ( ! defined( 'ABSPATH' ) ) {
}
?>
</div>
<div class="edit" style="display:none">
<div class="edit" style="display: none;">
<table class="meta" cellspacing="0">
<tfoot>
<tr>
@ -147,42 +147,11 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php do_action( 'woocommerce_admin_order_item_values', $_product, $item, absint( $item_id ) ); ?>
<?php if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) :
$tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('woocommerce_tax_classes' ) ) ) );
$classes_options = array();
$classes_options[''] = __( 'Standard', 'woocommerce' );
if ( $tax_classes ) {
foreach ( $tax_classes as $class ) {
$classes_options[ sanitize_title( $class ) ] = $class;
}
}
?>
<td class="tax_class" width="1%">
<div class="view">
<?php
$item_value = isset( $item['tax_class'] ) ? sanitize_title( $item['tax_class'] ) : '';
echo $classes_options[ $item_value ];
?>
</div>
<div class="edit" style="display:none">
<select class="tax_class" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" title="<?php _e( 'Tax class', 'woocommerce' ); ?>">
<?php
$item_value = isset( $item['tax_class'] ) ? sanitize_title( $item['tax_class'] ) : '';
foreach ( $classes_options as $value => $name )
echo '<option value="' . esc_attr( $value ) . '" ' . selected( $value, $item_value, false ) . '>' . esc_html( $name ) . '</option>';
?>
</select>
</div>
</td>
<?php endif; ?>
<td class="quantity" width="1%">
<div class="view">
<?php echo ( isset( $item['qty'] ) ) ? esc_html( $item['qty'] ) : ''; ?>
</div>
<div class="edit" style="display:none">
<div class="edit" style="display: none;">
<input type="number" step="<?php echo apply_filters( 'woocommerce_quantity_input_step', '1', $_product ); ?>" min="0" autocomplete="off" name="order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" value="<?php echo esc_attr( $item['qty'] ); ?>" size="4" class="quantity" />
</div>
</td>
@ -199,37 +168,47 @@ if ( ! defined( 'ABSPATH' ) ) {
}
?>
</div>
<div class="edit" style="display:none">
<div class="edit" style="display: none;">
<span class="subtotal"><label><?php _e( 'Subtotal', 'woocommerce' ); ?>: <a class="tips" data-tip="<?php _e( 'Before pre-tax discounts.', 'woocommerce' ); ?>" href="#">[?]</a> <input type="text" name="line_subtotal[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $item['line_subtotal'] ) ) ? esc_attr( wc_format_localized_price( $item['line_subtotal'] ) ) : ''; ?>" class="line_subtotal wc_input_price" /></label></span>
<label><?php _e( 'Total', 'woocommerce' ); ?>: <a class="tips" data-tip="<?php _e( 'After pre-tax discounts.', 'woocommerce' ); ?>" href="#">[?]</a> <input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $item['line_total'] ) ) ? esc_attr( wc_format_localized_price( $item['line_total'] ) ) : ''; ?>" class="line_total wc_input_price" /></label>
</div>
</td>
<?php if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) : ?>
<?php
if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) :
$tax_data = maybe_unserialize( $item['line_tax_data'] );
foreach ( $order_taxes as $tax_item ) :
$tax_item_id = $tax_item['rate_id'];
$tax_item_total = isset( $tax_data['total'][ $tax_item_id ] ) ? $tax_data['total'][ $tax_item_id ] : '';
$tax_item_subtotal = isset( $tax_data['subtotal'][ $tax_item_id ] ) ? $tax_data['subtotal'][ $tax_item_id ] : '';
?>
<td class="line_tax" width="1%">
<div class="view">
<?php
if ( isset( $item['line_tax'] ) ) {
if ( isset( $item['line_subtotal_tax'] ) && $item['line_subtotal_tax'] != $item['line_tax'] ) {
echo '<del>' . wc_price( wc_round_tax_total( $item['line_subtotal_tax'] ) ) . '</del> ';
if ( '' != $tax_item_total ) {
if ( isset( $tax_item_subtotal ) && $tax_item_subtotal != $tax_item_total ) {
echo '<del>' . wc_price( wc_round_tax_total( $tax_item_subtotal ) ) . '</del> ';
}
echo wc_price( wc_round_tax_total( $item['line_tax'] ) );
echo wc_price( wc_round_tax_total( $tax_item_total ) );
}
?>
</div>
<div class="edit" style="display:none">
<span class="subtotal"><input type="text" name="line_subtotal_tax[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $item['line_subtotal_tax'] ) ) ? esc_attr( wc_format_localized_price( $item['line_subtotal_tax'] ) ) : ''; ?>" class="line_subtotal_tax wc_input_price" /></span>
<div class="edit" style="display: none;">
<span class="subtotal"><input type="text" name="line_subtotal_tax[<?php echo absint( $item_id ); ?>][<?php echo absint( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_subtotal ) ) ? esc_attr( wc_format_localized_price( $tax_item_subtotal ) ) : ''; ?>" class="line_subtotal_tax wc_input_price" /></span>
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $item['line_tax'] ) ) ? esc_attr( wc_format_localized_price( $item['line_tax'] ) ) : ''; ?>" class="line_tax wc_input_price" />
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo absint( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
</div>
</td>
<?php endif; ?>
<?php
endforeach;
endif;
?>
<td class="wc-order-item-refund-quantity" width="1%" style="display:none">
<td class="wc-order-item-refund-quantity" width="1%" style="display: none;">
<input type="number" step="<?php echo apply_filters( 'woocommerce_quantity_input_step', '1', $_product ); ?>" min="0" max="<?php echo esc_attr( $item['qty'] ); ?>" autocomplete="off" name="order_item_refund_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" size="4" class="quantity" />
</td>

View File

@ -2,6 +2,20 @@
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) {
$order_taxes = $order->get_taxes();
$tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option( 'woocommerce_tax_classes' ) ) ) );
$classes_options = array();
$classes_options[''] = __( 'Standard', 'woocommerce' );
if ( $tax_classes ) {
foreach ( $tax_classes as $class ) {
$classes_options[ sanitize_title( $class ) ] = $class;
}
}
}
?>
<div class="woocommerce_order_items_wrapper wc-order-items-editable">
<table cellpadding="0" cellspacing="0" class="woocommerce_order_items">
@ -12,19 +26,27 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php do_action( 'woocommerce_admin_order_item_headers' ); ?>
<?php if ( get_option( 'woocommerce_calc_taxes' ) == 'yes' ) : ?>
<th class="tax_class"><?php _e( 'Tax&nbsp;Class', 'woocommerce' ); ?></th>
<?php endif; ?>
<th class="quantity"><?php _e( 'Qty', 'woocommerce' ); ?></th>
<th class="line_cost"><?php _e( 'Total', 'woocommerce' ); ?></th>
<?php if ( get_option( 'woocommerce_calc_taxes' ) == 'yes' ) : ?>
<th class="line_tax"><?php _e( 'Tax', 'woocommerce' ); ?></th>
<?php endif; ?>
<?php
if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) :
foreach ( $order_taxes as $tax_item ) :
$tax_class = wc_get_tax_class_by_tax_id( $tax_item['rate_id'] );
$tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'woocommerce' );
?>
<th class="wc-order-item-refund-quantity" style="display:none"><?php _e( 'Refund', 'woocommerce' ); ?></th>
<th class="line_tax"><?php echo esc_attr( $tax_class_name ); ?> <span class="tips" data-tip="<?php
echo esc_attr( $tax_item['label'] . ' (' . $tax_item['name'] . ')' );
?>">[?]</span></th>
<?php
endforeach;
endif;
?>
<th class="wc-order-item-refund-quantity" style="display: none;"><?php _e( 'Refund', 'woocommerce' ); ?></th>
<th class="wc-order-edit-line-item" width="1%">&nbsp;</th>
</tr>
@ -37,7 +59,6 @@ if ( ! defined( 'ABSPATH' ) ) {
$shipping_methods = WC()->shipping() ? WC()->shipping->load_shipping_methods() : array();
foreach ( $order_items as $item_id => $item ) {
switch ( $item['type'] ) {
case 'line_item' :
$_product = $order->get_product_from_item( $item );
@ -137,6 +158,9 @@ if ( ! defined( 'ABSPATH' ) ) {
<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>
<?php if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) : ?>
<button type="button" class="button add-order-tax"><?php _e( 'Add Tax', 'woocommerce' ); ?></button>
<?php endif; ?>
<button type="button" class="button cancel-action"><?php _e( 'Cancel', 'woocommerce' ); ?></button>
<button type="button" class="button button-primary save-action"><?php _e( 'Save', 'woocommerce' ); ?></button>
</div>

View File

@ -31,12 +31,6 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="hidden" class="order_refund_id" name="order_refund_id[]" value="<?php echo esc_attr( $refund->id ); ?>" />
</td>
<?php if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) : ?>
<td class="tax_class" width="1%"></td>
<?php endif; ?>
<td class="quantity" width="1%">1</td>
<td class="line_cost" width="1%">

View File

@ -43,12 +43,6 @@ if ( ! defined( 'ABSPATH' ) ) {
</div>
</td>
<?php if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) : ?>
<td class="tax_class" width="1%"></td>
<?php endif; ?>
<td class="quantity" width="1%">1</td>
<td class="line_cost" width="1%">
@ -60,11 +54,17 @@ if ( ! defined( 'ABSPATH' ) ) {
</div>
</td>
<?php if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) : ?>
<?php
if ( 'yes' == get_option( 'woocommerce_calc_taxes' ) ) :
for ( $i = 0; $i < count( $order_taxes ); $i++ ) :
?>
<td class="line_tax" width="1%"></td>
<?php endif; ?>
<?php
endfor;
endif;
?>
<td class="wc-order-item-refund-quantity" width="1%" style="display:none"></td>

View File

@ -1100,6 +1100,10 @@ class WC_Cart {
$base_price = $_product->get_price();
$line_price = $_product->get_price() * $values['quantity'];
// Tax data
$taxes = array();
$discounted_taxes = array();
/**
* No tax to calculate
*/
@ -1208,6 +1212,9 @@ class WC_Cart {
$this->cart_contents[ $cart_item_key ]['line_tax'] = $line_tax;
$this->cart_contents[ $cart_item_key ]['line_subtotal'] = $line_subtotal;
$this->cart_contents[ $cart_item_key ]['line_subtotal_tax'] = $line_subtotal_tax;
// Store rates ID and costs - Since 2.2
$this->cart_contents[ $cart_item_key ]['line_tax_data'] = array( 'total' => $taxes, 'subtotal' => $discounted_taxes );
}
// Only calculate the grand total + shipping if on the cart/checkout

View File

@ -213,7 +213,8 @@ class WC_Checkout {
'subtotal' => $values['line_subtotal'],
'subtotal_tax' => $values['line_subtotal_tax'],
'total' => $values['line_total'],
'tax' => $values['line_tax']
'tax' => $values['line_tax'],
'tax_data' => $values['line_tax_data'] // Since 2.2
)
)
);

View File

@ -570,3 +570,18 @@ function wc_create_refund( $args = array() ) {
return new WC_Order_Refund( $refund_id );
}
/**
* Get tax class by tax id.
*
* @since 2.2
* @param int $tax_id
* @return string
*/
function wc_get_tax_class_by_tax_id( $tax_id ) {
global $wpdb;
$tax_class = $wpdb->get_var( $wpdb->prepare( "SELECT tax_rate_class FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %d", $tax_id ) );
return wc_clean( $tax_class );
}