/**
  * template method that determines the algorithm to send data to and from the shipping
  * server. This method should be called from the implementing classes calculate shipping
  * function.
  */
 protected final function calculate_rate()
 {
     $services_to_use = $this->filter_services();
     $this->has_error = false;
     // canada post will return all services you have chosen in your online account in the response.
     // most configurations happen on canada post site. Therefore any other services that do something
     // similar, we don't want to take the approach that there are services to loop through here.
     if ($services_to_use) {
         foreach ($services_to_use as $current_service) {
             if (!fflcommerce_shipping::show_shipping_calculator() && !(defined('FFLCOMMERCE_CHECKOUT') && FFLCOMMERCE_CHECKOUT)) {
                 $request = '';
                 $this->set_error_message('Please proceed to checkout to get shipping estimates');
             } else {
                 // create request input for shipping service
                 $request = $this->create_mail_request($current_service);
             }
             if ($request) {
                 // send to shipping server and get xml back
                 $post_response = $this->send_to_shipping_server($request);
                 // convert xml into an array
                 $xml_response = $this->convert_xml_to_array($post_response);
                 // sums up the rates from flattened array, and generates amounts.
                 $rate = $this->retrieve_rate_from_response($xml_response);
                 if ($this->has_error()) {
                     fflcommerce_log($xml_response, 'fflcommerce_calculable_shipping');
                 }
                 $this->add_rate($rate, $current_service);
             }
         }
     } else {
         if (!fflcommerce_shipping::show_shipping_calculator() && !(defined('FFLCOMMERCE_CHECKOUT') && FFLCOMMERCE_CHECKOUT)) {
             $request = '';
             $this->set_error_message('Please proceed to checkout to get shipping estimates');
         } else {
             // create request input for shipping service
             $request = $this->create_mail_request();
         }
         if ($request) {
             // send to shipping server and get xml back
             $post_response = $this->send_to_shipping_server($request);
             // convert xml into an array
             $xml_response = $this->convert_xml_to_array($post_response);
             // services are obtained from response
             $services = $this->get_services_from_response($xml_response);
             if (empty($services)) {
                 fflcommerce_log($xml_response, 'fflcommerce_calculable_shipping');
             }
             foreach ($services as $current_service) {
                 $rate = $this->retrieve_rate_from_response($xml_response, $current_service);
                 $this->add_rate($rate, $current_service);
             }
         }
     }
     // service returned an error since no rates were calculated
     if (($this->rates == NULL || !$this->rates) && !$this->has_error()) {
         $this->has_error = true;
     }
 }
    function fflcommerce_shipping_calculator()
    {
        if (fflcommerce_shipping::show_shipping_calculator()) {
            ?>
			<form class="shipping_calculator" action="<?php 
            echo esc_url(fflcommerce_cart::get_cart_url());
            ?>
" method="post">
				<h2><a href="#" class="shipping-calculator-button"><?php 
            _e('Calculate Shipping', 'fflcommerce');
            ?>
<span>&darr;</span></a></h2>
				<section class="shipping-calculator-form">
					<p class="form-row">
						<select name="calc_shipping_country" id="calc_shipping_country" class="country_to_state" rel="calc_shipping_state">
							<?php 
            foreach (fflcommerce_countries::get_allowed_countries() as $key => $value) {
                ?>
								<option value="<?php 
                echo esc_attr($key);
                ?>
" <?php 
                selected(fflcommerce_customer::get_shipping_country(), $key);
                ?>
><?php 
                echo $value;
                ?>
</option>
							<?php 
            }
            ?>
						</select>
					</p>
					<div class="col2-set">
						<p class="form-row col-1">
							<?php 
            $current_cc = fflcommerce_customer::get_shipping_country();
            $current_r = fflcommerce_customer::get_shipping_state();
            $states = fflcommerce_countries::$states;
            if (fflcommerce_countries::country_has_states($current_cc)) {
                // Dropdown
                ?>
								<span>
								<select name="calc_shipping_state" id="calc_shipping_state">
									<option value=""><?php 
                _e('Select a state&hellip;', 'fflcommerce');
                ?>
</option><?php 
                foreach ($states[$current_cc] as $key => $value) {
                    echo '<option value="' . esc_attr($key) . '"';
                    if ($current_r == $key) {
                        echo 'selected="selected"';
                    }
                    echo '>' . $value . '</option>';
                }
                ?>
</select>
							</span>
							<?php 
            } else {
                // Input
                ?>
								<input type="text" class="input-text" value="<?php 
                echo esc_attr($current_r);
                ?>
" placeholder="<?php 
                _e('state', 'fflcommerce');
                ?>
" name="calc_shipping_state" id="calc_shipping_state" />
							<?php 
            }
            ?>
						</p>
						<p class="form-row col-2">
							<input type="text" class="input-text" value="<?php 
            echo esc_attr(fflcommerce_customer::get_shipping_postcode());
            ?>
" placeholder="<?php 
            _e('Postcode/Zip', 'fflcommerce');
            ?>
" title="<?php 
            _e('Postcode', 'fflcommerce');
            ?>
" name="calc_shipping_postcode" id="calc_shipping_postcode" />
						</p>
						<?php 
            do_action('fflcommerce_after_shipping_calculator_fields');
            ?>
					</div>
					<p>
						<button type="submit" name="calc_shipping" value="1" class="button"><?php 
            _e('Update Totals', 'fflcommerce');
            ?>
</button>
					</p>
					<p>
						<?php 
            $available_methods = fflcommerce_shipping::get_available_shipping_methods();
            foreach ($available_methods as $method) {
                for ($i = 0; $i < $method->get_rates_amount(); $i++) {
                    ?>
					<div class="col2-set">
						<p class="form-row col-1">
							<?php 
                    echo '<input type="radio" name="shipping_rates" value="' . esc_attr($method->id . ':' . $i) . '"' . ' class="shipping_select"';
                    if ($method->get_cheapest_service() == $method->get_selected_service($i) && $method->is_chosen()) {
                        echo ' checked>';
                    } else {
                        echo '>';
                    }
                    echo $method->get_selected_service($i);
                    ?>
						<p class="form-row col-2"><?php 
                    if ($method->get_selected_price($i) > 0) {
                        echo fflcommerce_price($method->get_selected_price($i));
                        echo __(' (ex. tax)', 'fflcommerce');
                    } else {
                        echo __('Free', 'fflcommerce');
                    }
                    ?>
					</div>
					<?php 
                }
            }
            ?>
					<input type="hidden" name="cart-url" value="<?php 
            echo esc_attr(fflcommerce_cart::get_cart_url());
            ?>
">
					<?php 
            fflcommerce::nonce_field('cart');
            ?>
				</section>
			</form>
		<?php 
        }
    }
 public static function get_tax_for_display($tax_class)
 {
     $return = false;
     if (fflcommerce_cart::get_tax_amount($tax_class, false) > 0 && fflcommerce_cart::get_tax_rate($tax_class) > 0 || fflcommerce_cart::get_tax_rate($tax_class) !== false) {
         $return = self::$tax->get_tax_class_for_display($tax_class) . ' (' . (double) fflcommerce_cart::get_tax_rate($tax_class) . '%) ';
         // only show estimated tag when customer is on the cart page and no shipping calculator is enabled to be able to change country
         if (!fflcommerce_shipping::show_shipping_calculator() && is_cart()) {
             $return .= '<small>' . sprintf(__('estimated for: %s', 'fflcommerece'), fflcommerce_countries::get_country(fflcommerce_tax::get_customer_country())) . '</small>';
         }
     }
     return $return;
 }