How to give a unique style to a fee on WooCommerce - css

I created a custom fee on Woocommerce based on a user plan. I did something like this on my functions.php:
function my_discount_based_on_user_membership( $cart ) {
$discount = 10;
$cart->add_fee( "My Discount", -$discount );
}
add_action( 'woocommerce_cart_calculate_fees', 'my_discount_based_on_user_membership', 20, 1 );
Let's say that this fee has the value of -$10. I want that -$10 have another color, like red for example. Is there a way of set a CSS class for a custom fee in Woocommerce? How can I target this element?
Since I could have another discounts later, target the element position using JS or CSS probably is not a good idea. Any advice?

To give a unique style to a fee in WooCommerce
Use CSS
.fee bdi {
color: red;
}
OR
You could overwrite the cart/cart-totals.php template file
This template can be overridden copying it to yourtheme/woocommerce/cart/cart-totals.php.
Replace (line 61 #version 2.3.6)
<td data-title="<?php echo esc_attr( $fee->name ); ?>"><?php wc_cart_totals_fee_html( $fee ); ?></td>
With
<td style="color:red;" data-title="<?php echo esc_attr( $fee->name ); ?>"><?php wc_cart_totals_fee_html( $fee ); ?></td>
AND
the checkout/review-order.php file
This template can be overridden by copying it to yourtheme/woocommerce/checkout/review-order.php.
Replace (line 80 #version 5.2.0)
<td><?php wc_cart_totals_fee_html( $fee ); ?></td>
With
<td style="color:red;"><?php wc_cart_totals_fee_html( $fee ); ?></td>
Note: instead of using inline CSS,
when overwriting the template files. You can also add a custom class instead <td class="my-class"...

Related

Woocommerce - Display full price (incl. tax) in admin order summary

I wish to display the full price that the customer paid for the item, rather than 'price without tax' and 'tax'.
I followed this: Woocommerce - Admin Order Detail Page and it almost gets me what I want, however it is not perfect to my case and I am failing to modify it. I am not very experienced in PHP and worried about breaking anything as it is a live webshop.
I managed to change the currency sign easily enough and put it at the end of the price rather than the start, but there's a couple of other things I wish to change and I'm not sure how/where.
We use commas instead of periods as decimal points. This is reflected without a problem everywhere else, but not with this custom snippet. How do I change this?
In the case of free item/shipping, this is empty. I tried to change "if $val>0" to just "if $val" but it made no difference.
I'd like this entire column to be on the right (as the last column) rather than on the left. So it reads Quantity, Total, Tax, Total incl. Tax.
Here is my current, slightly modified code:
function action_woocommerce_admin_order_item_values( $null, $item, $absint ) {
$val = ($item['type'] == 'line_item' || $item['type'] == 'shipping') ? $item['total'] + $item['total_tax'] : ' ';
$valdecimal = wc_format_decimal( $val, $dp='', $trim_zeros );
?>
<td class="item_fcost" data-sort-value="<?php echo $val; ?>">
<div class="view" style="font-weight: bold; text-align: right; padding-right: 10px;">
<?php if ($val) echo $valdecimal; echo ' DKK'; ?>
</div>
</td>
<?php
};
add_action( 'woocommerce_admin_order_item_values', 'action_woocommerce_admin_order_item_values', 10, 3 );
function action_woocommerce_admin_order_item_headers( $order ) {
echo '<th class="item_fcost sortable" data-sort="float" style="text-align: right;">Pris inkl. moms</th>';
};
add_action( 'woocommerce_admin_order_item_headers', 'action_woocommerce_admin_order_item_headers', 10, 3 );
Edit: I found out that this code also breaks/throws a fatal error with refunded orders. I've had to deactivate the code entirely.
I'm not experienced enough to know how to modify it and am still looking for help.
There was a little problem in your code and that's that you were accesing the $item as it was an array while it's actually an object. One of the objects extending the WC_Order_Item abstract classes. Also, the total and total_tax properties of $item are strings, not numbers so when you are adding them together, you first need to convert them to floats.
Lastly, I reasearched how the total is displayed by Woocommerce and they include the refunded total too. So I added the refunded total including VAT/tax too.
You can find updated code below.
function action_woocommerce_admin_order_item_values( $null, WC_Order_Item $item) {
$val = floatval($item->get_total()) + floatval($item->get_total_tax());
?>
<td class="item_full_cost" data-sort-value="<?= $val ?>">
<div class="view" style="font-weight: bold; text-align: right; padding-right: 10px;">
<?= wc_price($val, ['currency' => $item->get_order()->get_currency()]) ?>
</div>
<?php
$refunded = $item->get_order()->get_total_refunded_for_item( $item->get_id() );
if ( $refunded ) {
echo '<small class="refunded">-' . wc_price( $refunded, array( 'currency' => $item->get_order()->get_currency() ) ) . '</small>';
}
?>
</td>
<?php
};
add_action( 'woocommerce_admin_order_item_values', 'action_woocommerce_admin_order_item_values', 10, 2 );
function action_woocommerce_admin_order_item_headers( $order ) {
echo '<th class="line_full_cost sortable" data-sort="float" style="font-weight:bold;text-align: right;">' . __('Price incl. VAT') .'</th>';
};
add_action( 'woocommerce_admin_order_item_headers', 'action_woocommerce_admin_order_item_headers', 10, 3 );

WooCommerce:: id was called incorrectly error for custom checkout fields

I'm trying to display a custom checkout field I created in functions.php for WooCommerce and I get this error (along with the actual custom field text as follows:
Notice: id was called incorrectly. Order properties should not be accessed directly. Backtrace: include('wp-admin/edit-form-advanced.php'), do_meta_boxes, WC_Meta_Box_Order_Data::output, do_action('woocommerce_admin_order_data_after_billing_address'), WP_Hook->do_action, WP_Hook->apply_filters, cdm_custom_checkout_field_display_admin_order_meta, WC_Abstract_Legacy_Order->__get, wc_doing_it_wrong Please see Debugging in WordPress for more information. (This message was added in version 3.0.) in /www/webroot/cafed/wordpress/wp-includes/functions.php on line 4778
Here's the code that is generating this error.
add_action( 'woocommerce_admin_order_data_after_billing_address', 'so_custom_checkout_field_display_admin_order_meta', 10, 1 );
function so_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Gift Message').':</strong> ' . get_post_meta( $order->id, 'Gift Message', true ) . '</p>';
}
add_filter('woocommerce_email_order_meta_keys', 'my_custom_order_meta_keys');
function my_custom_order_meta_keys( $keys ) {
$keys[] = 'Gift Message';
return $keys;
}
I believe this has something to do in regards to updates with Woo's code but I'm not sure how to alter it.
Similar thing i have worked on before is working for me
/**
* Add the field to the checkout
*/
add_action('woocommerce_before_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h5>'.__('Time Slot: ').'</h5>';
echo '<h6>'.__('Every Day 09:00AM - 05:00PM').'</h6>';
woocommerce_form_field( 'gv_time_slot', array(
'type' => 'hidden',
'class' => array('my-field-class form-row-wide woocommerce-validated'),
'label' => __('Every Day 04:00Pm - 09:00PM'),
'required' => false,
'placeholder' => __('Check this'),
), $checkout->get_value( 'gv_time_slot' ));
echo '</div>';
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error.
if (!$_POST['gv_time_slot'])
$woocommerce->add_error( __('Please enter something into this new shiny field.') );
}
/**
* Update the order meta with field value
*/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['gv_time_slot']) update_post_meta( $order_id, 'Time Slot', esc_attr($_POST['gv_time_slot']));
}
// display the extra data on order recieved page and my-account order review
function sri_display_order_data( $order_id ){ ?>
<h2><?php _e( 'Time Slot' ); ?></h2>
<table class="shop_table shop_table_responsive additional_info">
<tbody>
<tr>
<th><?php _e( 'Your Order will be delivered between' ); ?></th>
<td><?php echo 'Every Day 09:00AM - 05:00PM'; ?></td>
</tr>
<tr>
<th><?php _e( '*Please Note:' ); ?></th>
<td><?php echo 'All orders placed before 3pm in the website/WhatsApp will be delivered on the same day. Orders after 3 pm will be moved to next day.'; ?></td>
</tr>
</tbody>
</table>
<?php }
add_action( 'woocommerce_thankyou', 'sri_display_order_data', 20 );
add_action( 'woocommerce_view_order', 'sri_display_order_data', 20 );

