function list_rates(&$d) { global $vmLogger; global $VM_LANG, $CURRENCY_DISPLAY, $mosConfig_absolute_path; /* Read current Configuration */ require_once CLASSPATH . "shipping/" . __CLASS__ . ".cfg.php"; /* * Check the current day and time to determine if it is too late to * ship today. This will have impact on the Saturday delivery * option and the ship date XML field. */ $cur_timestamp = time(); $cur_day_of_week = date('D', $cur_timestamp); $cur_month = date('n', $cur_timestamp); $cur_day_of_month = date('j', $cur_timestamp); $cur_year = date('Y', $cur_timestamp); if ($cur_day_of_week == 'Sun') { /* we don't ship on Sunday */ $shipping_delayed = true; $ship_timestamp = mktime(0, 0, 0, $cur_month, $cur_day_of_month + 1, $cur_year); $ship_delay_msg = $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_NOT_ON_WEEKENDS') . " " . $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_WILL_GO_OUT') . ": " . date('M j, Y', $ship_timestamp); $ship_day = 'Mon'; $ship_date = date('Y-m-d', $ship_timestamp); } else { if ($cur_day_of_week == 'Sat') { /* we don't ship on Saturday */ $shipping_delayed = true; $ship_timestamp = mktime(0, 0, 0, $cur_month, $cur_day_of_month + 2, $cur_year); $ship_delay_msg = $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_NOT_ON_WEEKENDS') . " " . $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_WILL_GO_OUT') . ": " . date('M j, Y', $ship_timestamp); $ship_day = 'Mon'; $ship_date = date('Y-m-d', $ship_timestamp); } else { /* check time */ $shipping_delayed = true; $cur_time = date('Gi'); if ($cur_time > intval(DHL_TOO_LATE)) { /* too late to go out today */ if ($cur_day_of_week == 'Fri') { $ship_timestamp = mktime(0, 0, 0, $cur_month, $cur_day_of_month + 3, $cur_year); $ship_delay_msg = $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_TOO_LATE_TO_SHIP') . " " . $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_WILL_GO_OUT') . ": " . date('M j, Y', $ship_timestamp); $ship_day = 'Mon'; $ship_date = date('Y-m-d', $ship_timestamp); } else { $ship_timestamp = mktime(0, 0, 0, $cur_month, $cur_day_of_month + 1, $cur_year); $ship_delay_msg = $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_TOO_LATE_TO_SHIP') . " " . $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_WILL_GO_OUT') . ": " . date('M j, Y', $ship_timestamp); $ship_day = date('D', $ship_timestamp); $ship_date = date('Y-m-d', $ship_timestamp); } } else { /* it's okay, we can ship today */ $shipping_delayed = false; $ship_day = $cur_day_of_week; $ship_date = date('Y-m-d', $cur_timestamp); } } } $db = new ps_DB(); $cart = $_SESSION['cart']; $q = "SELECT * FROM #__users, #__{vm}_country " . "WHERE user_info_id='" . $d["ship_to_info_id"] . "' AND ( country=country_2_code OR " . "country=country_3_code)"; $db->query($q); if (!$db->next_record()) { $q = "SELECT * FROM #__{vm}_user_info, " . "#__{vm}_country " . "WHERE user_info_id='" . $d["ship_to_info_id"] . "' AND ( country=country_2_code OR " . "country=country_3_code)"; $db->query($q); } if ($d['weight'] == 0) { return true; } $dhl_url = "https://eCommerce.airborne.com/"; if (DHL_TEST_MODE == 'TRUE') { $dhl_url .= "ApiLandingTest.asp"; } else { $dhl_url .= "ApiLanding.asp"; } /* We haven't defined any shipping methods yet. */ $methods = array(); /* determine if we are domestic or international */ $dest_country = $db->f("country_2_code"); $dest_state = $db->f("state"); $is_international = $this->is_international($dest_country, $dest_state); if (!$is_international) { if (DHL_EXPRESS_ENABLED == 'TRUE') { $methods[] = array('service_desc' => $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_EXPRESS'), 'service_code' => 'E', 'special_service' => '', 'package_type' => DHL_DOMESTIC_PACKAGE, 'international' => false); } if (DHL_NEXT_AFTERNOON_ENABLED == 'TRUE') { $methods[] = array('service_desc' => $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_NEXT_AFTERNOON'), 'service_code' => 'N', 'special_service' => '', 'package_type' => DHL_DOMESTIC_PACKAGE, 'international' => false); } if (DHL_SECOND_DAY_ENABLED == 'TRUE') { $methods[] = array('service_desc' => $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_SECOND_DAY'), 'service_code' => 'S', 'special_service' => '', 'package_type' => DHL_DOMESTIC_PACKAGE, 'international' => false); } if (DHL_GROUND_ENABLED == 'TRUE') { $methods[] = array('service_desc' => $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_GROUND'), 'service_code' => 'G', 'special_service' => '', 'package_type' => DHL_DOMESTIC_PACKAGE, 'international' => false); } if (DHL_1030_ENABLED == 'TRUE') { $methods[] = array('service_desc' => $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_1030'), 'service_code' => 'E', 'special_service' => '1030', 'package_type' => DHL_DOMESTIC_PACKAGE, 'international' => false); } // Saturday delivery is only an option on Fridays if (DHL_SATURDAY_ENABLED == 'TRUE' && $ship_day == 'Fri') { $methods[] = array('service_desc' => $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_SATURDAY'), 'service_code' => 'E', 'special_service' => 'SAT', 'package_type' => DHL_DOMESTIC_PACKAGE, 'international' => false); } $shipping_key = DHL_DOMESTIC_SHIPPING_KEY; if (DHL_DOMESTIC_PACKAGE != 'E') { $order_weight = $d['weight'] + floatval(DHL_PACKAGE_WEIGHT); } $content_desc = ''; $duty_value = 0; } else { if (DHL_INTERNATIONAL_ENABLED == 'TRUE') { $methods[] = array('service_desc' => $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_INTERNATIONAL'), 'service_code' => 'IE', 'special_service' => '', 'package_type' => DHL_INTERNATIONAL_PACKAGE, 'international' => true); } /* * XXX * We should really walk through the list of each product in * the order and check for special "harmonizing descriptions" * to build our $content_desc variables. */ $content_desc = DHL_CONTENT_DESC; $duty_value = $this->calc_duty_value($d); $shipping_key = DHL_INTERNATIONAL_SHIPPING_KEY; /* DHL country codes are non-standard, remap them */ $dest_country = $this->remap_country_code($dest_country, $dest_state); if (DHL_INTERNATIONAL_PACKAGE != 'E') { $order_weight = $d['weight'] + floatval(DHL_PACKAGE_WEIGHT); } } /* if we're not on an exact integer pound, round */ if (floatval(intval($order_weight)) != $order_weight) { /* round up */ $order_weight = $order_weight + 0.51; $order_weight = round($order_weight, 0); } /* calculate insurance protection value */ $insurance = $this->calc_insurance_value($d, $is_international); require_once $mosConfig_absolute_path . '/includes/domit/xml_domit_lite_include.php'; $html = ''; if ($shipping_delayed) { $html .= '<span class="message"><strong>'; $html .= $ship_delay_msg; $html .= '</strong></span><br />'; } foreach ($methods as $method) { $xmlReq = new DOMIT_Lite_Document(); $xmlReq->setXMLDeclaration('<?xml version="1.0"?>'); $root =& $xmlReq->createElement('eCommerce'); $root->setAttribute('action', 'Request'); $root->setAttribute('version', '1.1'); $xmlReq->setDocumentElement($root); $requestor =& $xmlReq->createElement('Requestor'); $id =& $xmlReq->createElement('ID'); $id->setText(DHL_ID); $requestor->appendChild($id); $password =& $xmlReq->createElement('Password'); $password->setText(DHL_PASSWORD); $requestor->appendChild($password); $root->appendChild($requestor); /* International Rate Estimate Request */ if ($method['international']) { $shipment =& $xmlReq->createElement('IntlShipment'); } else { $shipment =& $xmlReq->createElement('Shipment'); } $shipment->setAttribute('action', 'RateEstimate'); $shipment->setAttribute('version', '1.0'); $creds =& $xmlReq->createElement('ShippingCredentials'); $ship_key =& $xmlReq->createElement('ShippingKey'); $ship_key->setText($shipping_key); $creds->appendChild($ship_key); $an =& $xmlReq->createElement('AccountNbr'); $an->setText(DHL_ACCOUNT_NUMBER); $creds->appendChild($an); $shipment->appendChild($creds); $detail =& $xmlReq->createElement('ShipmentDetail'); $date =& $xmlReq->createElement('ShipDate'); $date->setText($ship_date); $detail->appendChild($date); $service =& $xmlReq->createElement('Service'); $code =& $xmlReq->createElement('Code'); $code->setText($method['service_code']); $service->appendChild($code); $detail->appendChild($service); $stype =& $xmlReq->createElement('ShipmentType'); $code =& $xmlReq->createElement('Code'); $code->setText($method['package_type']); $stype->appendChild($code); if ($insurance > 0 && DHL_ADDITIONAL_PROTECTION != 'NR') { /* include additional value protection */ $addl_prot =& $xmlReq->createElement('AdditionalProtection'); $code =& $xmlReq->createElement('Code'); $code->setText(DHL_ADDITIONAL_PROTECTION); $addl_prot->appendChild($code); $value =& $xmlReq->createElement('Value'); $value->setText(round($insurance, 0)); $addl_prot->appendChild($value); $detail->appendChild($addl_prot); } $detail->appendChild($stype); if ($method['international']) { $desc =& $xmlReq->createElement('ContentDesc'); /* CDATA description */ $desc_text =& $xmlReq->createCDATASection($content_desc); $desc->appendChild($desc_text); $detail->appendChild($desc); } $weight =& $xmlReq->createElement('Weight'); $weight->setText($order_weight); $detail->appendChild($weight); if ($method['special_service'] != '') { $sservices =& $xmlReq->createElement('SpecialServices'); $service =& $xmlReq->createElement('SpecialService'); $code =& $xmlReq->createElement('Code'); $code->setText($method['special_service']); $service->appendChild($code); $sservices->appendChild($service); $detail->appendChild($sservices); } $shipment->appendChild($detail); if ($method['international']) { $dutiable =& $xmlReq->createElement('Dutiable'); $dflag =& $xmlReq->createElement('DutiableFlag'); if ($duty_value == 0) { $dflag->setText('N'); $dutiable->appendChild($dflag); } else { $dflag->setText('Y'); $dutiable->appendChild($dflag); $dval =& $xmlReq->createElement('CustomsValue'); $dval->setText(round($duty_value, 0)); $dutiable->appendChild($dval); } $shipment->appendChild($dutiable); } $billing =& $xmlReq->createElement('Billing'); $party =& $xmlReq->createElement('Party'); $code =& $xmlReq->createElement('Code'); /* Always bill shipper */ $code->setText('S'); $party->appendChild($code); $billing->appendChild($party); if ($method['international']) { $duty_payer =& $xmlReq->createElement('DutyPaymentType'); /* receiver pays duties */ $duty_payer->setText('R'); $billing->appendChild($duty_payer); } $shipment->appendChild($billing); $recv =& $xmlReq->createElement('Receiver'); $addr =& $xmlReq->createElement('Address'); // Handle address_1 $address_1 = $db->f('address_1'); if (strlen($address_1) > 35) { $address_1 = substr($address_1, 0, 35); $vmLogger->debug('Address 1 too long. Shortened to 35 characters.'); } $street_addr =& $xmlReq->createCDATASection($address_1); $street =& $xmlReq->createElement('Street'); $street->appendChild($street_addr); $addr->appendChild($street); // Handle address_2 $address_2 = $db->f('address_2'); if (strlen($address_2) > 35) { $address_2 = substr($address_2, 0, 35); $vmLogger->debug('Address 2 too long. Shortened to 35 characters.'); } $street_addr2 =& $xmlReq->createCDATASection($address_2); $street2 =& $xmlReq->CreateElement('StreetLine2'); $street2->appendChild($street_addr2); $addr->appendChild($street2); $city =& $xmlReq->createElement('City'); $city_name =& $xmlReq->createCDATASection($db->f('city')); $city->appendChild($city_name); $addr->appendChild($city); if ($db->f('state') != '') { $state =& $xmlReq->createElement('State'); $state->setText($db->f('state')); $addr->appendChild($state); } $country =& $xmlReq->createElement('Country'); $country->setText($dest_country); $addr->appendChild($country); if ($db->f('zip') != '') { $pc =& $xmlReq->createElement('PostalCode'); $pc->setText($db->f('zip')); $addr->appendChild($pc); } $recv->appendChild($addr); $shipment->appendChild($recv); $root->appendChild($shipment); // $vmLogger->err($xmlReq->toNormalizedString()); if (function_exists("curl_init")) { $CR = curl_init(); curl_setopt($CR, CURLOPT_URL, $dhl_url); curl_setopt($CR, CURLOPT_POST, 1); curl_setopt($CR, CURLOPT_FAILONERROR, true); curl_setopt($CR, CURLOPT_POSTFIELDS, $xmlReq->toString()); curl_setopt($CR, CURLOPT_RETURNTRANSFER, 1); $xmlResult = curl_exec($CR); $error = curl_error($CR); if (!empty($error)) { $vmLogger->err(curl_error($CR)); $html = '<br/><span class="message">' . $VM_LANG->_('PHPSHOP_INTERNAL_ERROR') . ' DHL</span>'; return false; } curl_close($CR); } // XML Parsing $xmlResp = new DOMIT_Lite_Document(); if (!$xmlResp->parseXML($xmlResult, false, true)) { $vmLogger->err($VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_INVALID_XML') . $xmlResult); $html .= '<br /><span class="message">' . $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_INVALID_XML') . '</span>'; continue; } // $vmLogger->err($xmlResp->toNormalizedString()); // Check for success or failure. $result_code_list =& $xmlResp->getElementsByPath('//Result/Code'); $result_code =& $result_code_list->item(0); $result_desc_list =& $xmlResp->getElementsByPath('//Result/Desc'); $result_desc =& $result_desc_list->item(0); if ($result_code == NULL) { $html .= $VM_LANG->_('PHPSHOP_ERROR_DESC') . ': ' . $VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_MISSING_RESULT'); $vmLogger->debug($VM_LANG->_('PHPSHOP_SHIPPING_METHOD_DHL_MISSING_RESULT') . "\n" . $xmlResp->toNormalizedString()); continue; } // '203' is the code for success (at least with domestic) if ($result_code->getText() != '203') { $html .= '<br /><span class="message">' . $method['service_desc'] . ': ' . $result_desc->getText() . ' [code ' . $result_code->getText() . ']' . '</span>'; // display an error line for each fault $fault_node_list =& $xmlResp->getElementsByPath('//Faults/Fault'); if ($fault_node_list->getLength() > 0) { $html .= '<ul>'; } for ($i = 0; $i < $fault_node_list->getLength(); $i++) { $fault_node =& $fault_node_list->item($i); $fault_code_node_list =& $fault_node->getElementsByTagName('Code'); $fault_desc_node_list =& $fault_node->getElementsByTagName('Desc'); $fault_code_node =& $fault_code_node_list->item(0); $fault_desc_node =& $fault_desc_node_list->item(0); $html .= '<li>' . $fault_desc_node->getText() . ' [code ' . $fault_code_node->getText() . ']</li>'; } if ($fault_node_list->getLength() > 0) { $html .= '</ul>'; } continue; } else { $deliver_date_node_list =& $xmlResp->getElementsByPath('//ServiceLevelCommitment/Desc'); $deliver_date_node =& $deliver_date_node_list->item(0); $deliver_date = $deliver_date_node->getText(); $ship_rate_node_list =& $xmlResp->getElementsByTagName('TotalChargeEstimate'); $ship_rate_node =& $ship_rate_node_list->item(0); $ship_rate = $ship_rate_node->getText(); /* * If DHL freaks out and gives us a $0.00 shipping * rate, don't list the option. */ if ($ship_rate == 0.0) { continue; } $total_rate = $ship_rate + floatval(DHL_HANDLING_FEE); $ship_postage = $CURRENCY_DISPLAY->getFullValue($total_rate); /* * Leave the shipping class field empty * since it looks ugly. The information we need to * generate a shipping label for this rate will be * stored one off the end. */ $id_string = __CLASS__; $id_string .= "|DHL"; $id_string .= "|" . $method['service_desc']; $id_string .= "|" . $total_rate; $id_string .= "|"; $id_string .= "|" . $ship_date; $id_string .= ";" . $method['service_code']; $id_string .= ";" . $method['special_service']; $id_string .= ";" . $method['package_type']; if ($method['international']) { $id_string .= ";T"; } else { $id_string .= ";F"; } $id_string .= ";" . DHL_ADDITIONAL_PROTECTION; $id_string .= ";" . $order_weight; $id_string .= ";" . $duty_value; $id_string .= ";" . $insurance; $id_string .= ";" . $content_desc; $shipping_rate_id = urlencode($id_string); $html .= "\n<input type=\"radio\" " . "name=\"shipping_rate_id\"" . " value=\"{$shipping_rate_id}\" />\n"; $_SESSION[$shipping_rate_id] = 1; $html .= "DHL " . $method['service_desc']; $html .= " <strong>(" . $ship_postage . ")</strong>"; $html .= " - " . $deliver_date; $html .= "<br />"; } } echo $html; return true; }