Customize Woocommerce PIP add row to invoice - php

I have Woocommerce website that does not show VAT, and clients don't want that to change.
I have purchased WooCommerce Print Invoices/Packing Lists.
I would like to add an additional row to the bottom of the table with a calculation of how much VAT was in the invoice using a simple calculation based on the invoice total.
I have achieved this by editing order-table.php but would prefer to add this by adding a filter to functions.php.
I have looked at https://docs.woocommerce.com/document/woocommerce-print-invoice-packing-list/ but can not seem to achieve what I need.
Can anyone point me in the right direction?
Thanks

I found a filter after scouring through the code. I even added some extra code to reorder the values so that the VAT appears before the total. If you don't want it like that I will post the solution without reordering also. I've added in a dummy price of $10 which you can replace with your calculation.
function modify_wc_pip_document_table_footer( $rows, $type, $order_id ) {
$tmp_rows = array();
$tmp_rows['cart_subtotal'] = $rows['cart_subtotal'];
$tmp_rows['payment_method'] = $rows['payment_method'];
$tmp_rows['vat'] = array( 'vat_total' => '<strong class="order-order_total">VAT Total:</strong>',
'value' => wc_price(10)
);
$tmp_rows['order_total'] = $rows['order_total'];
return $tmp_rows;
}
add_filter( 'wc_pip_document_table_footer', 'modify_wc_pip_document_table_footer', 10, 3 );
Without reordering
function modify_wc_pip_document_table_footer( $rows, $type, $order_id ) {
$order = wc_get_order( $order_id );
$order_total = $order->get_total();
$rows['vat'] = array( 'vat_total' => '<strong class="order-order_total">VAT Total:</strong>',
'value' => wc_price(600)
);
return $rows;
}
add_filter( 'wc_pip_document_table_footer', 'modify_wc_pip_document_table_footer', 10, 3 );

Related

Pass specific metadata to Shop Exporter Deluxe in WooCommerce

we use the plugin
Shop Exporter Deluxe to output all orders in a CSV, this works quite well so far.
Now we have switched everything to multistores and receive the orders from the child shops, which we then want to export. Until then everything works. Now we have the product meta "WOONET_PARENT_ORDER_ORIGIN_TEXT" from the multishops in the database.
We want to add this value to the CSV.
We looked at the snippets from the plugin author
https://visser.com.au/documentation/store-exporter-deluxe/code-snippets/
and tried the following
function custom_woo_ce_extend_order_fields( $fields ) {
$fields[] = array(
'name' => 'get_store',
'label' => 'Multistore Shop',
'hover' => 'Get the Multistore Shopname'
);
return $fields;
}
add_filter( 'woo_ce_order_fields', 'custom_woo_ce_extend_order_fields' );
function custom_woo_ce_extend_order( $order, $order_id ) {
$order_get = wc_get_order($order);
$order->get_store .= $order_get->get_meta('WOONET_PARENT_ORDER_ORIGIN_TEXT');
return $order;
}
add_filter( 'woo_ce_order', 'custom_woo_ce_extend_order', 10, 2 );
The select field works so far, so the first function works.
However, no new value is added to the CSV

Hide orders with status (Pending Payment) on WooCommerce My Account page

Inspired by the thread 'Hiding order status in My Account recent orders list page'
I tried to hide orders with status (Pending Payment) on the 'My Account' page.
I modified the code slightly, but I can't get it to work.
add_filter('woocommerce_my_account_my_orders_actions', 'custom_removing_order_status_pending_payment', 10, 1);
function custom_removing_order_status_pending_payment( $order ){
unset($order['wc-pending']);
return $order;
}
I really appreciate any help. Thank you.
Right now you are using the woocommerce_my_account_my_orders_actions filter which will let you filter the buttons in the 'Action' column on the 'My Account' page.
If you want to filter out certain order statuses from the order list you will have to use the woocommerce_my_account_my_orders_query filter.
add_filter( 'woocommerce_my_account_my_orders_query', 'unset_pending_payment_orders_from_my_account', 10, 1 );
function unset_pending_payment_orders_from_my_account( $args ) {
$statuses = wc_get_order_statuses();
unset( $statuses['wc-pending'] );
$args['post_status'] = array_keys( $statuses );
return $args;
}
The accepted answer is mostly, OK, however, it relies on WooCommerce saving Orders as a WordPress custom post type, and there's been for a while a conversation about moving orders to their own custom table to improve performance and scalability of WooCommerce-powered stores.
As a general rule, it is better to use WooCommerce's specific methods and parameters.
The filter woocommerce_my_account_my_orders_query uses wc_get_orders which says to use 'status' as parameter, and not 'post_status'
The updated answer using WC_Order_Query would be
add_filter( 'woocommerce_my_account_my_orders_query', 'unset_pending_payment_orders_from_my_account', 10, 1 );
function unset_pending_payment_orders_from_my_account( $args ) {
$statuses = wc_get_order_statuses();
unset( $statuses['wc-pending'] );
$args['status'] = array_keys( $statuses );
return $args;
}

