amazon.php (15650B)
1 <?php 2 namespace openbay; 3 4 final class Amazon { 5 private $token; 6 private $encryption_key; 7 private $encryption_iv; 8 private $url = 'https://uk-amazon.openbaypro.com/'; 9 private $registry; 10 11 public function __construct($registry) { 12 $this->registry = $registry; 13 $this->token = $this->config->get('openbay_amazon_token'); 14 15 $this->setEncryptionKey($this->config->get('openbay_amazon_encryption_key')); 16 $this->setEncryptionIv($this->config->get('openbay_amazon_encryption_iv')); 17 } 18 19 public function __get($name) { 20 return $this->registry->get($name); 21 } 22 23 public function getEncryptionKey() { 24 return $this->encryption_key; 25 } 26 27 public function setEncryptionKey($key) { 28 $this->encryption_key = $key; 29 } 30 31 public function getEncryptionIv() { 32 return $this->encryption_iv; 33 } 34 35 public function setEncryptionIv($encryption_iv) { 36 $this->encryption_iv = $encryption_iv; 37 } 38 39 public function call($method, $data = array(), $use_json = true) { 40 if (!empty($data)) { 41 if ($use_json) { 42 $string = json_encode($data); 43 } else { 44 $string = $data; 45 } 46 47 $encrypted = $this->openbay->encrypt($string, $this->getEncryptionKey(), $this->getEncryptionIv(), false); 48 } else { 49 $encrypted = ''; 50 } 51 52 $post_data = array( 53 'token' => $this->token, 54 'data' => base64_encode($encrypted), 55 'opencart_version' => VERSION 56 ); 57 58 $headers = array(); 59 $headers[] = 'X-Endpoint-Version: 2'; 60 61 $defaults = array( 62 CURLOPT_HEADER => 0, 63 CURLOPT_HTTPHEADER => $headers, 64 CURLOPT_POST => 1, 65 CURLOPT_URL => $this->url . $method, 66 CURLOPT_USERAGENT => 'OpenBay Pro for Amazon/Opencart', 67 CURLOPT_FRESH_CONNECT => 1, 68 CURLOPT_RETURNTRANSFER => 1, 69 CURLOPT_FORBID_REUSE => 1, 70 CURLOPT_TIMEOUT => 30, 71 CURLOPT_SSL_VERIFYPEER => 0, 72 CURLOPT_SSL_VERIFYHOST => 0, 73 CURLOPT_POSTFIELDS => http_build_query($post_data, '', "&"), 74 ); 75 76 $curl = curl_init(); 77 78 curl_setopt_array($curl, $defaults); 79 80 $response = curl_exec($curl); 81 82 curl_close($curl); 83 84 return $response; 85 } 86 87 public function callNoResponse($method, $data = array(), $use_json = true) { 88 if (!empty($data)) { 89 if ($use_json) { 90 $string = json_encode($data); 91 } else { 92 $string = $data; 93 } 94 95 $encrypted = $this->openbay->encrypt($string, $this->getEncryptionKey(), $this->getEncryptionIv(), false); 96 } else { 97 $encrypted = ''; 98 } 99 100 $post_data = array( 101 'token' => $this->token, 102 'data' => rawurlencode(base64_encode($encrypted)), 103 'opencart_version' => VERSION 104 ); 105 106 $headers = array(); 107 $headers[] = 'X-Endpoint-Version: 2'; 108 109 $defaults = array( 110 CURLOPT_HEADER => 0, 111 CURLOPT_HTTPHEADER => $headers, 112 CURLOPT_POST => 1, 113 CURLOPT_URL => $this->url . $method, 114 CURLOPT_USERAGENT => 'OpenBay Pro for Amazon/Opencart', 115 CURLOPT_FRESH_CONNECT => 1, 116 CURLOPT_RETURNTRANSFER => 1, 117 CURLOPT_FORBID_REUSE => 1, 118 CURLOPT_TIMEOUT => 2, 119 CURLOPT_SSL_VERIFYPEER => 0, 120 CURLOPT_SSL_VERIFYHOST => 0, 121 CURLOPT_POSTFIELDS => http_build_query($post_data, '', "&"), 122 ); 123 $curl = curl_init(); 124 125 curl_setopt_array($curl, $defaults); 126 127 curl_exec($curl); 128 129 curl_close($curl); 130 } 131 132 public function getServer() { 133 return $this->url; 134 } 135 136 public function productUpdateListen($product_id, $data = array()) { 137 $logger = new \Log('amazon_stocks.log'); 138 $logger->write('productUpdateListen(), product ID: ' . $product_id); 139 140 $product = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "' LIMIT 1")->row; 141 142 if ($this->openbay->addonLoad('openstock') && (isset($product['has_option']) && $product['has_option'] == 1)) { 143 $this->load->model('extension/module/openstock'); 144 $logger->write('Variant item'); 145 146 $quantity_data = array(); 147 148 // check if post data['variant'], if not then call db to get variants 149 if (!isset($data['variant'])) { 150 $variants = $this->model_extension_module_openstock->getVariants($product_id); 151 } else { 152 $variants = $data['variant']; 153 } 154 155 foreach ($variants as $variant) { 156 $amazon_sku_rows = $this->db->query("SELECT `amazon_sku` FROM `" . DB_PREFIX . "amazon_product_link` WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($variant['sku']) . "'")->rows; 157 158 foreach($amazon_sku_rows as $amazon_sku_row) { 159 $quantity_data[$amazon_sku_row['amazon_sku']] = $variant['stock']; 160 } 161 } 162 163 if(!empty($quantity_data)) { 164 $logger->write('Updating with: ' . print_r($quantity_data, true)); 165 $this->updateQuantities($quantity_data); 166 } else { 167 $logger->write('Not required.'); 168 } 169 } else { 170 $this->putStockUpdateBulk(array($product_id)); 171 } 172 173 $logger->write('productUpdateListen() - finished'); 174 } 175 176 public function bulkUpdateOrders($orders) { 177 // Is the module enabled and called from admin? 178 if ($this->config->get('openbay_amazon_status') != 1 || !defined('HTTPS_CATALOG')) { 179 return; 180 } 181 $this->load->model('extension/openbay/amazon'); 182 183 $log = new \Log('amazon.log'); 184 $log->write('Called bulkUpdateOrders method'); 185 186 $request = array( 187 'orders' => array(), 188 ); 189 190 foreach ($orders as $order) { 191 $amazon_order = $this->getOrder($order['order_id']); 192 $amazon_order_products = $this->model_extension_openbay_amazon->getAmazonOrderedProducts($order['order_id']); 193 194 $products = array(); 195 196 foreach ($amazon_order_products as $amazon_order_product) { 197 $products[] = array( 198 'amazon_order_item_id' => $amazon_order_product['amazon_order_item_id'], 199 'quantity' => $amazon_order_product['quantity'], 200 ); 201 } 202 203 $order_info = array( 204 'amazon_order_id' => $amazon_order['amazon_order_id'], 205 'status' => $order['status'], 206 'products' => $products, 207 ); 208 209 if ($order['status'] == 'shipped' && !empty($order['carrier'])) { 210 if ($order['carrier_from_list']) { 211 $order_info['carrier_id'] = $order['carrier']; 212 } else { 213 $order_info['carrier_name'] = $order['carrier']; 214 } 215 216 $order_info['tracking'] = $order['tracking']; 217 } 218 219 $request['orders'][] = $order_info; 220 } 221 222 $log->write('order/bulkUpdate call: ' . print_r($request, 1)); 223 224 $response = $this->call('order/bulkUpdate', $request); 225 226 $log->write('order/bulkUpdate response: ' . $response); 227 } 228 229 public function updateOrder($order_id, $order_status_string, $courier_id = '', $courier_from_list = true, $tracking_no = '') { 230 231 if ($this->config->get('openbay_amazon_status') != 1) { 232 return; 233 } 234 235 /* Is called from admin? */ 236 if (!defined('HTTPS_CATALOG')) { 237 return; 238 } 239 240 $amazon_order = $this->getOrder($order_id); 241 242 if(!$amazon_order) { 243 return; 244 } 245 246 $amazon_order_id = $amazon_order['amazon_order_id']; 247 248 $log = new \Log('amazon.log'); 249 $log->write("Order's $amazon_order_id status changed to $order_status_string"); 250 251 $this->load->model('extension/openbay/amazon'); 252 $amazon_order_products = $this->model_extension_openbay_amazon->getAmazonOrderedProducts($order_id); 253 254 $request_node = new \SimpleXMLElement('<Request/>'); 255 256 $request_node->addChild('AmazonOrderId', $amazon_order_id); 257 $request_node->addChild('Status', $order_status_string); 258 259 if(!empty($courier_id)) { 260 if($courier_from_list) { 261 $request_node->addChild('CourierId', $courier_id); 262 } else { 263 $request_node->addChild('CourierOther', $courier_id); 264 } 265 $request_node->addChild('TrackingNo', $tracking_no); 266 } 267 268 $order_items_node = $request_node->addChild('OrderItems'); 269 270 foreach ($amazon_order_products as $product) { 271 $new_order_item = $order_items_node->addChild('OrderItem'); 272 $new_order_item->addChild('ItemId', htmlspecialchars($product['amazon_order_item_id'])); 273 $new_order_item->addChild('Quantity', (int)$product['quantity']); 274 } 275 276 $doc = new \DOMDocument('1.0'); 277 $doc->preserveWhiteSpace = false; 278 $doc->loadXML($request_node->asXML()); 279 $doc->formatOutput = true; 280 281 $this->model_extension_openbay_amazon->updateAmazonOrderTracking($order_id, $courier_id, $courier_from_list, !empty($courier_id) ? $tracking_no : ''); 282 $log->write('Request: ' . $doc->saveXML()); 283 $response = $this->call('order/update2', $doc->saveXML(), false); 284 $log->write("Response for Order's status update: $response"); 285 } 286 287 public function getCategoryTemplates() { 288 $result = $this->call("productv2/RequestTemplateList"); 289 if(isset($result)) { 290 return (array)json_decode($result); 291 } else { 292 return array(); 293 } 294 } 295 296 public function registerInsertion($data) { 297 $result = $this->call("productv2/RegisterInsertionRequest", $data); 298 if(isset($result)) { 299 return (array)json_decode($result); 300 } else { 301 return array(); 302 } 303 } 304 305 public function insertProduct($data) { 306 $result = $this->call("productv2/InsertProductRequest", $data); 307 if(isset($result)) { 308 return (array)json_decode($result); 309 } else { 310 return array(); 311 } 312 } 313 314 public function updateQuantities($data) { 315 $result = $this->call("product/UpdateQuantityRequest", $data); 316 if(isset($result)) { 317 return (array)json_decode($result); 318 } else { 319 return array(); 320 } 321 } 322 323 public function getStockUpdatesStatus($data) { 324 $result = $this->call("status/StockUpdates", $data); 325 if(isset($result)) { 326 return $result; 327 } else { 328 return false; 329 } 330 } 331 332 public function putStockUpdateBulk($product_id_array, $end_inactive = false){ 333 $logger = new \Log('amazon_stocks.log'); 334 $logger->write('putStockUpdateBulk(), End inactive: ' . (int)$end_inactive . ', ids: ' . json_encode($product_id_array)); 335 336 $quantity_data = array(); 337 338 foreach($product_id_array as $product_id) { 339 $linked_skus = $this->db->query("SELECT `amazon_sku` FROM `" . DB_PREFIX . "amazon_product_link` WHERE `product_id` = '" . (int)$product_id . "'")->rows; 340 341 if (!empty($linked_skus)) { 342 foreach ($linked_skus as $sku) { 343 $product = $this->db->query("SELECT `quantity`, `status` FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "'")->row; 344 345 if (!empty($product)) { 346 if ($end_inactive && $product['status'] == '0') { 347 $quantity_data[$sku['amazon_sku']] = 0; 348 } else { 349 $quantity_data[$sku['amazon_sku']] = $product['quantity']; 350 } 351 } 352 } 353 } else { 354 $logger->write('No linked SKU'); 355 } 356 } 357 358 if(!empty($quantity_data)) { 359 $logger->write('New Qty:' . print_r($quantity_data, true)); 360 361 $response = $this->updateQuantities($quantity_data); 362 363 $logger->write('API Response: ' . print_r($response, true)); 364 } else { 365 $logger->write('No update needed'); 366 } 367 } 368 369 public function getOrderdProducts($order_id) { 370 return $this->db->query("SELECT `op`.`product_id`, `p`.`quantity` as `quantity_left` FROM `" . DB_PREFIX . "order_product` as `op` LEFT JOIN `" . DB_PREFIX . "product` as `p` ON `p`.`product_id` = `op`.`product_id` WHERE `op`.`order_id` = '" . (int)$order_id . "'")->rows; 371 } 372 373 public function validate() { 374 if($this->config->get('openbay_amazon_status') != 0 && 375 $this->config->get('openbay_amazon_token') != '' && 376 $this->config->get('openbay_amazon_encryption_key') != '' && 377 $this->config->get('openbay_amazon_encryption_iv') != ''){ 378 return true; 379 } else { 380 return false; 381 } 382 } 383 384 public function deleteProduct($product_id){ 385 $this->db->query("DELETE FROM `" . DB_PREFIX . "amazon_product_link` WHERE `product_id` = '" . (int)$product_id . "'"); 386 } 387 388 public function orderDelete($order_id){ 389 /** 390 * @todo 391 */ 392 } 393 394 public function getOrder($order_id) { 395 $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1"); 396 397 if($qry->num_rows > 0) { 398 return $qry->row; 399 } else { 400 return false; 401 } 402 } 403 404 public function getCarriers() { 405 return array( 406 "USPS", 407 "UPS", 408 "UPSMI", 409 "FedEx", 410 "DHL", 411 "Fastway", 412 "GLS", 413 "GO!", 414 "Hermes Logistik Gruppe", 415 "Royal Mail", 416 "Parcelforce", 417 "City Link", 418 "TNT", 419 "Target", 420 "SagawaExpress", 421 "NipponExpress", 422 "YamatoTransport", 423 "DHL Global Mail", 424 "UPS Mail Innovations", 425 "FedEx SmartPost", 426 "OSM", 427 "OnTrac", 428 "Streamlite", 429 "Newgistics", 430 "Canada Post", 431 "Blue Package", 432 "Chronopost", 433 "Deutsche Post", 434 "DPD", 435 "La Poste", 436 "Parcelnet", 437 "Poste Italiane", 438 "SDA", 439 "Smartmail", 440 "FEDEX_JP", 441 "JP_EXPRESS", 442 "NITTSU", 443 "SAGAWA", 444 "YAMATO", 445 "BlueDart", 446 "AFL/Fedex", 447 "Aramex", 448 "India Post", 449 "Professional", 450 "DTDC", 451 "Overnite Express", 452 "First Flight", 453 "Delhivery", 454 "Lasership", 455 ); 456 } 457 458 public function parseCategoryTemplate($xml) { 459 $simplexml = null; 460 461 libxml_use_internal_errors(true); 462 if(($simplexml = simplexml_load_string($xml)) == false) { 463 return false; 464 } 465 466 $category = (string)$simplexml->filename; 467 468 $tabs = array(); 469 foreach($simplexml->tabs->tab as $tab) { 470 $attributes = $tab->attributes(); 471 $tabs[] = array( 472 'id' => (string)$attributes['id'], 473 'name' => (string)$tab->name, 474 ); 475 } 476 477 $fields = array(); 478 $field_types = array('required', 'desired', 'optional'); 479 foreach ($field_types as $type) { 480 foreach ($simplexml->fields->$type->field as $field) { 481 $attributes = $field->attributes(); 482 $fields[] = array( 483 'name' => (string)$attributes['name'], 484 'title' => (string)$field->title, 485 'definition' => (string)$field->definition, 486 'accepted' => (array)$field->accepted, 487 'type' => (string)$type, 488 'child' => false, 489 'order' => (isset($attributes['order'])) ? (string)$attributes['order'] : '', 490 'tab' => (string)$attributes['tab'], 491 ); 492 } 493 foreach ($simplexml->fields->$type->childfield as $field) { 494 $attributes = $field->attributes(); 495 $fields[] = array( 496 'name' => (string)$attributes['name'], 497 'title' => (string)$field->title, 498 'definition' => (string)$field->definition, 499 'accepted' => (array)$field->accepted, 500 'type' => (string)$type, 501 'child' => true, 502 'parent' => (array)$field->parent, 503 'order' => (isset($attributes['order'])) ? (string)$attributes['order'] : '', 504 'tab' => (string)$attributes['tab'], 505 ); 506 } 507 } 508 509 foreach($fields as $index => $field) { 510 $fields[$index]['unordered_index'] = $index; 511 } 512 513 usort($fields, array('openbay\Amazon','compareFields')); 514 515 return array( 516 'category' => $category, 517 'fields' => $fields, 518 'tabs' => $tabs, 519 ); 520 } 521 522 private static function compareFields($field1, $field2) { 523 if($field1['order'] == $field2['order']) { 524 return ($field1['unordered_index'] < $field2['unordered_index']) ? -1 : 1; 525 } else if(!empty($field1['order']) && empty($field2['order'])) { 526 return -1; 527 } else if(!empty($field2['order']) && empty($field1['order'])) { 528 return 1; 529 } else { 530 return ($field1['order'] < $field2['order']) ? -1 : 1; 531 } 532 } 533 }