Woocommerce Attributes Link

i would to modify the single product page in my shop site.
I have to remove links from attribute list in the Additional Information Tab.
I found this html is called in this page: /woocommerce/templates/single-product/product-attributes.php
In this part of code:
<td class="woocommerce-product-attributes-item__value"><?php echo wp_kses_post( $product_attribute['value'] ); ?></td>
Do you know if exist another argument instead “value” for example “slug” or “name”?
If not, how can modify the call to show only value without link?
Thank’s
Add the follows code snippet in your active theme's functions.php -
function filter_woocommerce_attribute_value( $value ) {
return preg_replace( '#<a.*?>([^>]*)</a>#i', '$1', $value );
}
add_filter( 'woocommerce_attribute', 'filter_woocommerce_attribute_value', 99 );

Remove product dimensions from single product pages in Woocommerce

Anyone knows how to hide the product dimensions from the additional tabs on Single Product page but still show the Weight value?
I search and see this filter but it hides both weight and dimensions.
add_filter( 'woocommerce_product_get_dimensions', '__return_false' );
To hide only dimensions (but not weight), there is 2 ways to make it work.
1) using hooks (here composite filter hooks):
Looking at the template that displays dimension in single products, you can see this line:
<?php if ( $display_dimensions && $product->has_dimensions() ) : ?>
Then if you look at WC_Product has_dimensions() method, you will see this line (where $this is the WC_Product Object instance):
return ( $this->get_length() || $this->get_height() || $this->get_width() ) && ! $this->get_virtual();
So when the length, the height and the with are empty (or false), the method returns false…
The following code that use composite hooks, will hide dimensions from "Additional information" tab in single product pages only:
add_filter( 'woocommerce_product_get_width', 'hide_single_product_dimentions', 25, 2 );
add_filter( 'woocommerce_product_get_height', 'hide_single_product_dimentions', 25, 2 );
add_filter( 'woocommerce_product_get_length', 'hide_single_product_dimentions', 25, 2 );
function hide_single_product_dimentions( $value, $product ){
// Only on single product pages
if( is_product() )
$value = '';
return $value;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
To hide weight (just for info) use this composite hook code:
add_filter( 'woocommerce_product_get_weight', 'hide_single_product_weight', 25, 2 );
function hide_single_product_weight( $value, $product ){
// Only on single product pages
if( is_product() )
$value = '';
return $value;
}
2) Overriding Woocommerce templates via your active theme:
First read: Overriding Woocommerce template via the theme.
It explain how to copy the template to your theme before editing it.
Here the related template is single-product/product-attributes.php.
You will have to remove this block from the template code (from line 33 to line 38):
<?php if ( $display_dimensions && $product->has_dimensions() ) : ?>
<tr>
<th><?php _e( 'Dimensions', 'woocommerce' ) ?></th>
<td class="product_dimensions"><?php echo esc_html( wc_format_dimensions( $product->get_dimensions( false ) ) ); ?></td>
</tr>
<?php endif; ?>
You can also use the css property display:none if everything else fails.

