<?php
/*=======================================================================
 *
 * tracking_amazon.php
 *
 * Autor: Marc Vollmann
 *
 =======================================================================*/


include_once ("../include/mcglobal.inc.php");


// Write logdata into log file
$currentTime = getDateTime("0");

$trackingReq = file_get_contents('php://input');

// writeToFile("../log/trckng_amzn.log", "POST RAW - " . $currentTime);
writeToFile("../log/trckng_amzn.log", $currentTime);
writeToFile("../log/trckng_amzn.log", $trackingReq);
writeToFile("../log/trckng_amzn.log", "___________________________________________________________________________________");
// writeToFile("../log/trckng_amzn.log", "__________");
/*
writeToFile("../log/trckng_amzn.log", "POST RAW - " . $currentTime);
writeToFile("../log/trckng_amzn.log", $HTTP_RAW_POST_DATA);
writeToFile("../log/trckng_amzn.log", "__________");

writeToFile("../log/trckng_amzn.log", "POST - " . $currentTime);
writeToFile("../log/trckng_amzn.log", print_r ($_POST,true));
writeToFile("../log/trckng_amzn.log", "__________");

writeToFile("../log/trckng_amzn.log", "GET - " . $currentTime);
writeToFile("../log/trckng_amzn.log", print_r ($_GET,true));
writeToFile("../log/trckng_amzn.log", "__________");

writeToFile("../log/trckng_amzn.log", "COOKIE - " . $currentTime);
writeToFile("../log/trckng_amzn.log", print_r ($_COOKIE,true));
writeToFile("../log/trckng_amzn.log", "__________");

writeToFile("../log/trckng_amzn.log", "SERVER - " . $currentTime);
writeToFile("../log/trckng_amzn.log", print_r ($_SERVER,true));
writeToFile("../log/trckng_amzn.log", "__________");

writeToFile("../log/trckng_amzn.log", "ENV - " . $currentTime);
writeToFile("../log/trckng_amzn.log", print_r ($_ENV,true));
writeToFile("../log/trckng_amzn.log", "__________");

writeToFile("../log/trckng_amzn.log", "FILES - " . $currentTime);
writeToFile("../log/trckng_amzn.log", print_r ($_FILES,true));
writeToFile("../log/trckng_amzn.log", "___________________________________________________________________________________");
*/

// Check HTTP-Parameters
// getSecHttpVars("1",array("f_act", "trackingReq", "selectedLanguage"));
// $trackingReq = urldecode($trackingReq);

if ($selectedLanguage == "" || !is_numeric($selectedLanguage)) : $selectedLanguage = "1"; endif;  // Default in English
$languageSelected = $selectedLanguage;

getLanguage(__FILE__);
getCurrentScript(__FILE__);

// ---------------------------------------------------------------------------

// Event messages
$eventMsgArray["EVENT_101"] = "Shipment has left seller facility and is in transit";       // Electronic Manifest transmitted by Amazon to the carrier and the carrier’s truck has departed the Amazon/seller facility
$eventMsgArray["EVENT_102"] = "Shipment received by carrier";       // Origin scan which confirms possession by the carrier

$eventMsgArray["EVENT_201"] = "Arrival Scan";   // Arrived at any of the carrier facilities
$eventMsgArray["EVENT_202"] = "Departure Scan";   // Departed any of the carrier facilities
$eventMsgArray["EVENT_203"] = "Arrived at destination country";   // Arrived at the destination country
$eventMsgArray["EVENT_204"] = "Initiated customs clearance process";   // Customs has started to clear the package
$eventMsgArray["EVENT_205"] = "Completed customs clearance process";   // Customs has cleared the package
$eventMsgArray["EVENT_206"] = "In transit to pickup location";   // Package is in transit to pickup location
$eventMsgArray["EVENT_207"] = "Problem resolved and shipment is in transit";   // Resolution of exception scan and package is in transit again
$eventMsgArray["EVENT_208"] = "Your selected store is closed for delivery and your shipment has been rerouted to a nearby store. The carrier will provide more information about the new store";   // Customer pick-up location is closed and the package was rerouted to a nearby pick-up location

