function test_returns_false_if_not_shipping_to_nexus_area()
 {
     update_option('woocommerce_default_country', 'US:CO');
     $tj = new WC_Taxjar_Integration();
     $tj_nexus = new WC_Taxjar_Nexus($tj);
     $this->assertFalse($tj_nexus->has_nexus_check('US', 'XO'));
 }
 /**
  * TaxJar API call
  *
  * @return void
  */
 public function taxjar_api_call($options = array())
 {
     global $woocommerce;
     $this->_log(':::: TaxJar Plugin requested ::::');
     // Process $options array and turn them into varibables
     $options = is_array($options) ? $options : array();
     extract(array_replace_recursive(array('to_country' => null, 'to_state' => null, 'to_zip' => null, 'to_city' => null, 'amount' => null, 'shipping_amount' => null), $options));
     // Initalize some variables & properties
     $store_settings = $this->get_store_settings();
     $customer = $woocommerce->customer;
     $this->tax_rate = 0;
     $this->amount_to_collect = 0;
     $this->item_collectable = 0;
     $this->shipping_collectable = 0;
     $this->freight_taxable = 1;
     $this->has_nexus = 0;
     $this->tax_source = 'origin';
     $this->rate_id = null;
     // Strict conditions to be met before API call can be conducted
     if (empty($to_country) || empty($to_zip) || $customer->is_vat_exempt()) {
         return false;
     }
     $taxjar_nexus = new WC_Taxjar_Nexus($this);
     if (!$taxjar_nexus->has_nexus_check($to_country, $to_state)) {
         $this->_log(':::: Order not shipping to nexus area ::::');
         return false;
     }
     // Setup Vars for API call
     $to_zip = explode(',', $to_zip);
     $to_zip = array_shift($to_zip);
     $from_country = $store_settings['store_country_setting'];
     $from_state = $store_settings['store_state_setting'];
     $from_zip = $store_settings['taxjar_zip_code_setting'];
     $from_city = $store_settings['taxjar_city_setting'];
     $shipping_amount = is_null($shipping_amount) ? 0.0 : $shipping_amount;
     $this->_log(':::: TaxJar API called ::::');
     $url = $this->uri . 'taxes';
     $body_string = sprintf('plugin=woo&to_state=%s&from_state=%s&amount=%s&shipping=%s&from_city=%s&from_zip=%s&to_city=%s&to_zip=%s&from_country=%s&to_country=%s&line_items[][quantity]=1&line_items[][unit_price]=%s', $to_state, $from_state, $amount, $shipping_amount, $from_city, $from_zip, $to_city, $to_zip, $from_country, $to_country, $amount);
     // Build the URL and Transient key
     $url = str_replace(' ', '%20', $url);
     $cache_key = hash('md5', $url . '/' . $body_string);
     // To check to see if we hit the API or not
     $taxjar_response = false;
     // Make sure we don't have a cached rate
     if (false === ($cache_value = wp_cache_get($cache_key, 'taxjar'))) {
         // Log this request
         $this->_log("Requesting: " . $url);
         // Make API call with API token in header
         $response = wp_remote_post($url, array('headers' => array('Authorization' => 'Token token="' . $this->settings['api_token'] . '"', 'Content-Type' => 'application/x-www-form-urlencoded'), 'user-agent' => $this->ua, 'body' => $body_string));
         // Fail loudly if we get an error from wp_remote_post
         if (is_wp_error($response)) {
             new WP_Error('request', __("There was an error retrieving the tax rates. Please check your server configuration."));
         } else {
             if (200 == $response['response']['code']) {
                 // Log the response
                 $this->_log("Received: " . $response['body']);
                 // Decode Response
                 $taxjar_response = json_decode($response['body']);
                 $taxjar_response = $taxjar_response->tax;
                 // Update Properties based on Response
                 $this->has_nexus = (int) $taxjar_response->has_nexus;
                 $this->tax_source = empty($taxjar_response->tax_source) ? 'origin' : $taxjar_response->tax_source;
                 $this->amount_to_collect = $taxjar_response->amount_to_collect;
                 if (!empty($taxjar_response->breakdown)) {
                     if (!empty($taxjar_response->breakdown->shipping)) {
                         $this->shipping_collectable = $taxjar_response->breakdown->shipping->tax_collectable;
                     }
                 }
                 $this->item_collectable = $this->amount_to_collect - $this->shipping_collectable;
                 $this->tax_rate = $taxjar_response->rate;
                 $this->freight_taxable = (int) $taxjar_response->freight_taxable;
                 // Create cache value
                 $cache_value = $this->amount_to_collect . '::' . $this->tax_rate . '::' . $this->freight_taxable . '::' . $this->has_nexus . '::' . $this->tax_source . '::' . $this->item_collectable . '::' . $this->shipping_collectable;
                 // Log the new cached value
                 $this->_log("Cache Value: " . $cache_value);
                 // Set Cache
                 wp_cache_set($cache_key, $cache_value, 'taxjar', $this->cache_time);
             } else {
                 // Log Response Error
                 $this->_log("Received (" . $response['response']['code'] . "): " . $response['body']);
             }
         }
     } else {
         // Read the cached value based on our delimiter
         $cache_value = explode('::', $cache_value);
         // Set properties to the cached values
         $this->amount_to_collect = $cache_value[0];
         $this->tax_rate = $cache_value[1];
         $this->freight_taxable = $cache_value[2];
         $this->has_nexus = $cache_value[3];
         $this->tax_source = $cache_value[4];
         $this->item_collectable = $cache_value[5];
         $this->shipping_collectable = $cache_value[6];
         // Log Cached Response
         $this->_log("Cached Amount: " . $this->amount_to_collect);
         $this->_log("Cached Nexus: " . $this->has_nexus);
         $this->_log("Cached Source: " . $this->tax_source);
         $this->_log("Cached Rate: " . $this->tax_rate);
         $this->_log("Shipping Taxable? " . $this->freight_taxable);
         $this->_log("Item Tax to Collect: " . $this->item_collectable);
         $this->_log("Shipping Tax to Collect: " . $this->shipping_collectable);
     }
     // Remove taxes if they are set somehow and customer is exempt
     if ($customer->is_vat_exempt()) {
         $wc_cart_object->remove_taxes();
     } elseif ($this->has_nexus) {
         //} else {
         // Use Woo core to find matching rates for taxable address
         $source_zip = $this->tax_source == 'destination' ? $to_zip : $from_zip;
         $source_city = $this->tax_source == 'destination' ? $to_city : $from_city;
         if (strtoupper($to_city) == strtoupper($from_city)) {
             $source_city = $to_city;
         }
         // Setup Tax Rates
         $tax_rates = array("tax_rate_country" => $to_country, "tax_rate_state" => $to_state, "tax_rate_name" => sprintf("%s Tax", $to_state), "tax_rate_priority" => 1, "tax_rate_compound" => false, "tax_rate_shipping" => $this->freight_taxable, "tax_rate" => $this->tax_rate * 100, "tax_rate_class" => '');
         // Clear the cached rates
         $this->clear_wc_tax_cache($to_country, $to_state, $source_city, $source_zip);
         $this->_log($source_city);
         $wc_rates = WC_Tax::find_rates(array('country' => $to_country, 'state' => $to_state, 'postcode' => $source_zip, 'city' => $source_city, 'tax_class' => ''));
         // If we have rates, use those, but if no rates returned create one to link with, or use the first rate returned.
         if (!empty($wc_rates)) {
             $this->_log('::: TAX RATES FOUND :::');
             $this->_log($wc_rates);
             // Get the existing ID
             $rate_id = key($wc_rates);
             // Update Tax Rates with TaxJar rates ( rates might be coming from a cached taxjar rate )
             $this->_log(':: UPDATING TAX RATES TO ::');
             $this->_log($tax_rates);
             WC_TAX::_update_tax_rate($rate_id, $tax_rates);
         } else {
             // Insert a rate if we did not find one
             $this->_log(':: Adding New Tax Rate ::');
             $rate_id = WC_Tax::_insert_tax_rate($tax_rates);
             WC_Tax::_update_tax_rate_postcodes($rate_id, wc_clean($source_zip));
             WC_Tax::_update_tax_rate_cities($rate_id, wc_clean($source_city));
         }
         $this->_log('Tax Rate ID Set: ' . $rate_id);
         $this->rate_id = $rate_id;
     }
 }