API Docs for: WebTemplate API v2.0
Show:

File: /data/www/webtemplate/wtv2/codedoc/wtFreight.php

<?php
/**
 *  WebTemplate Core
 *
 *  @version 2.0
 *  @module WebTemplate Core
 */


$GLOBALS["WTFREIGHTFUNCTION"] = null;


/**
 *  The class used to calculate Freight for Orders
 *
 *  @class WTFreight
 */
class WTFreight
{

  /**
   *  Register a custom function to calculate freight
   *
   *  @method registerFreightFunction  
   *  @static 
   *  @param {Function} function The custom function, which should return the cost of freight in dollars and cents
   *
   */
  static function registerFreightFunction($function) 
  {
    $GLOBALS["WTFREIGHTFUNCTION"] = $function;

  }

  static function countryToZone($country) {
    $sql = "SELECT
              zone
            FROM
              dbCountries.tblCountry
            WHERE
              countryName = '" . mysql_escape_string($country) . "'";
    $query = mysql_query($sql);
    if($row = mysql_fetch_row($query)) {
      return $row[0];
    }

    return false;
  }  


  /**
   *  Return the Australian state for a postcode
   *
   *  @method postcodeToState
   *  @static
   *  @param {String} postcode The postcode to find
   *  @return {String} The state the postcode belongs to
   */
  static function postcodeToState($postcode) 
  {

    if( $postcode == 2899 ) {
      return "Norfolk";
    }

    if( $postcode == 6798 ) {
      return "CHRISTMASIS";
    }

    if( $postcode == 6799) {
      return "COCOSIS";
    }

    if( ($postcode >= 1000 && $postcode <= 2599) || 
        ($postcode >= 2620 && $postcode <= 2898) || 
        ($postcode >= 2921 && $postcode <= 2999) ) {
      return "NSW";
    }

    if( ($postcode >= 200 && $postcode <= 299) ||
        ($postcode >= 2600 && $postcode <= 2619) || 
        ($postcode >= 2900 && $postcode <= 2920) ) {
      return "ACT";
    }

    if( ($postcode >= 3000 && $postcode <= 3999) || 
        ($postcode >= 8000 && $postcode <= 8999) ) {
      return "VIC";
    }

    if( ($postcode >= 4000 && $postcode <= 4999) ||
        ($postcode >= 9000 && $postcode <= 9999) ) {
      return "QLD";
    }

    if( ($postcode >= 5000 && $postcode <= 5799) || 
        ($postcode >= 5800 && $postcode <= 5999) ) {
      return "SA";
    }

    if( ($postcode >= 6000 && $postcode <= 6797) ||
        ($postcode >= 6800 && $postcode <= 6999) ) {
      return "WA";
    }

    if( ($postcode >= 7000 && $postcode <= 7799) ||
        ($postcode >= 7800 && $postcode <= 7999) ) {
      return "TAS";
    }

    if( ($postcode >= 800 && $postcode <= 899) ||
        ($postcode >= 900 && $postcode <= 999) ) {
      return "NT";
    }
   
  }

  /**
   *  Get a carriers Australian zone for a postcode
   *
   *  @method getDomesticZone
   *  @static
   *  @param {int} carrierGuid The guid of the carrier
   *  @param {String} postcode The postcode
   *  @return {int} The id of the zone, or 0 if no zone found
   */
  static function getDomesticZone($carrierGuid, $postcode)
  {
    if(!is_numeric($postcode)) {
      return 0;
    }
    $sql = "SELECT
              freightZoneGuid
            FROM
              tblFreightZoneArea,
              `Freight Zone`,
              wtNode
            WHERE
              tblFreightZoneArea.freightZoneGuid = `Freight Zone`.__guid
              AND `Freight Zone`.__guid = wtNode.__guid
              AND wtNode.__parentGuid = $carrierGuid
              AND lowerPostcode <= $postcode AND higherPostcode >= $postcode
              AND wtNode.__deleted = 0";

    $query = mysql_query($sql);
    if($row = mysql_fetch_row($query)) {
      return $row[0];
    }
    return 0;
  }
  

  /**
   *  Get the id of the weight range a weight (in grams) belongs to
   *
   *  @method getWeightRange
   *  @static
   *  @param {int} weight The weight in grams
   *  @return {int} The id of the weight range, or 0 if no range found
   */
  static function getWeightRange($weight)
  {
    $sql = "SELECT
              __guid
            FROM
              `Freight Weight Range`
            WHERE
              Low <= $weight AND High >= $weight";
    $query = mysql_query($sql);
    if($row = mysql_fetch_row($query)) {
      return $row[0];
    }
    return 0;
  }