$eventMsgArray["EVENT_300"] = "NOT DISPLAYED";   // Tendered to alternate carrier, line haul complete
$eventMsgArray["EVENT_301"] = "Delivered";   // Delivered to the customer directly
$eventMsgArray["EVENT_302"] = "Out for delivery";   // On the last leg of delivery to the customer
$eventMsgArray["EVENT_304"] = "Delivery attempted";   // Carrier attempted delivery, but unable to deliver to customer
$eventMsgArray["EVENT_306"] = "Customer contacted to arrange delivery";   // Carrier has contacted the customer to arrange delivery of the package
$eventMsgArray["EVENT_307"] = "Delivery appointment scheduled";   // Carrier has scheduled delivery of the package with the customer
$eventMsgArray["EVENT_308"] = "Available for pickup";   // Package is available for pickup from pickup location
$eventMsgArray["EVENT_309"] = "Returned to seller";   // Package was delivered back to seller’s facility
$eventMsgArray["EVENT_310"] = "Tendered to local postal carrier for final delivery";   // Local postal carrier will perform final delivery to the customer. If assigned a new tracking id, carrier name and tracking id should be provided.
$eventMsgArray["EVENT_311"] = "Tendered to local postal carrier for final delivery and no proof of delivery will be provided";   // Local postal carrier will perform final delivery to the customer but they will not scan the package as delivered (international use).
$eventMsgArray["EVENT_320"] = "Customer has picked up";
$eventMsgArray["EVENT_328"] = "Shipment addressed to a company that is closed on weekends. Shipment will be deliverd on the next working day"; // Business closed. The goods/consignements/equipment could not be delivered/collected as the business was closed

$eventMsgArray["EVENT_401"] = "Incorrect address";   // Destination address does not exist or is incorrect
$eventMsgArray["EVENT_402"] = "Customs clearance delay";   // Any situation which causes a delay clearing customs
$eventMsgArray["EVENT_403"] = "Customer moved";   // Consignee no longer lives at the delivery address and left no forwarding address
$eventMsgArray["EVENT_404"] = "Delay in delivery due to external factors";   // This represents a definite delay in delivery and will trigger correspondences to the customer to notify them of the delay
$eventMsgArray["EVENT_405"] = "Shipment damaged";   // Carrier damaged the package
$eventMsgArray["EVENT_406"] = "Held by carrier";   // The package is being held by the carrier
$eventMsgArray["EVENT_407"] = "Customer refused delivery";   // Consignee refused to accept package
$eventMsgArray["EVENT_408"] = "Returning to seller";   // Amazon has requested the package be returned to Amazon’s facility
$eventMsgArray["EVENT_409"] = "Lost by carrier";   // Carrier lost the package
$eventMsgArray["EVENT_411"] = "Paperwork received - did not receive shipment";   // Carrier received electronic or paper manifest, but the shipment has not been picked up
$eventMsgArray["EVENT_412"] = "Received shipment - did not receive paperwork";   // Carrier received the package, but not the electronic/paper manifest. This is sent only when the shipment cannot move until the problem is resolved
$eventMsgArray["EVENT_413"] = "Customer refused shipment due to customs charges";   // Customer has refused shipment due to customs duties, taxes and fees charges.
$eventMsgArray["EVENT_414"] = "Possible delay in delivery due to arrival at incorrect carrier facility";   // Package was mis-sorted and delivery maybe delayed
$eventMsgArray["EVENT_415"] = "Received from prior carrier";   // Carrier has received the package from the previous carrier
$eventMsgArray["EVENT_416"] = "Undeliverable";   // Package could not be delivered, and Amazon has instructed the carrier to destroy the package or follow alternate instructions
$eventMsgArray["EVENT_418"] = "Returning to seller due to incorrect address";   // Unable to complete delivery due to incorrect address and the shipment is being returned to the seller
$eventMsgArray["EVENT_419"] = "Returning to seller because customer refused delivery";   // Customer refused delivery and the shipment is being returned to the seller 
$eventMsgArray["EVENT_420"] = "Delay in delivery due to weather or natural disaster";   // Shipment delivery is delayed because of weather or natural disaster
$eventMsgArray["EVENT_421"] = "Unable to forward shipment to different address";   // Forwarding attempt failed
$eventMsgArray["EVENT_422"] = "Shipment forwarded to a different delivery address";   // Carrier has forwarded the package to an address
$eventMsgArray["EVENT_423"] = "Shipment damaged and will not be delivered";  // Carrier has identified the package as damaged, will not complete the delivery, and will dispose of the package
$eventMsgArray["EVENT_424"] = "Held for payment";  // Delivery of the package cannot be completed until payment is received by Carrier
$eventMsgArray["EVENT_425"] = "Possible delay in delivery due to extra carrier processing";  // There is possible delay in delivery because the carrier had to perform extra processing outside of the norm
$eventMsgArray["EVENT_426"] = "Confiscated or seized by an official government authority";  // The package will not be delivered nor returned due to being seized by an official government authority 
$eventMsgArray["EVENT_427"] = "Held by carrier – seller input required";  // The package is being held by the carrier because they require additional information from Amazon 
$eventMsgArray["EVENT_428"] = "Address issue corrected by carrier but delivery could be delayed.";  // The carrier was able to correct the customer’s address without any input from customer or Amazon
$eventMsgArray["EVENT_451"] = "Returning to seller because customer did not pick up on time";

