<?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();
}
}
}
?>