woocommerce wc_rbp_product_selling_price in custom data tag

In a site that I am developing in woocommerce I needed to be able to create 6 price lists with fixed prices for each product and to be able to apply a global discount in percentage for the price list assigned to the customer.
For the 6 price lists i've managed it through the plugin "Role Based Price For WooCommerce"
For the discount per client part i've created a little plugin. Here the code
function get_price_divider() {
$user_id = get_current_user_id();
$perc = get_user_meta( $user_id, 'sconto_cliente', true );
$sconto = ((int)$perc);
return $sconto;
}
add_filter('wc_rbp_product_selling_price', 'custom_price', 99, 2 );
function custom_price( $price, $product ) {
return ((int)$price)-((((int)$price)/100)*get_price_divider());
}
Everything works fine on the product page. It handle the hook 'wc_rbp_product_selling_price' correctly.
However, I need to pass this price to another plugin with which I made the "tool finder" for the products on sale.
The authors of the plugin (LSCF) give me the option to Create New Data Tag as specified here: https://pixolette.com/docs/lscf/custom-template/create-new-data-tag/
So i should display in their html template with this code
<div class="customdata">
Prezzo: {{post.custom_price}}
</div>
I've created the code below to do this but output always 0
add_action( 'lscf_custom_tags', 'lscf_custom_tags_function' );
function lscf_custom_tags_function( &$args ) {
global $price, $product;
$post_id = (int) $args['ID'];
$output = apply_filters( 'wc_rbp_product_selling_price', $price, $product );
$args['custom_price'] = $output;
}
What's wrong?
I'm not an expert but maybe you should reduce priority argument in the
add_filter('wc_rbp_product_selling_price', 'custom_price', 99, 2 );
It probably doesn't fire in time to adjust the price.

How to create custom discount for the cart in woocommerce

