Skip to content
This repository has been archived by the owner on Jun 15, 2022. It is now read-only.

Commit

Permalink
It isn't 100% complete yet, but introduce a custom data store for ref…
Browse files Browse the repository at this point in the history
…unds. Refs #45.
  • Loading branch information
stevegrunwell committed Feb 20, 2018
1 parent 4a524a4 commit b4ccdec
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 27 deletions.
22 changes: 22 additions & 0 deletions includes/class-wc-order-data-store-custom-table.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,28 @@ protected function update_post_meta( &$order ) {
do_action( 'woocommerce_order_object_updated_props', $order, $updated_props );
}

/**
* Get amount already refunded.
*
* @global $wpdb
*
* @param WC_Order $order Order object.
*
* @return float The amount already refunded.
*/
public function get_total_refunded( $order ) {
global $wpdb;

$total = $wpdb->get_var( $wpdb->prepare(
'SELECT SUM(o.amount) FROM ' . esc_sql( wc_custom_order_table()->get_table_name() ) . " AS o
INNER JOIN $wpdb->posts AS p ON ( p.post_type = 'shop_order_refund' AND p.post_parent = %d )
WHERE o.order_id = p.ID",
$order->get_id()
) );

return floatval( $total );
}

/**
* Finds an order ID based on its order key.
*
Expand Down
142 changes: 142 additions & 0 deletions includes/class-wc-order-refund-data-store-custom-table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php
/**
* WooCommerce order refund data store.
*
* @package WooCommerce_Custom_Orders_Table
* @author Liquid Web
*/

