wpovernight/woocommerce-pdf-invoices-packing-slips

WooCommerce Rental & Booking System discount not showing on invoice

BrunoPavlinic98 opened this issue · 6 comments

WooCommerce Rental & Booking System by RedQ Team is a plugin that manages rental and booking systems. If you create a new Rental product, you can go to the Price discount tab and set the discount for that product. I have tested that the user gets 10% discount if he rents the product for more than 3 days. Once the user rents something, the discount gets deducted from the total price, however, there is no discount shown on the invoice.

This plugin is not HPOS compatible!

This issue might be solvable using the following 2 hooks:

add_action( 'woocommerce_store_api_checkout_order_processed', function ( $order ) {
	$discount_total = 0;
	foreach ( $order->get_items() as $item_id => $item ) {
		$price_breakdown = $item->get_meta( 'rnb_price_breakdown' );
		if ( ! empty( $price_breakdown ) && isset( $price_breakdown['discount_total'] ) && 'redq_rental' === WC_Product_Factory::get_product_type( $item->get_product_id() ) ) {
			$discount_total += $price_breakdown['discount_total'];
		}
	}

	if ( 0 !== $discount_total ) {
		update_post_meta( $order->get_id(), '_redq_rental_order_discount', $discount_total );
	}

} , 10, 1 );

add_filter( 'wpo_wcpdf_woocommerce_totals', function( $totals, $order, $type ) {
	$new_totals = $totals;
	$discount = absint( $order->get_meta( '_redq_rental_order_discount' ) );
	if ( 0 !== $discount && isset( $totals['cart_subtotal'] ) ) {
		$subtotal = absint( $order->get_total() ) + $discount;
		$order->set_discount_total( $order->get_total_discount() + $discount );
		$new_totals = $order->get_order_item_totals();
		$new_totals['cart_subtotal']['value'] = wc_price( $subtotal );
	}
	return $new_totals;
}, 10, 3 );

The idea is to put a new meta data to the order after the order was placed in the checkout and put to the processing state(woocommerce_store_api_checkout_order_processed hook). The good thing is that RedQ placed rnb_price_breakdown meta to each order item, and therefore, we can sum them all and get the total discount, which can be saved to _redq_rental_order_discount order's meta data.

Then, the _redq_rental_order_discount order's meta data can be used by the wpo_wcpdf_woocommerce_totals hook in a way that it checks if the RedQ discount exists, and if yes, append that discount to already existing order discount and increase the order's subtotal by the RedQ discount value.

I tried this, and it works on my end.

@Terminator-Barbapapa @alexmigf @MohamadNateqi What do you think, should we first send this solution to the customer so that he can try it out and provide testing?
If his tests are positive, we could consider adding this functionality to our PRO plugin, as a part of a compatibility with other plugins.

What do you think? And of course, feel free to provide code review for the provided snippets.

What are the order totals after the discount being applied? Can you show me the order items + totals from the order page?

@BrunoPavlinic98 If the discount is stored in the item meta I don't think we need to store it again in the order meta. We should be able to show it on the invoice with the currently available filters.

@alexmigf Here is the information you requested:
The RedQ plugin's order info before confirming the order:
Duration Cost 100,00 €
Discount amount - 10,00 €
Subtotal 90,00 €
Grand Total 90,00 €

And the images from order backend and invoice:
Capture
Capture1

@Terminator-Barbapapa I think that this could work only with wpo_wcpdf_woocommerce_totals hook, without appending data to order meta. I will create a new snippet, and then, we can try to see if it will solve the issue.

@alexmigf @Terminator-Barbapapa Here is the new snippet:

add_filter( 'wpo_wcpdf_woocommerce_totals', function( $totals, $order, $type ) {
	$new_totals = $totals;

	$discount_total = 0;
	foreach ( $order->get_items() as $item_id => $item ) {
		$price_breakdown = $item->get_meta( 'rnb_price_breakdown' );
		if ( ! empty( $price_breakdown ) && isset( $price_breakdown['discount_total'] ) && 'redq_rental' === WC_Product_Factory::get_product_type( $item->get_product_id() ) ) {
			$discount_total += $price_breakdown['discount_total'];
		}
	}

	if ( 0 !== $discount_total && isset( $totals['cart_subtotal'] ) ) {
		$subtotal = absint( $order->get_total() ) + $discount_total;
		$order->set_discount_total( $order->get_total_discount() + $discount_total );
		$new_totals = $order->get_order_item_totals();
		$new_totals['cart_subtotal']['value'] = wc_price( $subtotal );
	}
	return $new_totals;
}, 10, 3 );

Works in the same way as with the two snippets.

I am closing this issue because it was fixed using custom snippets.