I'm creating a Plugin in WooCommerce and have a small issue with adding custom discounts to the CART / CHECKOUT page.
How can I apply custom discount to the cart without creating coupons?
Say I want to give some discount of 5 dollars on the cart page. How can I do that?
Below is my code from the plugin file where I have used a coupon to apply discount, but I want to add another custom discount without the use of coupon.
Action Hook in the plugin file :
add_action('woocommerce_calculate_totals',array(&$this,'cart_order_total_action'));
and its function in the plugin file is :
public function cart_order_total_action(){
if ( is_user_logged_in() ){
global $woocommerce;
global $current_user;
global $wpdb;
$u_id = $current_user->ID;
$table_name = $wpdb->prefix."woocommerce_customer_reward_ms";
$thetable2 = $wpdb->prefix . "woocommerce_customer_reward_cart_ms";
$table_name3 = $wpdb->prefix."woocommerce_customer_reward_points_log_ms";
$data = $wpdb->get_row("SELECT * from $table_name where id=$u_id");
$data2 = $wpdb->get_row("SELECT * from $thetable2");
/* Order Id goes here */
$orders=array();//order ids
$args = array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $current_user->ID,
'post_type' => 'shop_order',
'post_status' => 'publish',
'tax_query'=>array(
array(
'taxonomy' =>'shop_order_status',
'field' => 'slug',
'terms' =>'on-hold'
)
)
);
$posts=get_posts($args);
$orders=wp_list_pluck( $posts, 'ID' );
$order = $orders[0];
/* Order Id ends here */
if($data){
$user_points = $data->points;
$points_set = $data2->woo_pts_set;
$coupon_code = 'wooreward_discount';
if($user_points>=$points_set){
// this following Code is optional and can be removed......as there is no need of if statement here
if ( $woocommerce->cart->has_discount( $coupon_code ) ) {
/*$woocommerce->add_error( __('Coupon Code Already Applied.!!','woocommerce'));*/
return false;
}else{
$woocommerce->cart->add_discount(sanitize_text_field($coupon_code));
$woocommerce->add_message( __('Taxco925 Reward Discount Applied.!!','woocommerce'));
}
}else{
$woocommerce->add_error( __('Not Enough Taxco925 Points.!!','woocommerce'));
}
}else{
$woocommerce->add_error( __('You have have not earned any Taxco925 Points yet.!!','woocommerce'));
}
}
}
As you can see this line $woocommerce->cart->add_discount(sanitize_text_field($coupon_code));
adds my discount to the cart. But it uses coupon in the background to do so . Is there any way I can add a custom discount without the use of coupon.
add_action('woocommerce_checkout_order_processed','custom_disount',10,1);
function custom_disount($order_id){
$order = wc_get_order($order_id);
$order_items = $order->get_items();
foreach ($order_items as $order_item_key => $order_item) {
$product = new WC_Product((int) $order_item['product_id']);
$quantity = (int) $order_item['qty'];
$discount=($product->regular_price*30)/100; //30% disount.
wc_update_order_item_meta($order_item_key,'_line_total',($product->regular_price*$quantity)-($discount*$quantity));
}
}
You can add discount to each and every product in the cart using "woocommerce_get_discounted_price" hook.
For Eg.:
function filter_woocommerce_get_discounted_price( $price, $values, $instance ) {
//$price represents the current product price without discount
//$values represents the product object
//$instance represent the cart object
$discount = 300; // add custom discount rule , This is just an example
return ($price - $discount);
};
add_filter('woocommerce_get_discounted_price','filter_woocommerce_get_discounted_price', 10, 3 );
Maybe too late, but If someone have another solution tell me.
I use something like:
$discount = floatval(10);
if(!empty($discount) || $discount != 0){
$discount *= -1; // convert positive to negative fees
$woocommerce->cart->add_fee('discount', $discount, true, '' ); // add negative fees
}
If you use paypal standard payment, you got an error because you can't submit a product with negative pricing.
You just need to edit the paypal woocommerce plugin to pass this value.
But other Payment method is ok!
Best Regards,
Add fee with negative value will not produce the right total fee.
Tax is added on the fee amount resulting in higher total fee than expected.
You need to create a "coupon" and apply it to the cart before you create the order from the cart (it will not calculate right if you apply it on $order directly). Then recalculate the cart->total and finally create an order from the cart, after you have saved the order you can remove the "dynamic" created "coupon" if you want. You can create dynamic coupons with any dynamic $value and of any type (fixed, percent etc etc).
This is the only way to add discounts in woo3+.
Fee is doing it wrong when it comes to discounts. Also woo say about fee "Not use negative values here!".
I guessed you wanted some example?
here....
<?php
// this code inside wordpress and with woo3+ of course......
// you have to figure out the rest yourself, how to implement it. but here it is...
$order_data = array (
'status' => 'on-hold' // or whatever order staus
// can have more data if need here...
);
// below creates a coupon with discount_type = fixed_cart, default.
$coupon = array (
'post_title' => 'coupon_discount',
'post_status' => 'publish',
'post_type' => 'shop_coupon'
);
// can be modified with update_post_meta discount_type = percent and so on....
$dynamic_discount = 20; // yes, just a number can be from another dynamic input source....
$new_coupon_id = wp_insert_post( $coupon ); // add the coupon to the cart
add_post_meta( $new_coupon_id , 'coupon_amount' , $dynamic_discount , true ); // add the "discount" value ($dynamic_discount)..... depends on discount_type... in this case fixed_cart
WC()->cart->add_to_cart( 2122 , 2 ); // add products, product_id , quantity ..... can be in a loop.
WC()->cart->add_discount( 'coupon_discount' ); // APPLY THE COUPON WITH DISCOUNT -> This is the trick....
WC()->cart->calculate_totals(); // do some math on the "cart"
WC()->checkout(); // yes, checkout the "cart", now with the discount....
$order_id = WC()->checkout()->create_order( $order_data ); // basic order data, see the top in this script.. get new created order_id.
$order = wc_get_order( $order_id ); // get the order...
// can do more with $order here if want, but NOT any coupons... it just not work in $order as is...
$order->calculate_totals(); // math
WC()->cart->empty_cart(); // empty cart....
$order->save(); // save the order...
wp_delete_post( $new_coupon_id , true ); // IF you want to delete the "dynamic" coupon created above... up 2 u, if not you will end up with a lot of coupons
// sorry, a bad example, uggly code, but at least it work.... :)
// btw, i like Pattaya, send bitcoins :)
// Again, sorry for uggly code...
?>