/**
* Extend the WC_Order_Refund_Data_Store_CPT class, overloading methods that require database access in
* order to use the new table.
*
* This operates in a way similar to WC_Order_Data_Store_Custom_Table, but is for *refunds*.
*/
class WC_Order_Refund_Data_Store_Custom_Table extends WC_Order_Refund_Data_Store_CPT {

/**
* Set to true when creating so we know to insert meta data.
*
* @var boolean
*/
protected $creating = false;

/**
* Create a new refund in the database.
*
* @param WC_Order_Refund $refund The refund object, passed by reference.
*/
public function create( &$refund ) {
$this->creating = true;

parent::create( $refund );
}

/**
* Read refund data.
*
* @param WC_Order_Refund $refund The refund object, passed by reference.
* @param object $post_object The post object.
*/
protected function read_order_data( &$refund, $post_object ) {
global $wpdb;

$data = $this->get_order_data_from_table( $refund );

if ( ! empty( $data ) ) {
$refund->set_props( $data );

} else {
// Automatically backfill refund data from meta, but allow for disabling.
if ( apply_filters( 'wc_custom_order_table_automatic_migration', true ) ) {
$this->populate_from_meta( $refund );
}
}
}

/**
* Retrieve a single refund from the database.
*
* @global $wpdb
*
* @param WC_Order_Refund $refund The refund object.
*
* @return object The refund row, as an associative array.
*/
public function get_order_data_from_table( $refund ) {
global $wpdb;

$data = $wpdb->get_row( $wpdb->prepare(
'SELECT * FROM ' . esc_sql( wc_custom_order_table()->get_table_name() ) . ' WHERE order_id = %d LIMIT 1',
$refund->get_id()
), ARRAY_A ); // WPCS: DB call OK.

// If no matches were found, this record needs to be created.
if ( null === $data ) {
$this->creating = true;

return array();
}

// Expand anything that might need assistance.
$data['prices_include_tax'] = wc_string_to_bool( $data['prices_include_tax'] );

return $data;
}

/**
* Helper method that updates all the post meta for a refund based on it's settings in the
* WC_Order_Refund class.
*
* @global $wpdb
*
* @param WC_Order $refund The refund to be updated.
*/
protected function update_post_meta( &$refund ) {
global $wpdb;

$table = wc_custom_order_table()->get_table_name();
$refund_data = array(
'order_id' => $refund->get_id( 'edit' ),
'discount_total' => $refund->get_discount_total( 'edit' ),
'discount_tax' => $refund->get_discount_tax( 'edit' ),
'shipping_total' => $refund->get_shipping_total( 'edit' ),
'shipping_tax' => $refund->get_shipping_tax( 'edit' ),
'cart_tax' => $refund->get_cart_tax( 'edit' ),
'total' => $refund->get_total( 'edit' ),
'version' => $refund->get_version( 'edit' ),
'currency' => $refund->get_currency( 'edit' ),
'prices_include_tax' => wc_bool_to_string( $refund->get_prices_include_tax( 'edit' ) ),
'amount' => $refund->get_amount( 'edit' ),
'reason' => $refund->get_reason( 'edit' ),
'refunded_by' => $refund->get_refunded_by( 'edit' ),
);

// Insert or update the database record.
if ( $this->creating ) {
$inserted = $wpdb->insert( $table, $refund_data ); // WPCS: DB call OK.

if ( 1 !== $inserted ) {
return;
}

$this->creating = false;

} else {
$refund_data = array_intersect_key( $refund_data, $refund->get_changes() );

// There's nothing to update.
if ( empty( $refund_data ) ) {
return;
}

$wpdb->update(
wc_custom_order_table()->get_table_name(),
$refund_data,
array( 'order_id' => (int) $refund->get_id() )
);
}

do_action( 'woocommerce_order_refund_object_updated_props', $refund, $refund_data );
}
}
57 changes: 30 additions & 27 deletions includes/class-woocommerce-custom-orders-table-install.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,32 @@ protected static function install_tables() {
$tables = "
CREATE TABLE {$table} (
order_id BIGINT UNSIGNED NOT NULL,
order_key varchar(100) NOT NULL,
order_key varchar(100),
customer_id BIGINT UNSIGNED NOT NULL,
billing_index varchar(255) NOT NULL,
billing_first_name varchar(100) NOT NULL,
billing_last_name varchar(100) NOT NULL,
billing_company varchar(100) NOT NULL,
billing_address_1 varchar(200) NOT NULL,
billing_address_2 varchar(200) NOT NULL,
billing_city varchar(100) NOT NULL,
billing_state varchar(100) NOT NULL,
billing_postcode varchar(100) NOT NULL,
billing_country varchar(100) NOT NULL,
billing_index varchar(255),
billing_first_name varchar(100),
billing_last_name varchar(100),
billing_company varchar(100),
billing_address_1 varchar(200),
billing_address_2 varchar(200),
billing_city varchar(100),
billing_state varchar(100),
billing_postcode varchar(100),
billing_country varchar(100),
billing_email varchar(200) NOT NULL,
billing_phone varchar(200) NOT NULL,
shipping_index varchar(255) NOT NULL,
shipping_first_name varchar(100) NOT NULL,
shipping_last_name varchar(100) NOT NULL,
shipping_company varchar(100) NOT NULL,
shipping_address_1 varchar(200) NOT NULL,
shipping_address_2 varchar(200) NOT NULL,
shipping_city varchar(100) NOT NULL,
shipping_state varchar(100) NOT NULL,
shipping_postcode varchar(100) NOT NULL,
shipping_country varchar(100) NOT NULL,
payment_method varchar(100) NOT NULL,
payment_method_title varchar(100) NOT NULL,
billing_phone varchar(200),
shipping_index varchar(255),
shipping_first_name varchar(100),
shipping_last_name varchar(100),
shipping_company varchar(100),
shipping_address_1 varchar(200),
shipping_address_2 varchar(200),
shipping_city varchar(100),
shipping_state varchar(100),
shipping_postcode varchar(100),
shipping_country varchar(100),
payment_method varchar(100),
payment_method_title varchar(100),
discount_total varchar(100) NOT NULL DEFAULT 0,
discount_tax varchar(100) NOT NULL DEFAULT 0,
shipping_total varchar(100) NOT NULL DEFAULT 0,
Expand All @@ -91,12 +91,15 @@ protected static function install_tables() {
currency varchar(3) NOT NULL,
prices_include_tax varchar(3) NOT NULL,
transaction_id varchar(200) NOT NULL,
customer_ip_address varchar(40) NOT NULL,
customer_user_agent varchar(200) NOT NULL,
customer_ip_address varchar(40),
customer_user_agent varchar(200),
created_via varchar(200) NOT NULL,
date_completed varchar(20) DEFAULT NULL,
date_paid varchar(20) DEFAULT NULL,
cart_hash varchar(32) NOT NULL,
cart_hash varchar(32),
amount varchar(100),
refunded_by BIGINT UNSIGNED,
reason text,
PRIMARY KEY (order_id),
UNIQUE KEY `order_key` (`order_key`),
KEY `customer_id` (`customer_id`),
Expand Down
10 changes: 10 additions & 0 deletions includes/class-woocommerce-custom-orders-table.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public function setup() {
// Use the plugin's custom data stores for customers and orders.
add_filter( 'woocommerce_customer_data_store', __CLASS__ . '::customer_data_store' );
add_filter( 'woocommerce_order_data_store', __CLASS__ . '::order_data_store' );
add_filter( 'woocommerce_order-refund_data_store', __CLASS__ . '::order_refund_data_store' );

// Filter order report queries.
add_filter( 'woocommerce_reports_get_order_report_query', 'WooCommerce_Custom_Orders_Table_Filters::filter_order_report_query' );
Expand Down Expand Up @@ -134,4 +135,13 @@ public static function customer_data_store() {
public static function order_data_store() {
return 'WC_Order_Data_Store_Custom_Table';
}

/**
* Retrieve the class name of the WooCommerce order refund data store.
*
* @return string The data store class name.
*/
public static function order_refund_data_store() {
return 'WC_Order_Refund_Data_Store_Custom_Table';
}
}
53 changes: 53 additions & 0 deletions tests/test-order-refund-data-store.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* Tests for the WC_Order_Refund_Data_Store_Custom_Table class.
*
* @package WooCommerce_Custom_Orders_Table
* @author Liquid Web
*/

class OrderRefundDataStoreTest extends TestCase {

protected $user;

/**
* Since refunds are issued by people, generate and act as a user.
*
* @before
*/
public function set_current_user() {
$this->user = $this->factory()->user->create();

wp_set_current_user( $this->user );
}

public function test_read_order_data_meta() {
$order = WC_Helper_Order::create_order();
$refund = wc_create_refund( array(
'order_id' => $order->get_id(),
'amount' => 5,
'reason' => 'For testing',
) );

// Refresh the refund.
$refund = wc_get_order( $refund->get_id() );

$this->assertEquals( 5, $refund->get_amount() );
$this->assertEquals( $this->user, $refund->get_refunded_by() );
$this->assertEquals( 'For testing', $refund->get_reason() );
}

public function test_update_post_meta() {
$order = WC_Helper_Order::create_order();
$refund = wc_create_refund( array(
'order_id' => $order->get_id(),
'amount' => 7,
'reason' => 'For testing',
) );
$row = $this->get_order_row( $refund->get_id() );

$this->assertEquals( 7, $row['amount'] );
$this->assertEquals( $this->user, $row['refunded_by'] );
$this->assertEquals( 'For testing', $row['reason'] );
}
}
2 changes: 2 additions & 0 deletions tests/testcase.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ protected function toggle_use_custom_table( $enabled = true ) {
if ( $enabled ) {
add_filter( 'woocommerce_customer_data_store', 'WooCommerce_Custom_Orders_Table::customer_data_store' );
add_filter( 'woocommerce_order_data_store', 'WooCommerce_Custom_Orders_Table::order_data_store' );
add_filter( 'woocommerce_order-refund_data_store', 'WooCommerce_Custom_Orders_Table::order_data_store' );
} else {
remove_filter( 'woocommerce_customer_data_store', 'WooCommerce_Custom_Orders_Table::customer_data_store' );
remove_filter( 'woocommerce_order_data_store', 'WooCommerce_Custom_Orders_Table::order_data_store' );
remove_filter( 'woocommerce_order-refund_data_store', 'WooCommerce_Custom_Orders_Table::order_data_store' );
}
}

Expand Down

0 comments on commit b4ccdec

Please sign in to comment.