-
-
Save YourMark/cc5c02aa624090c453adbdf05aa7e6c5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Patboard\Plugin; | |
/** | |
* Class Cli_Command | |
* | |
*/ | |
class Cli_Command extends \WP_CLI_Command { | |
/** | |
* @var string | |
*/ | |
private $reason = 'VAT correction'; | |
/** | |
* Create refund orders for given order id's. | |
* | |
* @param $args | |
* @param $assoc_args | |
* | |
* @throws \Exception | |
*/ | |
function refund( $args, $assoc_args ) { | |
$orders = $assoc_args['orders']; | |
$orders = explode( ',', $orders ); | |
if ( isset( $assoc_args['reason'] ) ) { | |
$this->reason = $assoc_args['reason']; | |
} | |
foreach ( $orders as $orderid ) { | |
$refunded = $this->refund_order( $orderid ); | |
if ( is_wp_error( $refunded ) ) { | |
echo $orderid . ': ' . $refunded->get_error_message(); | |
} | |
} | |
} | |
/** | |
* @param $orderid | |
* | |
* @return \WC_Order_Refund|\WP_Error | |
* @throws \Exception | |
*/ | |
private function refund_order( $orderid ) { | |
$order = wc_get_order( $orderid ); | |
// If it's something else such as a WC_Order_Refund, we don't want that. | |
if ( ! is_a( $order, 'WC_Order' ) ) { | |
return new \WP_Error( 'wc-order', 'Provided ID is not a WC Order' ); | |
} | |
if ( 'refunded' == $order->get_status() ) { | |
return new \WP_Error( 'wc-order', 'Order has been already refunded' ); | |
} | |
// Get Items | |
$order_items = $order->get_items( array( 'line_item', 'fee', 'shipping' ) ); | |
// Refund Amount | |
$refund_amount = 0; | |
// Prepare line items which we are refunding | |
$line_items = []; | |
// Iterating through order shipping items | |
if ( ! $order_items ) { | |
return new \WP_Error( 'wc-order', 'This order has no items' ); | |
} | |
foreach ( $order_items as $item_id => $item ) { | |
$line_total = $item->get_total(); | |
$qty = $item->get_quantity(); | |
$tax_data = $item->get_total_tax(); | |
$refund_tax = 0; | |
if ( ! empty( $tax_data ) ) { | |
$refund_tax = wc_format_decimal( $tax_data ); | |
} | |
$refund_amount = wc_format_decimal( $refund_amount ) + wc_format_decimal( $line_total ); | |
$line_items[ $item_id ] = array( | |
'qty' => $qty, | |
'refund_total' => wc_format_decimal( $line_total ), | |
'refund_tax' => $refund_tax | |
); | |
} | |
$refund = wc_create_refund( array( | |
'amount' => $refund_amount, | |
'reason' => $this->reason, | |
'order_id' => $orderid, | |
'line_items' => $line_items, | |
'refund_payment' => false, | |
) ); | |
return $refund; | |
} | |
} | |
\WP_CLI::add_command( 'refund', array( __namespace__ . '\Cli_Command', 'refund' ) ); |
Hello @n9yty.
This is the solution that worked for me.
<?php
namespace Patboard\Plugin;
class Cli_Command extends \WP_CLI_Command {
/**
* @var string
*/
private $reason = 'VAT correction';
/**
* Create refund orders for given order id's.
*
* @param $args
* @param $assoc_args
*
* @throws \Exception
*/
function refund( $args, $assoc_args ) {
$orders = $assoc_args['orders'];
$orders = explode( ',', $orders );
if ( isset( $assoc_args['reason'] ) ) {
$this->reason = $assoc_args['reason'];
}
foreach ( $orders as $orderid ) {
if( empty( $orderid ) ) {
continue;
}
$refunded = $this->refund_order( $orderid );
if ( is_wp_error( $refunded ) ) {
echo \WP_CLI::log( \WP_CLI::colorize( '%r' . $orderid . ': ' . $refunded->get_error_message() . '%r' ) );
}
else {
echo \WP_CLI::log( \WP_CLI::colorize( '%g' . $orderid . ': Successfully refunded' . '%g' ) );
}
}
}
/**
* @param $orderid
*
* @return \WC_Order_Refund|\WP_Error
* @throws \Exception
*/
private function refund_order( $orderid ) {
$order = wc_get_order( $orderid );
// If it's something else such as a WC_Order_Refund, we don't want that.
if ( ! is_a( $order, 'WC_Order' ) ) {
return new \WP_Error( 'wc-order', 'Provided ID is not a WC Order' );
}
if ( 'refunded' == $order->get_status() ) {
return new \WP_Error( 'wc-order', 'Order has been already refunded' );
}
// Get Items
$order_items = $order->get_items( array( 'line_item', 'fee', 'shipping' ) );
// Refund Amount
$refund_amount = 0;
// Prepare line items which we are refunding
$line_items = [];
// Iterating through order shipping items
if ( ! $order_items ) {
return new \WP_Error( 'wc-order', 'This order has no items' );
}
foreach ( $order_items as $item_id => $item ) {
$line_total = $order->get_line_total( $item, false, false );
$qty = $item->get_quantity();
$tax_data = wc_get_order_item_meta( $item_id, '_line_tax_data' );
$refund_tax = array();
// Check if it's shipping costs. If so, get shipping taxes.
if ( $item instanceof \WC_Order_Item_Shipping ) {
$tax_data = wc_get_order_item_meta( $item_id, 'taxes' );
}
// If taxdata is set, format as decimal.
if ( ! empty( $tax_data['total'] ) ) {
$refund_tax = array_filter( array_map( 'wc_format_decimal', $tax_data['total'] ) );
}
// Calculate line total, including tax.
$line_total_inc_tax = wc_format_decimal( $line_total ) + ( is_numeric( reset( $refund_tax ) ) ? wc_format_decimal( reset( $refund_tax ) ) : 0 );
// Add the total for this line tot the grand total.
$refund_amount = wc_format_decimal( $refund_amount ) + round( $line_total_inc_tax, 2 );
// Fill item per line.
$line_items[ $item_id ] = array(
'qty' => $qty,
'refund_total' => wc_format_decimal( $line_total ),
'refund_tax' => array_map( 'wc_round_tax_total', $refund_tax )
);
}
// Check if the refund amount matches the actual order amount
$expected_refund = floatval( $order->get_total() );
$actual_refund = round( $refund_amount, 2 );
if ( $expected_refund !== $actual_refund ) {
$sum = $expected_refund - $actual_refund;
return new \WP_Error( 'wc-order', sprintf( 'Return amount is off by %f', $sum ) );
}
// And finally, create the refund.
$refund = wc_create_refund( array(
'amount' => $actual_refund,
'reason' => $this->reason,
'order_id' => $orderid,
'line_items' => $line_items,
'refund_payment' => false,
) );
return $refund;
}
}
\WP_CLI::add_command( 'refund', array( __namespace__ . '\Cli_Command', 'refund' ) );
Hi! Not sure where you get the taxes id from. Could you please share this? We're also trying to refund the total VAT in our refund request.
@pixelstart
I believe that's given in
$tax_data = wc_get_order_item_meta( $item_id, '_line_tax_data' );
The $tax_data contains the ID and value.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi! Was this updated to fix the issue you had? I saw on GitHub you said you had to pass the Tax ID in, but I'm not sure where you had to do that and if this code reflects that. Looking to use this for a current one-time problem (hopefully).