  /**
   *  Return true if can deliver to the postcode in args
   *
   *  @method getCanDeliver
   *  @static
   *  @param {Array} args Possible keys: "postcode"
   *  @return {boolean} returns true if can deliver
   */
  static function getCanDeliver($args) 
  {
    if($GLOBALS["WTFREIGHTFUNCTION"]) {
      $result = call_user_func($GLOBALS["WTFREIGHTFUNCTION"], $args);
      if($result === false ) {
        return false;
      }
      return true;
    }

    $freightModelNode = $GLOBALS["WT"]->getNode("/Config/Settings/Orders/Freight Model");
    $freightModel = $freightModelNode->getAttribute("Value");

    $q = Array();
    $q["Path"] = "Products/Freight/*";
    $q["Limit"] = 1;
    $q["Select"] = "`Freight Carrier`.__guid";
    $q["Node Type"] = "Freight Carrier";

    $carrierGuid = $GLOBALS["WT"]->query($q, "singleValueCallback");
    $carrier = $GLOBALS["WT"]->getNode($carrierGuid);

    switch($freightModel) {
      case 'None':
        return true;
        break;
      case 'Freight Rules':
        return true;
        break;
      case 'Per Zone':
      case 'Per Weight Per Zone': 
        $postcode = $args["postcode"];
        $freightZoneGuid = WTFreight::getDomesticZone($carrierGuid, $postcode);
        if(!$freightZoneGuid) {
          return false;
        }              
        return true;
        break;  
    }
  }

  /**
   *  Get the charge for freight
   *  
   *  @param {Array} args Associative array with keys: "weight", "postcode", "order value", "quantity"
   *  @return {float} Returns the charge for the freight
   */
  static function getCharge($args)
  {
    if($GLOBALS["WTFREIGHTFUNCTION"]) {
      return call_user_func($GLOBALS["WTFREIGHTFUNCTION"], $args);
    }

    $freightModelNode = $GLOBALS["WT"]->getNode("/Config/Settings/Orders/Freight Model");
    $freightModel = $freightModelNode->getAttribute("Value");

    if(array_key_exists("Freight Carrier ID", $args) && $args["Freight Carrier ID"]) {

      $carrierGuid = $args["Freight Carrier ID"];

    } else {

      $q = Array();
      $q["Path"] = "Products/Freight/*";
      $q["Limit"] = 1;
      $q["Select"] = "`Freight Carrier`.__guid";
      $q["Node Type"] = "Freight Carrier";

      $carrierGuid = $GLOBALS["WT"]->query($q, "singleValueCallback");
    }
    $carrier = $GLOBALS["WT"]->getNode($carrierGuid);



    switch($freightModel) {
      case 'None':
        return 0;
        break;
      case 'Freight Rules':
        $postcode = $args["postcode"];
        $orderValue = $args["order value"];

        $freightZoneGuid = WTFreight::getDomesticZone($carrierGuid, $postcode);


        if($GLOBALS["WTSITEID"] == 11288 || $GLOBALS["WTSITEID"] == 11393 || $GLOBALS["WTSITEID"] == 11498 || $GLOBALS["WTSITEID"] == 11586) { //D'Arenberg 2008, and Shingleback Winery,Key Brothers Pty Ltd,Kiddylicious
          $q = Array();
          $q["Node Type"] = "Freight Rule";
          $q["Select"] = "`Freight Rule`.__guid";
          $q["Criteria"] = "(`Order Value Rule` = 'Any' OR (`Order Value From` <= $orderValue AND `Order Value To` >= $orderValue)) AND (`Zone ID` = 0 OR `Zone ID` = $freightZoneGuid)";
          $q["Limit"] = 1;
          $freightGuid = $GLOBALS["WT"]->query($q, "singleValueCallback");


          if($freightGuid) {
            $freightRule = $GLOBALS["WT"]->getNode($freightGuid);
            if($freightRule) {
              $quantityRule = $freightRule->getAttribute("Order Quantity Rule");
              $charge = $freightRule->getAttribute("Charge");

              if($quantityRule == "Per") {
                $perquantity = $freightRule->getAttribute("Order Quantity");
                $quantity = $args["quantity"];
                $lots = ceil($quantity / $perquantity);
                return $lots * $charge;
              } else {

                return $charge;
              }
            }
          }
          return false;

        } else {
          $hasWeight = false;
          $weightRule = $GLOBALS["WT"]->getNode("/Config/Node Types/Freight Rule/Order Weight Rule");
          $hasWeight = $weightRule != NULL;

          $q = Array();
          $q["Node Type"] = "Freight Rule";
          $q["Select"] = "Charge";
          $q["Path"] = "$carrierGuid/*";
          $q["Criteria"] = "(`Order Value Rule` = 'Any' OR (`Order Value From` <= $orderValue AND `Order Value To` >= $orderValue)) AND (`Zone ID` = 0 OR `Zone ID` = $freightZoneGuid)";
          if($hasWeight) {
            $weight = (int)$args["weight"];
            $q["Criteria"] .= " AND (`Order Weight Rule` = 'Any' OR (`Order Weight From` <= $weight AND `Order Weight To` >= $weight)) ";  
          }
          $q["Limit"] = 1;
          $q["Select"] = "COUNT(*)";
          $matchingRules = $GLOBALS["WT"]->query($q, "singleValueCallback");
          if($matchingRules == 0) {
            return false;
          }
          $q["Select"] = "Charge";
          $freight = $GLOBALS["WT"]->query($q, "singleValueCallback");
        }
        return $freight;
        break;
      case 'Per Zone':
        $postcode = $args["postcode"];
        $freightZoneGuid = WTFreight::getDomesticZone($carrierGuid, $postcode);
        if($freightZoneGuid != 0) {
          $freightZone = $GLOBALS["WT"]->getNode($freightZoneGuid);
          return $freightZone->getAttribute("Zone Charge");
        } else {
          return false;
        }
        break;
      case 'Per Weight Per Zone':
        $postcode = $args["postcode"];      
        $weight = $args["weight"];


/*        if($weight == 0) {
          $weight = 1;
        }*/

        $freightZoneGuid = WTFreight::getDomesticZone($carrierGuid, $postcode);
        $freightWeightRangeGuid = WTFreight::getWeightRange($weight);

        if($freightZoneGuid != 0 && $freightWeightRangeGuid != 0) {
          $sql = "SELECT
                    charge
                  FROM
                    tblFreightCharge
                  WHERE
                    carrierGuid = $carrierGuid 
                    AND freightZoneGuid = $freightZoneGuid
                    AND weightRangeGuid = $freightWeightRangeGuid";
          $query = mysql_query($sql);
          if($row = mysql_fetch_row($query)) {
            return $row[0];
          }
        }
        return false;      
                    
        break;
    }
    return 0;
  }

}