// ---------------------------------------------------------------------------

// Error messages
$errMsgArray["ERROR_101"] = "INVALID TRACKING NUMBER";         // Request contains an invalid tracking number
$errMsgArray["ERROR_102"] = "NO TRACKING INFO FOUND";          // No data exists in the carrier’s system for the given tracking number

$errMsgArray["ERROR_201"] = "INVALID USERID/PASSWORD";         // Request contains an invalid user ID or password
$errMsgArray["ERROR_202"] = "INVALID API VERSION";             // Request contains an incompatible API version
$errMsgArray["ERROR_203"] = "XML DOCUMENT NOT WELL FORMED";    // Request is not a well-formed XML document
$errMsgArray["ERROR_204"] = "XML DOCUMENT NOT VALID";          // Request is not a valid XML document

$errMsgArray["ERROR_301"] = "TRACKING SERVICE NOT AVAILABLE";  // Generic error code to handle any situation where Amazon

// ---------------------------------------------------------------------------

// Delivery location codes
$deliveryLocCodes["AS_INSTRUCTED"] = "As instructed";  // Package was delivered as per instructions
$deliveryLocCodes["CARPORT"] = "Carport";  // Package was left inside a carport
$deliveryLocCodes["CUSTOMER_PICKUP"] = "Picked up by customer";  // Package was picked up by customer
$deliveryLocCodes["DECK"] = "Deck";  // Package was left on an outside deck
$deliveryLocCodes["DOCK"] = "Shipping dock";  // Package was left on dock
$deliveryLocCodes["FRONT_DESK"] = "Front desk";  // Package was left at front desk
$deliveryLocCodes["FRONT_DOOR"] = "Front door";  // Package was left in or near the front door
$deliveryLocCodes["GARAGE"] = "Garage";  // Package was left in or near the garage door
$deliveryLocCodes["GUARD"] = "Guard";  // Package was handed to a security guard
$deliveryLocCodes["MAILBOX"] = "Mailbox";  // Package was left inside the residence’s mailbox
$deliveryLocCodes["MAIL_ROOM"] = "Mail room";  // Package was left in mail room
$deliveryLocCodes["MAIL_SLOT"] = "Mail slot";  // Package was left in mail slot
$deliveryLocCodes["MC_BOY"] = "Delivered to male child";  // Package was handed directly to a male child.
$deliveryLocCodes["MC_GIRL"] = "Delivered to female child";  // Package was handed directly to a female child.
$deliveryLocCodes["MC_MAN"] = "Delivered to male adult";  // Package was handed directly to a man
$deliveryLocCodes["MC_WOMAN"] = "Delivered to female adult";  // Package was handed directly to a woman
$deliveryLocCodes["NEIGHBOR"] = "Left with neighbor";  // Package was handed directly to a neighbor
$deliveryLocCodes["OUTBUILDING"] = "Outbuilding";  // Package was left in an outbuilding
$deliveryLocCodes["PATIO"] = "Patio";  // Package was left on an outside patio
$deliveryLocCodes["PORCH"] = "Porch";  // Package was left on an outside porch
$deliveryLocCodes["REAR_DOOR"] = "Rear door";  // Package was in or near the rear door
$deliveryLocCodes["RECEIVER"] = "Resident";  // Package was handed to resident
$deliveryLocCodes["RECEPTIONIST"] = "Receptionist";  // Package was handed to a receptionist
$deliveryLocCodes["SECURE_LOCATION"] = "Secure location";  // Package was left in a secure location
$deliveryLocCodes["SIDE_DOOR"] = "Side door";  // Package was left at side door