wordpress template specific metaboxes?

i have built several diffrent templates for my WP site each calling diffrent metas.
ok, im looking for a way to add a meta-box that will only display if the correct page template is selected.
say i have a homepage.php template, this template calls some specific meta info that only the homepage uses, a call to action of example, so i need the meta-box to appear once the proper page template is selected and disappear if a different page template is selected.
any help is appreciated.
get_page_template will return the template you are looking at. You can switch on this to display the content you want.
ok i finally found a way around it guys and here it is:
<?php
function my_admin() {
$post_id = $_GET['post'] ? $_GET['post'] : $_POST['post_ID'] ;
$template_file = get_post_meta($post_id,'_wp_page_template',TRUE);
// check for a template type
if ($template_file == 'home.php'){
add_meta_box( 'product_info',
'Informacion de Producto',
'display_product_info_meta_box',
'ex_producto', 'normal', 'high'
);
}
}
function display_product_info_meta_box( $product_info ) {
$product_price = floatval( get_post_meta( $product_info->ID, 'product_price', true ) );
$product_code = esc_html( get_post_meta( $product_info->ID, 'product_code', true ) );
?>
<table>
<tr style="width: 100%">
<td >Precio Producto</td>
<td><input type="text" size="80" name="product_info_product_price" value="<?php echo $product_price; ?>" /></td>
</tr>
<tr style="width: 100%">
<td >Codigo de Producto</td>
<td><input type="text" size="80" name="product_info_product_code" value="<?php echo $product_code; ?>" /></td>
</tr>
</table>
<?php
}
add_action( 'admin_init', 'my_admin' );
?>
so... yeap i hope that dose someone out there some good :)

Resources