Add a Custom Field to WooCommerce Order Items

Currently, WooCommerce Order Items within an order, have the following columns:
Item
Tax Class
Qty
Totals
Tax
See screenshot
What I'm aiming to do is add an extra column (or meta) which has a dropdown field for Product Status.
Does anyone have any ideas on how I might accomplish this?
In case someone else stumbles upon this, I needed to add some custom order meta to the order items meta box on the edit order screen. In 2017 this is how I solved this dilemma.
The file class-wc-meta-box-order-items.php, found under includes/admin/meta-boxes has changed slightly since 2014 but it does include the template file html-order-items.php.
It's in that last file that you will find two undocumented hooks, woocommerce_admin_order_item_headers, which you would use to add your custom column heading text and has access to the $order object and woocommerce_admin_order_item_values, which places your custom content right before the Cost column and has access to $product, $item and $item_id.
So to add a custom column it would look something like this.
add_action( 'woocommerce_admin_order_item_headers', 'pd_admin_order_items_headers' );
function pd_admin_order_items_headers($order){
?>
<th class="line_customtitle sortable" data-sort="your-sort-option">
Custom Title
</th>
<?php
}
where your-sort-option depends on what data you are wanting to sort. I used string-ins in my situation.
Than for the content in each line item you would have.
add_action( 'woocommerce_admin_order_item_values', 'pd_admin_order_item_values' );
function pd_admin_order_item_values( $product, $item, $item_id ) {
//Get what you need from $product, $item or $item_id
?>
<td class="line_customtitle">
<?php //your content here ?>
</td>
<?php
}
There are a few other hooks and filters in that template file that are definitely worth looking at if you need content in different places within that meta-box.
I am in the middle of some major adjustments to this table as well, and I haven't figured it all out yet, but I know this much, if you review the class-wc-meta-box-order-items.php within the plugin directory, you will find this snippet of code:
// List order items
$order_items = $order->get_items( apply_filters( 'woocommerce_admin_order_item_types', array( 'line_item', 'fee' ) ) );
foreach ( $order_items as $item_id => $item ) {
switch ( $item['type'] ) {
case 'line_item' :
$_product = $order->get_product_from_item( $item );
$item_meta = $order->get_item_meta( $item_id );
include( 'views/html-order-item.php' );
break;
case 'fee' :
include( 'views/html-order-fee.php' );
break;
}
do_action( 'woocommerce_order_item_' . $item['type'] . '_html', $item_id, $item );
}
DO NOT EDIT THIS SNIPPET!!!
From here you can begin to see what makes up that table. I believe (from what I know of WooCommerce so far) is you can create a function that hooks in at the filter there: woocommerce_admin_order_item_types();
That's what I would do something like this:
# Admin Panel Updates
add_filter( 'woocommerce_add_order_item_meta', array( $this, 'display_order_item_meta' ), 10, 2 );
public function display_order_item_meta( $order_items ) {
array_push($order_items,'event'); //Not sure how to manipulate this yet
return $order_items;
}
Also it looks like we would need to do something with the action hook (woocommerce_order_item_' . $item['type'] . '_html', $item_id, $item), perhaps something along these lines:
add_filter( 'woocommerce_order_item_event_html', array( $this, 'display_event_item_meta' ), 10, 2 );
public function display_event_item_meta( $item_id, $item) {
switch ( $item['type'] ) {
case 'event' :
include( 'views/html-order-event-item.php' );
break;
}
}
That's my best guess so far, but I'm positive this is the right snippet of code to be dissecting.

Categories