// Pickup location codes
$pickupLocCodes["CARRIER_FACILITY"] = "Available for pickup at carrier facility";  // Package can be picked up from carrier’s hub
$pickupLocCodes["CONVENIENCE_STORE"] = "Available for pickup at local convenience store";  // Package can be picked up at a local store
$pickupLocCodes["LOCAL_POST_OFFICE"] = "Available for pickup at your local post office";  // Package can be picked up at local post office

// ---------------------------------------------------------------------------

function getSingleTagContent ($strToParse, $tagBegin, $tagEnd) {
  $tagContent = "";
  $repeat = TRUE;
  while ($repeat && !(strpos($strToParse, $tagBegin) === FALSE) && !(strpos($strToParse, $tagEnd) === FALSE)) :

     $pos0 = strpos($strToParse, $tagBegin);                         // begin of tagBegin (first occurrence)
     $pos1 = strpos($strToParse, $tagBegin) + strlen($tagBegin);     // end of tagBegin   (first occurrence)
     $pos2 = strpos($strToParse, $tagEnd);                           // begin of tagEnd   (first occurrence)
     $pos3 = strpos($strToParse, $tagEnd) + strlen($tagEnd);         // end of tagEnd     (first occurrence)
     
     $repeat = FALSE;
     if ($pos2 - $pos1 > 0) :
        // Get the content of the tag
        $tagContent = substr($strToParse, $pos1, $pos2 - $pos1);
     endif;
  endwhile;
  return $tagContent;
};

function getTagContent ($strToParse, $tagBegin, $tagEnd) {
  $tagContentArray = array();
  $repeat = TRUE;
  while ($repeat && !(strpos($strToParse, $tagBegin) === FALSE) && !(strpos($strToParse, $tagEnd) === FALSE)) :
     $pos0 = strpos($strToParse, $tagBegin);                         // begin of tagBegin (first occurrence)
     $pos1 = strpos($strToParse, $tagBegin) + strlen($tagBegin);     // end of tagBegin   (first occurrence)
     $pos2 = strpos($strToParse, $tagEnd);                           // begin of tagEnd   (first occurrence)
     $pos3 = strpos($strToParse, $tagEnd) + strlen($tagEnd);         // end of tagEnd     (first occurrence)
     if ($pos2 - $pos1 > 0) :
        // Get the content of the tag
        $tmpContent = substr($strToParse, $pos1, $pos2 - $pos1);
        $tagContentArray[] = $tmpContent;
        $strToParse = str_replace($tagBegin . $tmpContent . $tagEnd, "", $strToParse);
     endif;
  endwhile;
  return $tagContentArray;
}

function getTrackingIDOfRequest ($req) {
	global $apiVersion, $trackingUserID, $trackingPassword, $trackingIDs;
	$apiVersion       = getSingleTagContent($req, "<APIVersion>", "</APIVersion>");      // API Version
	$trackingUserID   = getSingleTagContent($req, "<UserID>", "</UserID>");              // User ID
	$trackingPassword = getSingleTagContent($req, "<Password>", "</Password>");          // Password
	$trackingIDs      = getTagContent($req, "<TrackingNumber>", "</TrackingNumber>");    // Tracking IDs	
};

// ---------------------------------------------------------------------------

