/**
  * Determines whether or not WooTax needs to be updated
  * If a data update is necessary, initiates update by warning admin
  *
  * @since 4.4
  */
 public static function maybe_update_wootax()
 {
     global $wpdb;
     if (version_compare(self::$db_version, WT_VERSION, '=')) {
         return;
     } else {
         self::maybe_update_addresses();
         self::maybe_update_settings();
         if (self::needs_data_update()) {
             wootax_add_message('<strong>WooTax data update required.</strong> Please backup your database, then click "Complete Update" to run the updater. <a class="button button-primary" href="' . admin_url('admin.php?page=wt-update') . '">Complete Update</a>', 'update-nag', 'upgrade-message', true, false);
         } else {
             update_option('wootax_version', WT_VERSION);
         }
     }
 }
 /** 
  * Send a Returned request to TaxCloud when a full or partial refund is processed
  * - Full refund initiated when an order's status is set to "refunded"
  * - Partial refund initiated when WooCommerce manual refund mechanism is used
  *
  * @since 4.4
  * @param (int) $order_id ID of WooCommerce order
  * @param (bool) $cron is this method being called from a WooTax cronjob?
  * @param (array) $items array of items to refund for partial refunds
  */
 public static function refund_order($order_id, $cron = false, $items = array())
 {
     $order = self::get_order($order_id);
     // Different rules need to be applied for full refunds
     $full_refund = count($items) == 0;
     $destination_address = !$full_refund ? $order->destination_address : array();
     // Exit if the order has already been refunded, has not been captured, or was placed by international customer
     if ($full_refund && true === self::get_meta($order_id, 'refunded')) {
         return;
     } else {
         if (!self::get_meta($order_id, 'captured')) {
             if (!$cron && $full_refund) {
                 wootax_add_message('<strong>WARNING:</strong> This order was not refunded in TaxCloud because it has not been captured yet. Please set the order\'s status to completed before refunding it.', 'update-nag');
             } else {
                 if (!$cron) {
                     return "You must set this order's status to 'completed' before refunding any items.";
                 }
             }
             return;
         } else {
             if (isset($destination_address['Country']) && !in_array($destination_address['Country'], array('United States', 'US'))) {
                 return true;
             }
         }
     }
     // Set up item mapping array if this is a partial refund
     if (!$full_refund) {
         // Construct mapping array
         $mapping_array = self::get_meta($order_id, 'mapping_array');
         if (count($mapping_array) == 0) {
             foreach ($items as $location => $items) {
                 $mapping_array[$location] = array();
                 foreach ($items as $item) {
                     $mapping_array[$location][$item['ItemID']] = $order->get_item_index($item['ItemID']);
                 }
             }
         }
     }
     // Loop through sub-orders and send Returned request for each
     $taxcloud_ids = self::get_meta($order_id, 'taxcloud_ids');
     foreach ($taxcloud_ids as $address_key => $order_ids) {
         $refund_items = NULL;
         // Get cart items to refund in correct format if appropriate
         if (!$full_refund && isset($items[$address_key])) {
             $refund_items = array();
             // Get items in appropriate format
             foreach ($items[$address_key] as $item) {
                 $item['Index'] = $mapping_array[$address_key][$item['ItemID']];
                 $refund_items[] = $item;
             }
         }
         // Send Returned request
         $date = new DateTime('NOW');
         $req = array('cartItems' => $refund_items, 'returnedDate' => $date->format(DateTime::ATOM), 'orderID' => $order_ids['order_id']);
         $res = TaxCloud()->send_request('Returned', $req);
         // Check for errors
         if ($res == false) {
             if (!$cron && $full_refund) {
                 wootax_add_message('There was an error while refunding the order. ' . TaxCloud()->get_error_message());
                 break;
             } else {
                 return TaxCloud()->get_error_message();
             }
         }
     }
     // For full refunds, remove order tax completely
     if ($full_refund) {
         $order->remove_tax();
     }
     self::update_meta($order_id, 'refunded', true);
     return true;
 }
 /**
  * Configures WooCommerce tax settings to work with WooTax
  * Executed on plugin activation
  *
  * @since 4.2
  */
 public static function configure_woocommerce()
 {
     // Update WooCommerce settings
     update_option('woocommerce_calc_taxes', 'yes');
     update_option('woocommerce_prices_include_tax', 'no');
     update_option('woocommerce_tax_based_on', 'shipping');
     update_option('woocommerce_default_customer_address', 'base');
     update_option('woocommerce_shipping_tax_class', '');
     update_option('woocommerce_tax_round_at_subtotal', false);
     update_option('woocommerce_tax_display_shop', 'excl');
     update_option('woocommerce_tax_display_cart', 'excl');
     update_option('woocommerce_tax_total_display', 'itemized');
     // Confirm activation with user
     wootax_add_message('<strong>Success!</strong> Your WooCommerce tax settings have been automatically adjusted to work with WooTax.', 'updated', 'activated', true, true);
 }