/** * Perform a lookup for the order and update tax totals * * @since 4.2 * @param (array) $items an array of CartItems * @param (array) $type_array an array mapping item IDs to item types (cart/shipping) * @param (boolean) is this lookup for a subscription renewal order? */ public function do_lookup($items, $type_array, $subscription = false) { // Fire request if we are ready to do so if ($this->ready_for_lookup()) { $taxcloud_ids = $lookup_data = array(); if (!$subscription) { // Remove currently applied taxes (delete order item instead?) $this->remove_tax(); // Generate lookup data $lookup_data = $this->generate_lookup_data($items); WT_Orders::update_meta($this->order_id, 'lookup_data', $lookup_data); // Generate TaxCloud Cart/Order IDs $taxcloud_ids = $this->generate_order_ids(); WT_Orders::update_meta($this->order_id, 'taxcloud_ids', $taxcloud_ids); } else { // Only generate lookup data $lookup_data = $this->generate_lookup_data($items); } $mapping_array = WT_Orders::get_meta($this->order_id, 'mapping_array'); // Retrieve validated destination addresses $destination_address = maybe_validate_address($this->destination_address, $this->order_id); // Used in every tax lookup $all_cart_items = array(); $tax_total = $shipping_tax_total = 0; // Fetch some information about the order $exempt_cert = $this->get_exemption_certificate(); $customer_id = $this->get_customer_id(); $delivered_by_seller = wt_is_local_delivery($this->get_shipping_method()); // Loop through locations in lookup_data array and send a Lookup request for each foreach ($lookup_data as $location_key => $items) { // Fetch cart_id $cart_id = isset($taxcloud_ids[$location_key]['cart_id']) ? $taxcloud_ids[$location_key]['cart_id'] : ''; // Get the origin address $origin_address = wootax_get_address($location_key); // Build request array $req = array('customerID' => $customer_id, 'cartID' => $cart_id, 'cartItems' => $items, 'origin' => $origin_address, 'destination' => $destination_address, 'deliveredBySeller' => $delivered_by_seller); if (!empty($exempt_cert)) { $req['exemptCert'] = $exempt_cert; } // Send Lookup request $res = TaxCloud()->send_request('Lookup', $req); if ($res !== false) { // Initialize some vars $cart_items = $res->CartItemsResponse->CartItemResponse; // Store the returned CartID for later use $taxcloud_ids[$location_key]['cart_id'] = $res->CartID; // If cart_items only contains one item, it will not be an array. // In that case, convert to an array if (!is_array($cart_items)) { $cart_items = array($cart_items); } // Loop through items and update tax amounts foreach ($cart_items as &$cart_item) { // Fetch item info $index = $cart_item->CartItemIndex; $item_id = $mapping_array[$location_key][$index]; $type = isset($type_array[$item_id]) ? $type_array[$item_id] : 'cart'; $tax = $cart_item->TaxAmount; // Update item tax if (!$subscription) { $this->apply_item_tax($item_id, $tax); } // Keep track of cart tax/shipping tax totals if ($type == 'cart') { $tax_total += $tax; } else { $shipping_tax_total += $tax; } // Add ItemID property so @see $this->ajax_update_order_tax() can work as expected $cart_item->ItemID = $item_id; } } else { // Return error return TaxCloud()->get_error_message(); } // Add cart_items to all_cart_items array $all_cart_items[] = $cart_items; } if (!$subscription) { // Save updated tax totals $this->update_tax_totals($tax_total, $shipping_tax_total); // Update TaxCloud IDs array WT_Orders::update_meta($this->order_id, 'taxcloud_ids', $taxcloud_ids); // Reset identifiers array (only useful before first lookup from "edit order" screen) WT_Orders::update_meta($this->order_id, 'identifiers', array()); // Store mapping array in reverse order (map item ids to item indexes) $new_mapping_array = array(); foreach ($mapping_array as $location => $mappings) { foreach ($mappings as $item_index => $item_id) { if (!isset($new_mapping_array[$location])) { $new_mapping_array[$location] = array(); } $new_mapping_array[$location][$item_id] = $item_index; } } WT_Orders::update_meta($this->order_id, 'mapping_array', $new_mapping_array); // Update index/location mappings foreach ($lookup_data as $address_key => $items) { foreach ($items as $item) { $item_id = $item['ItemID']; if ($item_id == WT_SHIPPING_ITEM) { // WC 2.1 shipping WT_Orders::update_meta($this->order_id, 'shipping_index', $item['Index']); } else { wc_update_order_item_meta($item_id, '_wootax_location_id', $address_key); wc_update_order_item_meta($item_id, '_wootax_index', $item['Index']); } } } } // Return CartItems $return_arr = array(); foreach ($all_cart_items as $cart_items) { $return_arr = array_merge($return_arr, $cart_items); } return $return_arr; } else { return 'An error occurred while calculating order taxes. It is possible that the order has already been "completed" or that no customer shipping address is available. Please try again.'; } }
/** * Perform a tax lookup for the user's cart * * @since 4.2 */ public function do_lookup() { // Remove currently applied taxes $this->remove_tax(); // Retrieve validated destination addresses $destination_address = maybe_validate_address($this->destination_address); // Define some variable used in every tax lookup $tax_array = array(); $lookup_data = array(); $tax_total = 0; $shipping_tax_total = 0; // Fetch some information about this order $exempt_cert = $this->get_exemption_certificate(); $customer_id = $this->get_customer_id(); $delivered_by_seller = wt_is_local_delivery($this->get_shipping_method()); // Loop through locations in lookup_data array and send a Lookup request for each foreach ($this->lookup_data as $location_key => $items) { $lookup_data[$location_key] = $items; // Fetch cart_id $cart_id = isset($this->taxcloud_ids[$location_key]) ? $this->taxcloud_ids[$location_key]['cart_id'] : ''; // Get the origin address $origin_address = wootax_get_address($location_key); // Build Lookup request (cartID empty for first request) $req = array('customerID' => $customer_id, 'cartID' => $cart_id, 'cartItems' => $items, 'origin' => $origin_address, 'destination' => $destination_address, 'deliveredBySeller' => $delivered_by_seller); if (!empty($exempt_cert)) { $req['exemptCert'] = $exempt_cert; } // Send Lookup request $res = $this->taxcloud->send_request('Lookup', $req); if ($res !== false) { // Initialize some vars $cart_items = $res->CartItemsResponse->CartItemResponse; // Store cartID to improve efficiency of subsequent lookup requests $this->taxcloud_ids[$location_key]['cart_id'] = $res->CartID; // If cart_items only contains one item, it will not be an array. // In that case, convert to an array to avoid the need for extra code if (!is_array($cart_items)) { $cart_items = array($cart_items); } // Loop through items and update tax amounts foreach ($cart_items as &$cart_item) { // Fetch item info $index = $cart_item->CartItemIndex; $tax = $cart_item->TaxAmount; $type = $this->mapping_array[$location_key][$index]['type']; // Update item tax switch ($type) { case 'cart': $item_id = $this->mapping_array[$location_key][$index]['key']; // Identifier is cart item key $this->apply_item_tax($item_id, $tax); $tax_total += $tax; break; case 'shipping': $item_id = WT_SHIPPING_ITEM; // Identifier is SHIPPING $shipping_tax_total += $tax; break; case 'fee': $item_id = $this->mapping_array[$location_key][$index]['index']; // Identifier is cart fee index $this->apply_fee_tax($item_id, $tax); $tax_total += $tax; break; } // Add item tax to cart_taxes array $this->cart_taxes[$item_id] = $tax; // Map item id to location $this->location_mapping_array[$item_id] = $location_key; } } else { // We will not display ZIP mismatch errors or SoapFaults. These messages tend to be disruptive and there is not much the customer can do to resolve them. $error = $this->taxcloud->get_error_message(); if (strpos($error, 'zip') === false && strpos($error, 'SoapFault') === false) { wc_add_notice('An error occurred while calculating the tax for this order. ' . $error, 'error'); } return; } } // Update item identifiers $this->update_item_identifiers(); // Save updated tax totals $this->update_tax_totals($tax_total, $shipping_tax_total); // Set value of lookup_sent to prevent duplicate lookups $this->lookup_sent = $this->get_order_hash(); // Save checkout data in session $this->save_session_data(); }