// Generate a response for a specified tracking ID with existing tracking data
function generateTrackingResponseXML () {
	global $tratId, $jbId, $trSort, $tratState, $tratRemark, $tratpType, $tratpState, $tratpRemark, $tratpCreatetime, $trSignname, $trHsno, $adStreet, $adZipcode, $adCity, $adCountry;
  global $trackingIDs, $eventCounter, $trackingIDErrorState, $deliveryAddress, $eventMsgArray, $errMsgArray;

  $trackingIDsLen = count($trackingIDs);

  $response = "";

  $response .= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
  $response .= "<AmazonTrackingResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"AmazonTrackingResponse.xsd\">";
  $response .= "<APIVersion>3.5</APIVersion>";

  // List tracking events
  $eventResponse = "";  
  for ($j = 0; $j < $trackingIDsLen; $j++) :

      if ($trackingIDErrorState[$j] == "0") :

         $eventResponse .= "<TrackingNumber>" . $trackingIDs[$j] . "</TrackingNumber>";
         $eventResponse .= "<PackageDestinationLocation>";
         $eventResponse .= "<City>" . $deliveryAddress["ad_city"] . "</City>";
         $eventResponse .= "<StateProvince></StateProvince>";
         $eventResponse .= "<PostalCode>" . $deliveryAddress["ad_zipcode"] . "</PostalCode>";
         $eventResponse .= "<CountryCode>" . $deliveryAddress["ad_country"] . "</CountryCode>";
         $eventResponse .= "</PackageDestinationLocation>";
         $eventResponse .= "<TrackingEventHistory>";

         for ($i = 0; $i < $eventCounter[$j]; $i++) :

             $tmpEventNo = $tratpType[$j][$i];  // Get event number of current process entry
   
             if ($tmpEventNo != "" && is_numeric($tmpEventNo)) :
                $eventResponse .= "<TrackingEventDetail>";
                $eventResponse .= "<EventCode>EVENT_" . $tmpEventNo . "</EventCode>";
                $eventResponse .= "<EventCodeDesc>" .  $eventMsgArray["EVENT_" . $tmpEventNo] . "</EventCodeDesc>";
                $eventResponse .= "<EventDateTime>" . substr($tratpCreatetime[$j][$i],0,10) . "T" . substr($tratpCreatetime[$j][$i],11,8) . "+01:00" . "</EventDateTime>";
                $eventResponse .= "<EventLocation>";
                $eventResponse .= "<City>" . $adCity[$j][$i] . "</City>";
                $eventResponse .= "<StateProvince>" . "" . "</StateProvince>";
                $eventResponse .= "<PostalCode>" . $adZipcode[$j][$i] . "</PostalCode>";
                $eventResponse .= "<CountryCode>" . ($adCountry[$j][$i] == "" ? "DE" : $adCountry[$j][$i]) . "</CountryCode>";
                $eventResponse .= "</EventLocation>";
                $eventResponse .= "<AdditionalLocationInfo>" . $tratpRemark[$j][$i] . "</AdditionalLocationInfo>";
                $eventResponse .= "<SignedForByName>" . $trSignname[$j][$i] . "</SignedForByName>";
                $eventResponse .= "</TrackingEventDetail>";
             endif;
         endfor;
   
         $eventResponse .= "</TrackingEventHistory>";
      endif;
  endfor;
  if ($eventResponse != "") :
     $response .= "<PackageTrackingInfo>";
     $response .= $eventResponse;
     $response .= "</PackageTrackingInfo>";
  endif;

  // List tracking errors
  for ($j = 0; $j < $trackingIDsLen; $j++) :
  
      if ($trackingIDErrorState[$j] != "0") :

         $response .= "<TrackingErrorInfo>";
         $response .= "<TrackingNumber>" . $trackingIDs[$j] . "</TrackingNumber>";
         $response .= "<TrackingErrorDetail>";
         $response .= "<ErrorDetailCode>ERROR_" . $trackingIDErrorState[$j] . "</ErrorDetailCode>";
         $response .= "<ErrorDetailCodeDesc>" . $errMsgArray["ERROR_" . $trackingIDErrorState[$j]] . "</ErrorDetailCodeDesc>";
         $response .= "</TrackingErrorDetail>";
         $response .= "</TrackingErrorInfo>";
      endif;
  endfor;
  
  $response .= "</AmazonTrackingResponse>";

  // $response = urlencode($response);

  $responseLen = strlen($response);

return $response;
};

// Generate a response for an invalid specified tracking ID
function generateTrackingErrorResponse () {
  global $tratId, $jbId, $trSort, $tratState, $tratRemark, $tratpType, $tratpState, $tratpRemark, $tratpCreatetime, $trSignname, $trHsno, $adStreet, $adZipcode, $adCity, $adCountry;
  global $trackingIDs, $eventCounter, $trackingIDErrorState, $deliveryAddress, $eventMsgArray, $errMsgArray;

  $response = "";

  $response .= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
  $response .= "<AmazonTrackingResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"AmazonTrackingResponse.xsd\">";
  $response .= "<APIVersion>3.5</APIVersion>";
  
  for ($j = 0; $j < $trackingIDsLen; $j++) :
  
      if ($trackingIDErrorState[$j] != "0") :

         $response .= "<TrackingErrorInfo>";
         $response .= "<TrackingNumber>" . $trackingIDs[$j] . "</TrackingNumber>";
         $response .= "<TrackingErrorDetail>";
         $response .= "<ErrorDetailCode>ERROR_" . $trackingIDErrorState[$j] . "</ErrorDetailCode>";
         $response .= "<ErrorDetailCodeDesc>" . $errMsgArray["ERROR_" . $trackingIDErrorState[$j]] . "</ErrorDetailCodeDesc>";
         $response .= "</TrackingErrorDetail>";
         $response .= "</TrackingErrorInfo>";
      endif;
  endfor;

  $response .= "</AmazonTrackingResponse>";

return $response;
};


