Advertisement
Guest User

Prestashop Stamps.com

a guest
Aug 29th, 2016
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 17.08 KB | None | 0 0
  1. /* Stamps.com Prestashop Integration (version 3.13.0):
  2.  
  3. NOT exactly "easy-to-use" for the average, non-technical small-business store owner.  The add-on from the store is actually missing the "stamps.php" file that is critical to the operation of the module.  We acquired this file from Stamps.com tech support.  This file cannot be placed within the "stampsdotcom" folder where the module is located.  Getting this file is undocumented anywhere (future versions may be different).  Unfortunately, it still didn't import all of our outstanding orders.  We couldn't figure it out.  Finally, after parsing through the "stamps.php" file I figured out what the issue was.
  4.  
  5. Within "stamps.php" it is setting an end date of the current date minus 2 hours.  It's setting UTC as the current date and timezone ($psTimeZone) and subtracting 2 to get a conservative range of outstanding orders.  Frankly, the script should be asking what the timezone is from Prestashop.  We had to change the line of code (line 315) to read minus 5 hours to get it to work properly for our timezone ($end = new DateTime(date("Y-m-d\TH:i:s", time()-5), $psTimeZone);).
  6.  
  7. I've pasted the full code for the Stamps.php file below.  Remember, upload this file to the root of your Prestashop instance after installing the module.  It needs to be accessible at https://<yoursite>/stamps.php
  8.  
  9. You can test it by creating a separate admin employee account strictly for the Stamps.com application.  An example would be "externalstamps@<ourdomain>.com".  To test the module go out to a browser and type "https://<yourdomain>.com/stamps.php?action=getorders&username=<username>&password=<password>".  Obviously, input all of that without the quotes and replace the domain, username, and password information where applicable.  */
  10.  
  11. <?php
  12.  
  13. define('REQUIRE_SECURE', FALSE);
  14. $moduleVersion = "3.13.0";
  15. $schemaVersion = "1.1.0";
  16. error_reporting(E_ALL ^ (E_NOTICE | E_WARNING | E_DEPRECATED));
  17. header('Access-Control-Allow-Origin: https://batch.internetpostage.com');
  18. require'config/config.inc.php';
  19.  
  20. //Timezone from PrestaShop
  21. $psTimeZone = new DateTimeZone(Configuration::get('PS_TIMEZONE'));
  22.  
  23. header("Content-Type: text/xml;charset=utf-8");
  24. header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  25.  
  26. // HTTP/1.1
  27. header("Cache-Control: no-store, no-cache, must-revalidate");
  28. header("Cache-Control: post-check=0, pre-check=0", false);
  29.  
  30. // HTTP/1.0
  31. header("Pragma: no-cache");    
  32.  
  33. // write xml documenta declaration
  34. function writeXmlDeclaration()
  35. {
  36.     echo "<?xml version=\"1.0\" standalone=\"yes\" ?>";
  37. }
  38.  
  39. function writeStartTag($tag, $attributes = null)
  40. {
  41.     echo '<' . $tag;
  42.  
  43.     if ($attributes != null)
  44.     {
  45.         echo ' ';
  46.  
  47.         foreach ($attributes as $name => $attribValue)
  48.         {
  49.             echo $name. '="'. htmlspecialchars($attribValue). '" ';
  50.         }
  51.     }
  52.  
  53.     echo '>';
  54. }
  55.  
  56. // write closing xml tag
  57. function writeCloseTag($tag)
  58. {
  59.     echo '</' . $tag . '>';
  60. }
  61.  
  62. // Output the given tag\value pair
  63. function writeElement($tag, $value)
  64. {
  65.     writeStartTag($tag);
  66.     echo htmlspecialchars($value);
  67.     writeCloseTag($tag);
  68. }
  69.  
  70. // Outputs the given name/value pair as an xml tag with attributes
  71. function writeFullElement($tag, $value, $attributes)
  72. {
  73.     echo '<'. $tag. ' ';
  74.  
  75.     foreach ($attributes as $name => $attribValue)
  76.     {
  77.         echo $name. '="'. htmlspecialchars($attribValue). '" ';
  78.     }
  79.     echo '>';
  80.     echo htmlspecialchars($value);
  81.     writeCloseTag($tag);
  82. }
  83.  
  84.  
  85. // Function used to output an error and quit.
  86. function outputError($code, $error)
  87. {      
  88.     writeStartTag("Error");
  89.     writeElement("Code", $code);
  90.     writeElement("Description", $error);
  91.     writeCloseTag("Error");
  92. }      
  93.  
  94. $secure = false;
  95. try
  96. {
  97.     if (isset($_SERVER['HTTPS']))
  98.     {
  99.         $secure = ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == '1');
  100.     }
  101. }
  102. catch(Exception $e)
  103. {
  104. }
  105.  
  106. $actions = (isset($_REQUEST['action']) ? $_REQUEST['action'] : '');
  107.     if(strtolower($actions) == 'phpinfo')
  108.     {
  109.         if (checkAdminLogin())
  110.         {
  111.             return phpinfo();
  112.         }    
  113.     }  
  114. // Open the XML output and root
  115. writeXmlDeclaration();
  116. writeStartTag("ShipWorks", array("moduleVersion" => $moduleVersion, "schemaVersion" => $schemaVersion));
  117.  
  118. // Enforse SSL
  119. if (!$secure && REQUIRE_SECURE)
  120. {
  121.     outputError(10, 'A secure (https://) connection is required.');
  122. }
  123. else
  124. {
  125.     if (checkAdminLogin())
  126.     {
  127.         $action = (isset($_REQUEST['action']) ? $_REQUEST['action'] : '');
  128.         switch (strtolower($action))
  129.         {
  130.             case 'getmodule': Action_GetModule(); break;
  131.             case 'getstore': Action_GetStore(); break;
  132.             case 'getcount': Action_GetCount(); break;
  133.             case 'getorders': Action_GetOrders(); break;
  134.             case 'getstatuscodes': Action_GetStatusCodes(); break;
  135.             case 'updatestatus': action_UpdateStatus();break;
  136.             case 'updateshipment': action_UpdateShipment(); break;
  137.             default:
  138.                 outputError(20, "'$action' is not supported.");
  139.         }
  140.     }
  141. }
  142.  
  143. // Close the output
  144. writeCloseTag("ShipWorks");
  145.  
  146. //Check username, password
  147. function checkAdminLogin()
  148. {
  149.     $loginOK = false;
  150.  
  151.     if (isset($_REQUEST['username']) && isset($_REQUEST['password']))
  152.     {
  153.  
  154.         $username = $_REQUEST['username'];
  155.         $password = $_REQUEST['password'];
  156.        
  157.         $sql = new DbQuery();
  158.         $sql->select('id_employee');
  159.         $sql->from('employee', 'e');
  160.         $sql->where("e.email = '$username'");
  161.  
  162.         $employeeId = Db::getInstance()->getRow($sql);
  163.        
  164.         if($employeeId)
  165.         {
  166.             $employeeId = $employeeId['id_employee'];
  167.  
  168.             $encryptedPassword = Tools::encrypt($password);
  169.             if (Employee::checkPassword($employeeId, $encryptedPassword))
  170.             {
  171.                 $loginOK = true;        
  172.             }
  173.         }
  174.     }
  175.  
  176.     if (!$loginOK)
  177.     {
  178.         outputError(50, "The username or password is incorrect or user provided does not have administrator access.");
  179.     }
  180.  
  181.     return $loginOK;
  182. }
  183.  
  184. // Get module data
  185. function action_GetModule()
  186. {
  187.     writeStartTag("Module");
  188.  
  189.     writeElement("Platform", "PrestaShop");
  190.     writeElement("Developer", "Interapptive, Inc. (support@interapptive.com)");
  191.  
  192.     writeStartTag("Capabilities");
  193.     writeElement("DownloadStrategy", "ByModifiedTime");
  194.     writeFullElement("OnlineCustomerID", "", array("supported" => "true", "dataType" => "numeric"));
  195.     writeFullElement("OnlineStatus", "", array("supported" => "true", "supportsComments" => "false", "downloadOnly"=>"false", "dataType" => "numeric"));
  196.     writeFullElement("OnlineShipmentUpdate", "", array("supported" => "true"));
  197.     writeCloseTag("Capabilities");
  198.     writeStartTag("Communications");
  199.     writeFullElement("Http", "", array("expect100Continue" => "true"));
  200.     writeElement("ResponseEncoding", "UTF-8");
  201.     writeCloseTag("Communications");
  202.  
  203.     writeCloseTag("Module");           
  204. }
  205.  
  206. // Write store data
  207. function Action_GetStore()
  208. {
  209.  
  210.     $name = Configuration::get('PS_SHOP_NAME');
  211.     $companyOrOwner = Configuration::get('');
  212.     $email = Configuration::get('PS_SHOP_EMAIL');
  213.     $street1 = Configuration::get('PS_SHOP_ADDR1');
  214.     $street2 = Configuration::get('PS_SHOP_ADDR2');
  215.     $street3 = '';
  216.     $city = Configuration::get('PS_SHOP_CITY');
  217.     $state = Configuration::get('PS_SHOP_STATE');
  218.     $postalCode = Configuration::get('PS_SHOP_CODE');
  219.     $country = Configuration::get('PS_SHOP_COUNTRY');
  220.     $phone = Configuration::get('PS_SHOP_PHONE');
  221.     $website = '';
  222.    
  223.     writeStartTag("Store");
  224.     writeElement("Name", $name);
  225.     writeElement("CompanyOrOwner", $companyOrOwner);
  226.     writeElement("Email", $email);
  227.     writeElement("Street1", $street1);
  228.     writeElement("Street2", $street2);
  229.     writeElement("Street3", $street3);
  230.     writeElement("City", $city);
  231.     writeElement("State", $state);
  232.     writeElement("PostalCode", $postalCode);
  233.     writeElement("Country", $country);
  234.     writeElement("Phone", $phone);
  235.     writeElement("Website", $website);
  236.     writeCloseTag("Store");
  237. }
  238.  
  239. // Get the count of orders greater than the start date
  240. function Action_GetCount()
  241. {        
  242.     global $psTimeZone;
  243.     $start = '1970-01-01';
  244.    
  245.     if($_REQUEST['start'])
  246.     {
  247.         $start = $_REQUEST['start'];
  248.     }
  249.    
  250.     //Date/Time from ShipWorks in UTC
  251.     $start = new DateTime($start, new DateTimeZone('UTC'));
  252.     if($start->setTimezone($psTimeZone) != null)
  253.     {
  254.         $start = $start->setTimezone($psTimeZone); 
  255.     }
  256.    
  257.     $end = new DateTime(date("Y-m-d\TH:i:s", time()-2), $psTimeZone);
  258.    
  259.     if($end == null)
  260.     {
  261.         $end = new DateTime(date("Y-m-d\TH:i:s", time()-2));
  262.     }  
  263.  
  264.     // Write the params for easier diagnostics
  265.     writeStartTag("Parameters");
  266.     writeElement("Start", $start);
  267.     writeElement("End", $end);
  268.     writeCloseTag("Parameters");
  269.        
  270.     $startSQL = $start->format("Y-m-d H:i:s");
  271.     $endSQL = $end->format("Y-m-d H:i:s");
  272.    
  273.     $sql = new DbQuery();
  274.     $sql->select('count(*) as count');
  275.     $sql->from('orders', 'o');
  276.     $sql->where("o.date_upd > '$startSQL'");
  277.     $sql->where("o.date_upd < '$endSQL'");
  278.      
  279.     $count = Db::getInstance()->getRow($sql);
  280.  
  281.     writeElement("OrderCount", $count['count']);
  282. }
  283.  
  284. // Get all orders greater than the given start date, limited by max count
  285. function Action_GetOrders()
  286. {
  287.     $start = '1970-01-01';
  288.     $maxcount = 5000;
  289.     global $psTimeZone;
  290.  
  291.     if (isset($_REQUEST['start']))
  292.     {
  293.         $start = $_REQUEST['start'];
  294.     }
  295.  
  296.     if (isset($_REQUEST['maxcount']))
  297.     {
  298.         //$maxcount = (int)$_REQUEST['maxcount'];
  299.     }
  300.    
  301.     //Date/Time from ShipWorks in UTC
  302.     $start = new DateTime($start, new DateTimeZone('UTC'));
  303.     if($start->setTimezone($psTimeZone) != null)
  304.     {
  305.         $start = $start->setTimezone($psTimeZone); 
  306.     }
  307.    
  308.     $end = new DateTime(date("Y-m-d\TH:i:s", time()-5), $psTimeZone);
  309.    
  310.     if($end == null)
  311.     {
  312.         $end = new DateTime(date("Y-m-d\TH:i:s", time()-2));
  313.     }  
  314.     // Write the params for easier diagnostics
  315.     writeStartTag("Parameters");
  316.     writeElement("Start", $start->format("Y-m-d\TH:i:s"));
  317.     writeElement("End", $end->format("Y-m-d\TH:i:s"));
  318.     writeElement("MaxCount", $maxcount);
  319.     writeCloseTag("Parameters");                                    
  320.  
  321.     $startSQL = $start->format("Y-m-d H:i:s");
  322.     $endSQL = $end->format("Y-m-d H:i:s");
  323.    
  324.     $sql = new DbQuery();
  325.     $sql->select('id_order');
  326.     $sql->from('orders', 'o');
  327.     $sql->where("o.date_upd > '$startSQL'");
  328.     $sql->where("o.date_upd < '$endSQL'");
  329.     $sql->orderBy("o.date_upd");
  330.     $sql->limit($maxcount,0);
  331.    
  332.     $orderids = Db::getInstance()->executeS($sql);
  333.    
  334.     writeStartTag("Orders");
  335.  
  336.     $start = null;
  337.     $processedIds = '';
  338.    
  339.     foreach ($orderids as $orderid)
  340.     {
  341.         $order = new Order($orderid['id_order']);
  342.         $start = new DateTime($order->date_upd, $psTimeZone);
  343.         $startSQL = $start->format("Y-m-d H:i:s");
  344.        
  345.         // Add the id to the list we have processed
  346.         if ($processedIds != "")
  347.         {
  348.             $processedIds .= ", ";
  349.         }
  350.        
  351.         $processedIds .= $orderid['id_order'];
  352.         WriteOrder($order);
  353.     }
  354.  
  355.     //make sure that we dont skip an order if it has the same lastmodified as order #50 from above
  356.     if ($processedIds)
  357.     {
  358.         $sql = new DbQuery();
  359.         $sql->select('id_order');
  360.         $sql->from('orders', 'o');
  361.         $sql->where("o.date_upd = '$startSQL'");
  362.         $sql->where("o.id_order not in ($processedIds)");
  363.        
  364.         $skippedOrderids = Db::getInstance()->executeS($sql);
  365.        
  366.         foreach ($skippedOrderids as $orderid)
  367.         {
  368.             $order = new Order($orderid['id_order']);
  369.             WriteOrder($order);
  370.         }
  371.     }
  372.  
  373.     writeCloseTag("Orders");
  374. }
  375.  
  376. // Output the order as xml
  377. function WriteOrder($order)
  378. {                
  379.     global $secure;
  380.     global $psTimeZone;
  381.    
  382.     $orderDate = new DateTime($order->date_add, $psTimeZone);
  383.     $orderDate = $orderDate->setTimezone(new DateTimeZone('UTC'));
  384.    
  385.     $lastModified = new DateTime($order->date_upd, $psTimeZone);
  386.     $lastModified = $lastModified->setTimezone(new DateTimeZone('UTC'));
  387.    
  388.     writeStartTag("Order");
  389.  
  390.     writeElement("OrderNumber", $order->id);
  391.     writeElement("OrderDate", $orderDate->format("Y-m-d\TH:i:s"));
  392.     writeElement("LastModified", $lastModified->format("Y-m-d\TH:i:s"));
  393.    
  394.     $carrier = new Carrier($order->id_carrier);
  395.    
  396.     writeElement("ShippingMethod", $carrier->name);
  397.     writeElement("StatusCode", $order->current_state);
  398.  
  399.     writeStartTag("Notes");
  400.    
  401.     $sql = new DbQuery();
  402.     $sql->select('id_message');
  403.     $sql->from('message', 'm');
  404.     $sql->where("m.id_order = '$order->id'");
  405.    
  406.     $messageIds = Db::getInstance()->executeS($sql);
  407.    
  408.     foreach($messageIds as $messageId)
  409.     {
  410.         $message = new Message($messageId['id_message']);
  411.         writeFullElement("Note", $message->message, array("public" => "true"));
  412.     }
  413.    
  414.     writeCloseTag("Notes");
  415.    
  416.     $customer = new Customer($order->id_customer);
  417.     $billToAddress = new Address($order->id_address_invoice);
  418.     $billToState = new State($billToAddress->id_state);
  419.    
  420.     writeStartTag("BillingAddress");
  421.     writeElement("FirstName", $billToAddress->firstname);
  422.     writeElement("LastName", $billToAddress->lastname);
  423.     writeElement("Company",$billToAddress->company);
  424.     writeElement("Street1", $billToAddress->address1);
  425.     writeElement("Street2",$billToAddress->address2);
  426.     writeElement("Street3","");
  427.     writeElement("City", $billToAddress->city);
  428.     writeElement("State", $billToState->iso_code);
  429.     writeElement("PostalCode", $billToAddress->postcode);
  430.     writeElement("Country", $billToAddress->country);
  431.     writeElement("Phone", $billToAddress->phone);
  432.     writeElement("Email",$customer->email);
  433.     writeCloseTag("BillingAddress");
  434.    
  435.    
  436.     $shipToAddress = new Address($order->id_address_delivery);
  437.     $shipToState = new State($shipToAddress->id_state);
  438.    
  439.     writeStartTag("ShippingAddress");
  440.     writeElement("FirstName", $shipToAddress->firstname);
  441.     writeElement("LastName", $shipToAddress->lastname);
  442.     writeElement("Company",$shipToAddress->company);
  443.     writeElement("Street1", $shipToAddress->address1);
  444.     writeElement("Street2",$shipToAddress->address2);
  445.     writeElement("Street3","");
  446.     writeElement("City", $shipToAddress->city);
  447.     writeElement("State", $shipToState->iso_code);
  448.     writeElement("PostalCode", $shipToAddress->postcode);
  449.     writeElement("Country", $shipToAddress->country);
  450.     writeElement("Phone", $shipToAddress->phone);
  451.     writeElement("Email",$customer->email);
  452.     writeCloseTag("ShippingAddress");
  453.    
  454.  
  455.     writeStartTag("Payment");
  456.     writeElement("Method", $order->payment);
  457.     writeCloseTag("Payment");
  458.  
  459.     WriteOrderItems($order->getProducts());
  460.  
  461.     WriteOrderTotals($order);
  462.  
  463.     writeCloseTag("Order");
  464. }
  465.  
  466. // Outputs notes elements
  467. function WriteNote($noteText, $public)
  468. {
  469.     $attributes = array("public" => $public ? "true" : "false");
  470.  
  471.     writeFullElement("Note", $noteText, $attributes);
  472. }
  473.  
  474. // writes a single order total
  475. function WriteOrderTotal($name, $value, $class, $impact = "add")
  476. {
  477.     if ($value > 0)
  478.     {
  479.         writeFullElement("Total", $value, array("name" => $name, "class" => $class, "impact" => $impact));
  480.     }
  481. }
  482.  
  483. // Write all totals lines for the order
  484. function WriteOrderTotals($order)
  485. {
  486.     writeStartTag("Totals");
  487.  
  488.     WriteOrderTotal("Shipping and Handling", $order->total_shipping_tax_incl, "shipping", "add");
  489.  
  490.     WriteOrderTotal("Discounts", $order->total_discounts, "discount","subtract");
  491.  
  492.     WriteOrderTotal("Grand Total", $order->total_paid, "total", "none");
  493.    
  494.     writeCloseTag("Totals");
  495. }
  496.  
  497. // Write XML for all products for the given order
  498. function WriteOrderItems($orderItems)
  499. {
  500.     writeStartTag("Items");
  501.  
  502.     foreach ($orderItems as $item)
  503.     {
  504.         writeStartTag("Item");
  505.  
  506.         writeElement("Code", $item['product_reference']);
  507.         writeElement("SKU", $item['product_reference']);
  508.         writeElement("Name", $item['product_name']);
  509.         writeElement("Quantity", (int)$item['product_quantity']);
  510.         writeElement("UnitPrice", $item['product_price']);
  511.         writeElement("Weight", $item['product_weight']);
  512.  
  513.         writeCloseTag("Item");
  514.     }
  515.  
  516.     writeCloseTag("Items");
  517. }
  518.  
  519. // Returns the shipping status codes for the store
  520. function Action_GetStatusCodes()
  521. {
  522.     $status = new OrderState();
  523.     $shippingStatus = $status->getOrderStates('1');
  524.  
  525.     writeStartTag("StatusCodes");
  526.     foreach ($shippingStatus as $status)
  527.     {
  528.         writeStartTag("StatusCode");
  529.         writeElement("Code", $status['id_order_state']);
  530.         writeElement("Name", $status['name']);
  531.         writeCloseTag("StatusCode");
  532.     }
  533.     writeCloseTag("StatusCodes");
  534.    
  535. }
  536.  
  537. //Update order status
  538. function action_UpdateStatus()
  539. {
  540.     $orderId = 0;
  541.     $statusCode = '';
  542.     $comments = '';
  543.  
  544.     if (!isset($_POST['order']) || !isset($_POST['status']) || !isset($_POST['comments']))
  545.     {
  546.         outputError(50, "Not all parameters supplied.");
  547.         return;
  548.     }
  549.  
  550.     $orderId = $_REQUEST['order'];
  551.     $statusCode = (int)$_REQUEST['status'];
  552.     $comments = $_REQUEST['comments'];
  553.  
  554.     // write the params for easier diagnostics
  555.     writeStartTag("Parameters");
  556.     writeElement("Order", $orderId);   
  557.     writeElement("Status", $statusCode);
  558.     writeElement("Comments", $comments);
  559.     writeCloseTag("Parameters");
  560.    
  561.     $order = new Order($orderId);
  562.     $order->setCurrentState($statusCode);
  563.     echo "<UpdateSuccess/>";   
  564. }
  565.  
  566. //Upload tracking
  567. function action_UpdateShipment()
  568. {
  569.     $orderId = 0;
  570.     $trackingNumber = '';
  571.    
  572.  
  573.     if (!isset($_POST['order']) || !isset($_POST['tracking']))
  574.     {
  575.         outputError(50, "Not all parameters supplied.");
  576.         return;
  577.     }
  578.  
  579.     $orderId = $_POST['order'];
  580.     $trackingNumber = $_POST['tracking'];
  581.    
  582.     // write the params for easier diagnostics
  583.     writeStartTag("Parameters");
  584.     writeElement("OrderID", $orderId); 
  585.     writeElement("Tracking", $trackingNumber);
  586.     writeCloseTag("Parameters");
  587.  
  588.     $order = new Order($orderId);
  589.  
  590.     $order->shipping_number = $trackingNumber;
  591.     $order->update();
  592.    
  593.     $orderCarrier = new OrderCarrier($orderId);
  594.     $orderCarrier->tracking_number = $trackingNumber;
  595.     $orderCarrier->update();
  596.    
  597.     echo "<UpdateSuccess/>";   
  598. }
  599. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement