<?php
// Check to ensure this file is included in Freeway!
defined('_FEXEC') or die();
/*
  Version 1.1 for MS1

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2003 Steve Fatula of Fatula Consulting
  compconsultant@yahoo.com

  Released under the GNU General Public License
*/

// Be sure and set the following defines for your information
define('MODULE_SHIPPING_FEDEX1_ADDRESS_1', '1204 Edmonton Trail NE'); // Required
define('MODULE_SHIPPING_FEDEX1_ADDRESS_2', ''); // Optional
define('MODULE_SHIPPING_FEDEX1_CITY', ''); // Required
define('MODULE_SHIPPING_FEDEX1_STATE', ''); // Required for US or CA, 2 letter code
define('MODULE_SHIPPING_FEDEX1_PHONE', '9721112234'); // Required
define('MODULE_SHIPPING_FEDEX1_PAGER', ''); // Optional
define('MODULE_SHIPPING_FEDEX1_EMAIL', ''); // Optional
define('MODULE_SHIPPING_FEDEX1_FAX', ''); // Optional

  class fedex1 {
    var $code, $title, $description, $icon, $enabled, $meter, $intl;

// class constructor
    function fedex1() {
      $this->code = 'fedex1';
      $this->title = MODULE_SHIPPING_FEDEX1_TEXT_TITLE;
      $this->description = MODULE_SHIPPING_FEDEX1_TEXT_DESCRIPTION;
      $this->sort_order = MODULE_SHIPPING_FEDEX1_SORT_ORDER;
      $this->icon = DIR_WS_ICONS . 'shipping_fedex.gif';
      $this->tax_class = MODULE_SHIPPING_FEDEX1_TAX_CLASS;
      $this->enabled = ((MODULE_SHIPPING_FEDEX1_STATUS == 'True') ? true : false);
      $this->meter = MODULE_SHIPPING_FEDEX1_METER;

// You can comment out any methods you do not wish to quote
      $this->domestic_types = array('01' => 'Priority',
                                    '03' => '2 Day Air',
                                    '05' => 'Standard Overnight',
                                    '06' => 'First Overnight', 
                                    '20' => 'Express Saver',
                                    '90' => 'Home Delivery',
                                    '92' => 'Ground Service');

      $this->international_types = array('01' => 'International Priority',
                                         '03' => 'International Economy',
                                         '06' => 'International First',
                                         '90' => 'Home Delivery',
                                         '92' => 'Ground Service');
    }

// class methods
    function quote($method = '') {
      global $shipping_weight, $shipping_num_boxes, $cart, $order;

      if (tep_not_null($method)) {
        $this->_setService($method);
      }
      $this->_setWeight($shipping_weight);
      $totals = $cart->show_total();
      $this->_setInsuranceValue($totals / $shipping_num_boxes);

      $fedexQuote = $this->_getQuote();

      if (is_array($fedexQuote)) {
        if (isset($fedexQuote['error'])) {
          $this->quotes = array('module' => $this->title,
                                'error' => $fedexQuote['error']);
        } else {
          $this->quotes = array('id' => $this->code,
                                'module' => $this->title . ' (' . $shipping_num_boxes . ' x ' . $shipping_weight . 'lbs)');

          $methods = array();
          foreach ($fedexQuote as $type => $cost) {
            $skip = FALSE;
            if ($this->intl === FALSE) {
              $service_descr = $this->domestic_types[$type];
              switch ($type) {
                case 90:
                  if ($order->delivery['company'] != '') {
                    $skip = TRUE;
                  }
                  break;
                case 92:
                  if ($order->delivery['company'] == '') {
                    $skip = TRUE;
                  }
                  break;
              }
            } else {
             $service_descr = $this->international_types[$type];
            }
            if ($method) {
              if ($type != $method) $skip = TRUE;
            }
            if (!$skip) {

              $methods[] = array('id' => $type,
                                 'title' => $service_descr,
                                 'cost' => (SHIPPING_HANDLING + MODULE_SHIPPING_FEDEX1_SURCHARGE + $cost) * $shipping_num_boxes);
            }
          }

          $this->quotes['methods'] = $methods;
          if ($this->tax_class > 0) {
            $this->quotes['tax'] = tep_get_tax_rate($this->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']);
          }
        }
      } else {
        $this->quotes = array('module' => $this->title,
                              'error' => 'An error occured with the fedex shipping calculations.<br>Fedex may not deliver to your country, or your postal code may be wrong.');
      }

      if (tep_not_null($this->icon)) $this->quotes['icon'] = tep_image($this->icon, $this->title);

      return $this->quotes;
    }

    function check() {
      if (!isset($this->_check)) {
        $check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_SHIPPING_FEDEX1_STATUS'");
        $this->_check = tep_db_num_rows($check_query);
      }
      return $this->_check;
    }

    function install() {
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Fedex Shipping', 'MODULE_SHIPPING_FEDEX1_STATUS', 'True', 'Do you want to offer Fedex shipping?', '6', '10', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Enter the Fedex Account Number', 'MODULE_SHIPPING_FEDEX1_ACCOUNT', 'NONE', 'Enter the fedex Account Number assigned to you.', '6', '11', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Enter the Fedex Meter ID', 'MODULE_SHIPPING_FEDEX1_METER', 'NONE', 'Enter the Fedex MeterID assigned to you, set to NONE to get a meter number', '6', '12', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Enter Fedex Server URL (without leading https://, do not append the port)', 'MODULE_SHIPPING_FEDEX1_SERVER', 'NONE', 'Obtain the test and production server urls from Fedex', '6', '13', now())");
	  tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Fedex Drop off type', 'MODULE_SHIPPING_FEDEX1_DROPOFF', '1', 'Dropoff type (1 = Regular pickup, 2 = request coutier, 3 = drop box, 4 = drop at BSC, 5 = drop at station)?', '6', '14', now())");
	  tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Fedex surcharge?', 'MODULE_SHIPPING_FEDEX1_SURCHARGE', '0', 'Surcharge amount to add to shipping charge?', '6', '15', now())");
	  tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Fedex Insurance Over?', 'MODULE_SHIPPING_FEDEX1_INSURE', 'NONE', 'Insure packages over what dollar amount?', '6', '16', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Fedex Tax Class', 'MODULE_SHIPPING_FEDEX1_TAX_CLASS', '0', 'Use the following tax class on the shipping fee.', '6', '17', 'tep_get_tax_class_title', 'tep_cfg_pull_down_tax_classes(', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Fedex Sort Order', 'MODULE_SHIPPING_FEDEX1_SORT_ORDER', '6', 'Sort order of display.', '6', '18', now())");
    }

    function remove() {
      tep_db_query("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");
    }

    function keys() {
      return array('MODULE_SHIPPING_FEDEX1_STATUS', 'MODULE_SHIPPING_FEDEX1_ACCOUNT', 'MODULE_SHIPPING_FEDEX1_METER', 'MODULE_SHIPPING_FEDEX1_SERVER', 'MODULE_SHIPPING_FEDEX1_DROPOFF', 'MODULE_SHIPPING_FEDEX1_SURCHARGE', 'MODULE_SHIPPING_FEDEX1_INSURE','MODULE_SHIPPING_FEDEX1_TAX_CLASS','MODULE_SHIPPING_FEDEX1_SORT_ORDER');
    }

    function _setService($service) {
      $this->service = $service;
    }

    function _setWeight($pounds) {
      $this->pounds = ($pounds < 1 ? "1.0" : sprintf("%01.1f", $pounds));
    }

    function _setInsuranceValue($order_amount) {
      if ($order_amount > MODULE_SHIPPING_FEDEX1_INSURE) {
        $this->insurance = sprintf("%01.2f",$order_amount);
      } else {
        $this->insurance = 0;
      }
    }

    function _AccessFedex($data) {
     // $ch = curl_init();
    /*  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
      curl_setopt($ch, CURLOPT_VERBOSE, 1);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_URL, 'https://' . MODULE_SHIPPING_FEDEX1_SERVER);
      curl_setopt($ch, CURLOPT_HTTPHEADER, array("Referer: " . STORE_NAME,
                                                 "Host: " . MODULE_SHIPPING_FEDEX1_SERVER,
                                                 "Accept: image/gif,image/jpeg,image/pjpeg,text/plain,text/html,**",
                                                 "Pragma:",
                                                 "Content-Type:image/gif"));
      curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
      $reply = curl_exec($ch);
      curl_close ($ch);
      return $reply;*/
    }

    function _getMeter() {
      $data = '0,"211"'; // Transaction Code, required
      $data .= '10,"' . MODULE_SHIPPING_FEDEX1_ACCOUNT . '"'; // Sender Fedex account number
      $data .= '4003,"' . STORE_OWNER . '"'; // Subscriber contact name
      $data .= '4007,"' . STORE_NAME . '"'; // Subscriber company name
      $data .= '4008,"' . MODULE_SHIPPING_FEDEX1_ADDRESS_1 . '"'; // Subscriber Address line 1
      if (MODULE_SHIPPING_FEDEX1_ADDRESS_2 != '') {
        $data .= '4009,"Address Line 2"'; // Subscriber Address Line 2
      }
      $data .= '4011,"' . MODULE_SHIPPING_FEDEX1_CITY . '"'; // Subscriber City Name
      if (MODULE_SHIPPING_FEDEX1_STATE != '') {
        $data .= '4012,"' . MODULE_SHIPPING_FEDEX1_STATE . '"'; // Subscriber State code
      }
      $data .= '4013,"' . SHIPPING_ORIGIN_ZIP . '"'; // Subscriber Postal Code 
      $countries_array = tep_get_countries(SHIPPING_ORIGIN_COUNTRY,true); 
      $countries_code = $countries_array['countries_iso_code_2']; 
      $data .= '4014,"' . $countries_code . '"'; // Subscriber Country Code 

      $data .= '4015,"' . MODULE_SHIPPING_FEDEX1_PHONE . '"'; // Subscriber phone number
      if (MODULE_SHIPPING_FEDEX1_PAGER != '') {
        $data .= '4017,"' . MODULE_SHIPPING_FEDEX1_PAGER . '"'; // Subscriber pager number
      }
      if (MODULE_SHIPPING_FEDEX1_EMAIL != '') {
        $data .= '4018,"' . MODULE_SHIPPING_FEDEX1_EMAIL . '"'; // Subscriber email address
      }
      if (MODULE_SHIPPING_FEDEX1_FAX != '') {
        $data .= '4022,"' . MODULE_SHIPPING_FEDEX1_FAX . '"'; // Subscriber fax number
      }
      $data .= '99,""'; // End of Record, required
      $fedexData = $this->_AccessFedex($data);
      $meterStart = strpos($fedexData,'"498,"');

      if (!($meterStart === FALSE)) {
        $meterStart += 6;
        $meterEnd = strpos($fedexData, '"', $meterStart);
        $this->meter = substr($fedexData, $meterStart, $meterEnd - $meterStart);
	$meter_sql = "UPDATE configuration SET configuration_value=\"" . $this->meter . "\" where configuration_key=\"MODULE_SHIPPING_FEDEX1_METER\"";
	tep_db_query($meter_sql);
      }

      return;
    }

    function _ParseFedex($data) {
      $current = 0;
      $length = strlen($data);
      $resultArray = array();
      while ($current < $length) {
        $endpos = strpos($data, ',', $current);
        if ($endpos === FALSE) { break; }
        $index = substr($data, $current, $endpos - $current);
        $current = $endpos + 2;
        $endpos = strpos($data, '"', $current);
        $resultArray[$index] = substr($data, $current, $endpos - $current);
        $current = $endpos + 1;
      }
    return $resultArray;
    }
     
    function _getQuote() {
      global $order, $customer_id, $sendto;

      if (MODULE_SHIPPING_FEDEX1_METER == "NONE") { 
        $this->_getMeter();
      }

      $data = '0,"25"'; // TransactionCode, required;
      $data .= '10,"' . MODULE_SHIPPING_FEDEX1_ACCOUNT . '"'; // Sender fedex account number
      $data .= '498,"' . $this->meter . '"'; // Meter number
      $data .= '8,"' . MODULE_SHIPPING_FEDEX1_STATE . '"'; // Sender state code
      $data .= '9,"' . SHIPPING_ORIGIN_ZIP . '"'; // Origin postal code 
      $countries_array = tep_get_countries(SHIPPING_ORIGIN_COUNTRY, true); 
      $countries_code = $countries_array['countries_iso_code_2']; 
      $data .= '117,"' . $countries_code . '"'; // Origin country 
      if ($order->delivery['country']['iso_code_2'] == "US" || $order->delivery['country']['iso_code_2'] == "CA" || $order->delivery['country']['iso_code_2'] == "PR") {
        $dest_zip = str_replace(' ', '', $order->delivery['postcode']);
        $data .= '17,"' . $dest_zip . '"'; // Recipient zip code
      }
      $data .= '50,"' . $order->delivery['country']['iso_code_2'] . '"'; // Recipient country
      $data .= '75,"LBS"'; // Weight units
      $data .= '1116,"I"'; // Dimension units
      $data .= '1401,"' . $this->pounds . '"'; // Total weight
      if ($this->insurance > 0) {
        $data .= '1415,"' . $this->insurance . '"'; // Insurance value
        $data .= '68,"USD"'; // Insurance value currency
      }
      if ($order->delivery['company'] == '') {
        $data .= '440,"Y"'; // Residential address
      }
      $data .= '1333,"' . MODULE_SHIPPING_FEDEX1_DROPOFF . '"'; // Drop of drop off or pickup
      $data .= '99,""'; // End of record
      $fedexData = $this->_AccessFedex($data);
      $fedexData = $this->_ParseFedex($fedexData);
      $i = 1;
      if (STORE_COUNTRY == $order->delivery['country']['id']) {
        $this->intl = FALSE;
      } else {
        $this->intl = TRUE;
      }
      $rates = array();
      while (isset($fedexData['1274-' . $i])) {
        if ($this->intl) {
          if (isset($this->international_types[$fedexData['1274-' . $i]])) {
            $rates[$fedexData['1274-' . $i]] = $fedexData['1419-' . $i];
          }
        } else {
          if (isset($this->domestic_types[$fedexData['1274-' . $i]])) {
            $rates[$fedexData['1274-' . $i]] = $fedexData['1419-' . $i];
          }
        }
        $i++;
      }

      if (is_array($rates)) asort($rates);

      return ((sizeof($rates) > 0) ? $rates : false);
    }
  }
?>