// ---------------------------------------------------------------------------

// ******************************************
// * Get the tracking ID out of the request *
// ******************************************
getTrackingIDOfRequest($trackingReq);   // Set global parameters: $trackingIDs, $trackingUserID, $trackingPassword
global $db, $PHP_SELF;

$trackingIDsLen = count($trackingIDs);

if ($apiVersion == "3.5") :

   if ($trackingUserID == "stbx" && $trackingPassword == "cagtmv2924") :

      // Initial code
      $generalErrorState = "0";

      if ($trackingIDsLen > 0) :

         // Get the array for formatting the database-values for the output according to the defined type
         $outputFormatField = defineOutputFormats();

         // Init global arrays
         $deliveryAddress      = array();
         $trackingIDErrorState = array();
         $eventCounter         = array();
         $tratId               = array();
         $jbId                 = array(); 
         $trSort               = array();
         $tratState            = array();
         $tratRemark           = array();
         $tratpType            = array();
         $tratpState           = array();
         $tratpRemark          = array();
         $tratpCreatetime      = array();
         $trSignname           = array();
         $trHsno               = array();
         $adStreet             = array();
         $adZipcode            = array();
         $adCity               = array();
         $adCountry            = array();
   
         for ($j = 0; $j < $trackingIDsLen; $j++) :
   
             $trackingID = trim($trackingIDs[$j]);
             
             // Init with "INVALID TRACKING NUMBER"
             $trackingIDErrorState[$j] = "101";

             if ($trackingID != "") :

                // Ckeck validity of the tracking ID
                // ... here ...
                if (true) :
   
                   // Check existence of the hash value
                   // if (existsEntry("meta_object.metaobject",array("mo_hash",$trackingID))) :
                   if (existsEntry("phoenix.tourarticle",array("trat_serialno",$trackingID))) :

/*  
                      $moId      = getFieldValueFromId("meta_object.metaobject", "mo_hash", $trackingID, "mo_id");
                      $moIdRefDB = getFieldValueFromId("meta_object.metaobject", "mo_id", $moId, "mo_id_ref_db");
                      $objType   = getFieldValueFromId("meta_object.metaobject", "mo_id", $moId, "mo_obj_type");
                      $objId     = getFieldValueFromId("meta_object.metaobject", "mo_id", $moId, "mo_obj_id");
*/

                      if (true || $moId != "" && $moId > "0") :
   
                         // Get database instance
//                       $dbInst = getFieldValueFromId("meta_object.metaobject", "mo_id", $moIdRefDB, "mo_value");
   
                         if (true || $dbInst != "") :
   
                            // Get database connection
//                          $db_conn = getDbConnectionSpecial($dbInst, $dbname, $dblogin, $dbpassword);
   
                            if (true || $objType == "track") :

                               // Get tracking ID from "tourarticle"
                               $sqlquery = "SELECT trat.trat_id, trat.jb_id, trat.tr_sort, trat.trat_state, trat.trat_remark,"
                                         . "       tratp.tratp_type, tratp.tratp_state, tratp.tratp_remark, tratp.tratp_createtime,"
                                         . "       tr.tr_signname, tr.tr_hsno,"
                                         . "       ad.ad_street, ad.ad_zipcode, ad.ad_city, ad.ad_country"
                                         . "  FROM phoenix.tourarticle AS trat, phoenix.tourarticleprocess AS tratp, phoenix.tour AS tr, phoenix.address AS ad"
                                         . "  WHERE trat.trat_serialno = '" . $trackingID . "' AND"
                                         . "        trat.trat_id = tratp.trat_id AND"
                                         . "        trat.jb_id = tr.jb_id AND"
                                         . "        trat.tr_sort = tr.tr_sort AND"
                                         . "        tr.ad_id = ad.ad_id"
                                         . "  ORDER BY tratp.tratp_createtime";