class WTFreightZone extends WTNode
{

  function setAttributes($attributes) {
    $prevZoneData = $this->getAttribute("Zone Data");
    parent::setAttributes($attributes);
    $this->setZoneData($prevZoneData);
  }

  function freightJavascript() {
    ob_start();
?>
<script language="javascript">

var g_countries = Array();
<?php
  $sql = "SELECT
            countryID, countryName
          FROM
            dbCountries.tblCountry
          ORDER BY
            countryID";
   $query = mysql_query($sql);
   while($row = mysql_fetch_array($query)) {
?>
g_countries[<?= $row[0] ?>] = "<?= $row[1] ?>";
<?php
   }
?>

var g_zoneCountries = Array();

function renderZoneCountries() {
  var html = '<table class="datatable">';
  for(var i = 0;i < g_zoneCountries.length; i++) {
    html += '<tr><td>' + g_countries[g_zoneCountries[i]] + '</td></tr>';
  }
  html += "</table>";
  var countriesElement = document.getElementById("countries");
  countriesElement.innerHTML = html;
}

function addCountry() {
  var countryIDElement = document.getElementById("countryID");
  var countryID = countryIDElement.value;
  g_zoneCountries[g_zoneCountries.length] = countryID;
  renderZoneCountries();
}
</script>
<?php
    $contents = ob_get_contents();
    ob_end_clean();
    return $contents;
  }