//                             $result = $db_conn->query($sqlquery);
$result = $db->query($sqlquery);
                               if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());

                               $i = 0;
                               $eventCounter[$j] = 0;
                               while ($row = $result->fetchRow()):

                                     $tratId[$j][$i]          = $row["trat_id"];               // [$j] = Index per tracking ID in "trat_serialno"
                                     $jbId[$j][$i]            = $row["jb_id"];
                                     $trSort[$j][$i]          = $row["tr_sort"];
                                     $tratState[$j][$i]       = $row["trat_state"];
                                     $tratRemark[$j][$i]      = $row["trat_remark"];
   
                                     $tratpType[$j][$i]       = $row["tratp_type"];
                                     $tratpState[$j][$i]      = $row["tratp_state"];
                                     $tratpRemark[$j][$i]     = $row["tratp_remark"];
                                     $tratpCreatetime[$j][$i] = $row["tratp_createtime"];
   
                                     $trSignname[$j][$i]      = $row["tr_signname"];
                                     $trHsno[$j][$i]          = $row["tr_hsno"];
                                     $adStreet[$j][$i]        = $row["ad_street"];
                                     $adZipcode[$j][$i]       = $row["ad_zipcode"];
                                     $adCity[$j][$i]          = $row["ad_city"];
                                     $adCountry[$j][$i]       = $row["ad_country"];

                                     $i++;
                                     $eventCounter[$j]++;                                      // How many events per tracking ID
                               endwhile;
                               $result->free();

                               // Check if no tracking data is found according to the current tracking ID
                               $trackingIDErrorState[$j] = "0";   // Init: OK
                               if ($i == 0) :
                                  $trackingIDErrorState[$j] = "102";   // "NO TRACKING DATA FOUND"
                               endif;

                               // -------------------------------------
                               
                               // Get delivery address and data of the end customer
                               $sqlquery = "SELECT trat.jb_id, trat.tr_sort,"
                                         . "       tr.tr_signname, tr.tr_hsno, tr.tr_person,"
                                         . "       ad.ad_street, ad.ad_zipcode, ad.ad_city, ad.ad_country"
                                         . "  FROM phoenix.tourarticle AS trat, phoenix.tour AS tr, phoenix.address AS ad"
                                         . "  WHERE trat.trat_serialno = '" . $trackingID . "' AND"
                                         . "        trat.jb_id = tr.jb_id AND"
                                         . "        trat.tr_sort = tr.tr_sort AND"
                                         . "        tr.ad_id = ad.ad_id"
                                         . "  ORDER BY trat.jb_id, trat.tr_sort";
                               
//                             $result = $db_conn->query($sqlquery);
$result = $db->query($sqlquery);
                               if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());
                               
                               // The last row is the youngest order with the corresponding station no.
                               while ($row = $result->fetchRow()):
                               
                                     $deliveryAddress["jb_id"] = $row["jb_id"];
                                     $deliveryAddress["tr_sort"] = $row["tr_sort"];
                                     $deliveryAddress["ad_street"] = $row["ad_street"];
                                     $deliveryAddress["tr_hsno"] = $row["tr_hsno"];
                                     $deliveryAddress["ad_zipcode"] = $row["ad_zipcode"];
                                     $deliveryAddress["ad_city"] = $row["ad_city"];
                                     $deliveryAddress["ad_country"] = $row["ad_country"];
                                     $deliveryAddress["tr_person"] = $row["tr_person"];
                               endwhile;
                               $result->free();

                            endif;
                         endif;
                      endif;
                   endif;
                endif;
             endif;
         endfor;   // End loop tracking IDs
      else :
         // No tracking ID has been sent
         for ($j = 0; $j < $trackingIDsLen; $j++) :
             $trackingIDErrorState[$j] = "204";
         endfor;
      endif;
   else :
      // UserId or password not correct (for ALL tracking IDs!!!)
      for ($j = 0; $j < $trackingIDsLen; $j++) :
          $trackingIDErrorState[$j] = "201";
      endfor;
   endif;
else :
   // API version not correct (for ALL tracking IDs!!!)
   for ($j = 0; $j < $trackingIDsLen; $j++) :
       $trackingIDErrorState[$j] = "202";
   endfor;
endif;

// Generate response   
$response = generateTrackingResponseXML();
?>

<?php echo $response ?>