  function getFormAttributeHTML($attributeInfo, $values) {
    $freightModelNode = $GLOBALS["WT"]->getNode("/Config/Settings/Orders/Freight Model");
    $freightModel = $freightModelNode->getAttribute("Value");
    if($attributeInfo["Attribute Name"] == "Zone Charge" && $freightModel != "Per Zone") {
      return "";
    }

    if($attributeInfo["Attribute Name"] == "Zone Data") {
      $carrierGuid = $GLOBALS["WT"]->getRequestValue("carrierGuid", 0);
      if($carrierGuid != 0) {
        $carrier = $GLOBALS["WT"]->getNode($carrierGuid);
        $type = $carrier->getAttribute("Type"); 
        if($type == "International") {
          $label = "Zone Data:";
          $control = WTFreightZone::freightJavascript();
          $control .= '<div id="countries"></div>';
          $control .= '<select name="countryID" id="countryID">';
          $sql = "SELECT
                    countryID, countryName
                  FROM
                    dbCountries.tblCountry
                  ORDER BY
                    countryName";
          $query = mysql_query($sql);
          while($row = mysql_fetch_row($query)) {
            $control .= '<option value="' . $row[0] . '">' . $row[1] . '</option>';
          }
          $control .= '</select> <input type="button" value="Add" onclick="addCountry()">';
 
          return WTNode::getFormRowHTML($label, $control);
        } else {
          $label = '<label for="attr' . $attributeInfo["__guid"] . '">Postcode Ranges</label>:';
          $control = '<textarea name="attr' . $attributeInfo["__guid"] . '" id="attr' . $attributeInfo["__guid"] . '" rows="5" cols="30">' . htmlEntities($values["Zone Data"]) . '</textarea>';
          return WTNode::getFormRowHTML($label, $control);
        }
   
      }
    }

    return parent::getFormAttributeHTML($attributeInfo, $values);
  }


  function setCharge($weightRangeGuid, $charge) {
    $sql = "SELECT
              COUNT(*) 
            FROM
              tblFreightCharge
            WHERE
              weightRangeGuid = $weightRangeGuid
              AND freightZoneGuid = {$this->m_guid}";
    $query = mysql_query($sql);
    $row = mysql_fetch_row($query);
    if($row[0] == 0) {
      $sql = "INSERT INTO
                tblFreightCharge
              SET
                carrierGuid = {$this->m_parentGuid},
                weightRangeGuid = $weightRangeGuid,
                freightZoneGuid = {$this->m_guid},
                charge = $charge";                            
    } else {
      $sql = "UPDATE
                tblFreightCharge
              SET
                charge = $charge
              WHERE
                weightRangeGuid = $weightRangeGuid
                AND freightZoneGuid = {$this->m_guid}";
    }
    if(!mysql_query($sql)) {
      print "<br>" . $sql . "<br>";
      print mysql_error();
    }
  }

  function getCharge($carrierGuid, $weight) {
    return 111;
  }

  function setZoneData($prevZoneData) {
    $zoneData = $this->getAttribute("Zone Data");
    if($zoneData == $prevZoneData) {
      return;
    }

    $postcodeArray = explode(",", $zoneData);

    $sql = "DELETE FROM
              tblFreightZoneArea
            WHERE
              freightZoneGuid = {$this->m_guid}";
    if(!mysql_query($sql)) {
      print $sql; 
      print mysql_error();
    }
    foreach($postcodeArray as $postcode) {
      $lowerPostcode = 0;
      $higherPostcode = 0;
      if(strpos($postcode, "-") !== false) {
        list($lower, $higher) = explode("-", $postcode);
        $lowerPostcode = (int)$lower;
        $higherPostcode = (int)$higher;
        if($lowerPostcode > $higherPostcode) {
          $lowerPostcode = (int)$higher;
          $higherPostcode = (int)$lower;
        }
      } else {
        if(is_numeric($postcode)) {
          $lowerPostcode = (int)$postcode;
          $higherPostcode = (int)$postcode;
        }
      }
      if($lowerPostcode != 0 && $higherPostcode != 0) {
        $sql = "INSERT INTO
                  tblFreightZoneArea
                SET
                  freightZoneGuid = {$this->m_guid},
                  lowerPostcode = $lowerPostcode,
                  higherPostcode = $higherPostcode";
        if(!mysql_query($sql)) {
          print $sql;
          print mysql_error();
        }  
      }
    }
    $zoneData = "";
    $sql = "SELECT
              lowerPostcode, higherPostcode
            FROM
              tblFreightZoneArea
            WHERE
              freightZoneGuid = {$this->m_guid}
            ORDER BY
              lowerPostcode";
    $query = mysql_query($sql);
    while($row = mysql_fetch_row($query)) {
      $lower = $row[0];
      $higher = $row[1];
      if($zoneData != "") {
        $zoneData .= ", ";
      }
      if($lower == $higher) {
        $zoneData .= $lower;
      } else {
        $zoneData .= "$lower-$higher";
      }
    }
    $sql = "UPDATE
              `Freight Zone`
            SET
              `Zone Data` = '$zoneData'
            WHERE
              __guid = {$this->m_guid}";
    if(!mysql_query($sql)) {
      print mysql_error();
    }
     
  }
}
?>