aboutsummaryrefslogtreecommitdiffstats
path: root/public/system/library/openbay
diff options
context:
space:
mode:
Diffstat (limited to 'public/system/library/openbay')
-rw-r--r--public/system/library/openbay/amazon.php534
-rw-r--r--public/system/library/openbay/amazonus.php509
-rw-r--r--public/system/library/openbay/ebay.php1514
-rw-r--r--public/system/library/openbay/etsy.php459
-rw-r--r--public/system/library/openbay/fba.php305
5 files changed, 3321 insertions, 0 deletions
diff --git a/public/system/library/openbay/amazon.php b/public/system/library/openbay/amazon.php
new file mode 100644
index 0000000..f627180
--- /dev/null
+++ b/public/system/library/openbay/amazon.php
@@ -0,0 +1,534 @@
+<?php
+namespace openbay;
+
+final class Amazon {
+ private $token;
+ private $encryption_key;
+ private $encryption_iv;
+ private $url = 'https://uk-amazon.openbaypro.com/';
+ private $registry;
+
+ public function __construct($registry) {
+ $this->registry = $registry;
+ $this->token = $this->config->get('openbay_amazon_token');
+
+ $this->setEncryptionKey($this->config->get('openbay_amazon_encryption_key'));
+ $this->setEncryptionIv($this->config->get('openbay_amazon_encryption_iv'));
+ }
+
+ public function __get($name) {
+ return $this->registry->get($name);
+ }
+
+ public function getEncryptionKey() {
+ return $this->encryption_key;
+ }
+
+ public function setEncryptionKey($key) {
+ $this->encryption_key = $key;
+ }
+
+ public function getEncryptionIv() {
+ return $this->encryption_iv;
+ }
+
+ public function setEncryptionIv($encryption_iv) {
+ $this->encryption_iv = $encryption_iv;
+ }
+
+ public function call($method, $data = array(), $use_json = true) {
+ if (!empty($data)) {
+ if ($use_json) {
+ $string = json_encode($data);
+ } else {
+ $string = $data;
+ }
+
+ $encrypted = $this->openbay->encrypt($string, $this->getEncryptionKey(), $this->getEncryptionIv(), false);
+ } else {
+ $encrypted = '';
+ }
+
+ $post_data = array(
+ 'token' => $this->token,
+ 'data' => base64_encode($encrypted),
+ 'opencart_version' => VERSION
+ );
+
+ $headers = array();
+ $headers[] = 'X-Endpoint-Version: 2';
+
+ $defaults = array(
+ CURLOPT_HEADER => 0,
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_POST => 1,
+ CURLOPT_URL => $this->url . $method,
+ CURLOPT_USERAGENT => 'OpenBay Pro for Amazon/Opencart',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 30,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query($post_data, '', "&"),
+ );
+
+ $curl = curl_init();
+
+ curl_setopt_array($curl, $defaults);
+
+ $response = curl_exec($curl);
+
+ curl_close($curl);
+
+ return $response;
+ }
+
+ public function callNoResponse($method, $data = array(), $use_json = true) {
+ if (!empty($data)) {
+ if ($use_json) {
+ $string = json_encode($data);
+ } else {
+ $string = $data;
+ }
+
+ $encrypted = $this->openbay->encrypt($string, $this->getEncryptionKey(), $this->getEncryptionIv(), false);
+ } else {
+ $encrypted = '';
+ }
+
+ $post_data = array(
+ 'token' => $this->token,
+ 'data' => base64_encode($encrypted),
+ 'opencart_version' => VERSION
+ );
+
+ $headers = array();
+ $headers[] = 'X-Endpoint-Version: 2';
+
+ $defaults = array(
+ CURLOPT_HEADER => 0,
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_POST => 1,
+ CURLOPT_URL => $this->url . $method,
+ CURLOPT_USERAGENT => 'OpenBay Pro for Amazon/Opencart',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 2,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query($post_data, '', "&"),
+ );
+ $curl = curl_init();
+
+ curl_setopt_array($curl, $defaults);
+
+ curl_exec($curl);
+
+ curl_close($curl);
+ }
+
+ public function getServer() {
+ return $this->url;
+ }
+
+ public function productUpdateListen($product_id, $data = array()) {
+ $logger = new \Log('amazon_stocks.log');
+ $logger->write('productUpdateListen(), product ID: ' . $product_id);
+
+ $product = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "' LIMIT 1")->row;
+
+ if ($this->openbay->addonLoad('openstock') && (isset($product['has_option']) && $product['has_option'] == 1)) {
+ $this->load->model('extension/module/openstock');
+ $logger->write('Variant item');
+
+ $quantity_data = array();
+
+ // check if post data['variant'], if not then call db to get variants
+ if (!isset($data['variant'])) {
+ $variants = $this->model_extension_module_openstock->getVariants($product_id);
+ } else {
+ $variants = $data['variant'];
+ }
+
+ foreach ($variants as $variant) {
+ $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;
+
+ foreach($amazon_sku_rows as $amazon_sku_row) {
+ $quantity_data[$amazon_sku_row['amazon_sku']] = $variant['stock'];
+ }
+ }
+
+ if(!empty($quantity_data)) {
+ $logger->write('Updating with: ' . print_r($quantity_data, true));
+ $this->updateQuantities($quantity_data);
+ } else {
+ $logger->write('Not required.');
+ }
+ } else {
+ $this->putStockUpdateBulk(array($product_id));
+ }
+
+ $logger->write('productUpdateListen() - finished');
+ }
+
+ public function bulkUpdateOrders($orders) {
+ // Is the module enabled and called from admin?
+ if ($this->config->get('openbay_amazon_status') != 1 || !defined('HTTPS_CATALOG')) {
+ return;
+ }
+ $this->load->model('extension/openbay/amazon');
+
+ $log = new \Log('amazon.log');
+ $log->write('Called bulkUpdateOrders method');
+
+ $request = array(
+ 'orders' => array(),
+ );
+
+ foreach ($orders as $order) {
+ $amazon_order = $this->getOrder($order['order_id']);
+ $amazon_order_products = $this->model_extension_openbay_amazon->getAmazonOrderedProducts($order['order_id']);
+
+ $products = array();
+
+ foreach ($amazon_order_products as $amazon_order_product) {
+ $products[] = array(
+ 'amazon_order_item_id' => $amazon_order_product['amazon_order_item_id'],
+ 'quantity' => $amazon_order_product['quantity'],
+ );
+ }
+
+ $order_info = array(
+ 'amazon_order_id' => $amazon_order['amazon_order_id'],
+ 'status' => $order['status'],
+ 'products' => $products,
+ );
+
+ if ($order['status'] == 'shipped' && !empty($order['carrier'])) {
+ if ($order['carrier_from_list']) {
+ $order_info['carrier_id'] = $order['carrier'];
+ } else {
+ $order_info['carrier_name'] = $order['carrier'];
+ }
+
+ $order_info['tracking'] = $order['tracking'];
+ }
+
+ $request['orders'][] = $order_info;
+ }
+
+ $log->write('order/bulkUpdate call: ' . print_r($request, 1));
+
+ $response = $this->call('order/bulkUpdate', $request);
+
+ $log->write('order/bulkUpdate response: ' . $response);
+ }
+
+ public function updateOrder($order_id, $order_status_string, $courier_id = '', $courier_from_list = true, $tracking_no = '') {
+ if ($this->config->get('openbay_amazon_status') != 1) {
+ return;
+ }
+
+ /* Is called from admin? */
+ if (!defined('HTTPS_CATALOG')) {
+ return;
+ }
+
+ $amazon_order = $this->getOrder($order_id);
+
+ if(!$amazon_order) {
+ return;
+ }
+
+ $amazon_order_id = $amazon_order['amazon_order_id'];
+
+ $log = new \Log('amazon.log');
+ $log->write("Order's $amazon_order_id status changed to $order_status_string");
+
+ $this->load->model('extension/openbay/amazon');
+ $amazon_order_products = $this->model_extension_openbay_amazon->getAmazonOrderedProducts($order_id);
+
+ $request_node = new \SimpleXMLElement('<Request/>');
+
+ $request_node->addChild('AmazonOrderId', $amazon_order_id);
+ $request_node->addChild('Status', $order_status_string);
+
+ if(!empty($courier_id)) {
+ if($courier_from_list) {
+ $request_node->addChild('CourierId', $courier_id);
+ } else {
+ $request_node->addChild('CourierOther', $courier_id);
+ }
+ $request_node->addChild('TrackingNo', $tracking_no);
+ }
+
+ $order_items_node = $request_node->addChild('OrderItems');
+
+ foreach ($amazon_order_products as $product) {
+ $new_order_item = $order_items_node->addChild('OrderItem');
+ $new_order_item->addChild('ItemId', htmlspecialchars($product['amazon_order_item_id']));
+ $new_order_item->addChild('Quantity', (int)$product['quantity']);
+ }
+
+ $doc = new \DOMDocument('1.0');
+ $doc->preserveWhiteSpace = false;
+ $doc->loadXML($request_node->asXML());
+ $doc->formatOutput = true;
+
+ $this->model_extension_openbay_amazon->updateAmazonOrderTracking($order_id, $courier_id, $courier_from_list, !empty($courier_id) ? $tracking_no : '');
+ $log->write('Request: ' . $doc->saveXML());
+
+ $response = $this->call('order/update2', $doc->saveXML(), false);
+
+ $log->write("Response for Order's status update: $response");
+ }
+
+ public function getCategoryTemplates() {
+ $result = $this->call("productv2/RequestTemplateList", array('list' => true));
+ if(isset($result)) {
+ return (array)json_decode($result);
+ } else {
+ return array();
+ }
+ }
+
+ public function registerInsertion($data) {
+ $result = $this->call("productv2/RegisterInsertionRequest", $data);
+ if(isset($result)) {
+ return (array)json_decode($result);
+ } else {
+ return array();
+ }
+ }
+
+ public function insertProduct($data) {
+ $result = $this->call("productv2/InsertProductRequest", $data);
+ if(isset($result)) {
+ return (array)json_decode($result);
+ } else {
+ return array();
+ }
+ }
+
+ public function updateQuantities($data) {
+ $result = $this->call("product/UpdateQuantityRequest", $data);
+ if(isset($result)) {
+ return (array)json_decode($result);
+ } else {
+ return array();
+ }
+ }
+
+ public function getStockUpdatesStatus($data) {
+ $result = $this->call("status/StockUpdates", $data);
+ if(isset($result)) {
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+ public function putStockUpdateBulk($product_id_array, $end_inactive = false){
+ $logger = new \Log('amazon_stocks.log');
+ $logger->write('putStockUpdateBulk(), End inactive: ' . (int)$end_inactive . ', ids: ' . json_encode($product_id_array));
+
+ $quantity_data = array();
+
+ foreach($product_id_array as $product_id) {
+ $linked_skus = $this->db->query("SELECT `amazon_sku` FROM `" . DB_PREFIX . "amazon_product_link` WHERE `product_id` = '" . (int)$product_id . "'")->rows;
+
+ if (!empty($linked_skus)) {
+ foreach ($linked_skus as $sku) {
+ $product = $this->db->query("SELECT `quantity`, `status` FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "'")->row;
+
+ if (!empty($product)) {
+ if ($end_inactive && $product['status'] == '0') {
+ $quantity_data[$sku['amazon_sku']] = 0;
+ } else {
+ $quantity_data[$sku['amazon_sku']] = $product['quantity'];
+ }
+ }
+ }
+ } else {
+ $logger->write('No linked SKU');
+ }
+ }
+
+ if(!empty($quantity_data)) {
+ $logger->write('New Qty:' . print_r($quantity_data, true));
+
+ $response = $this->updateQuantities($quantity_data);
+
+ $logger->write('API Response: ' . print_r($response, true));
+ } else {
+ $logger->write('No update needed');
+ }
+ }
+
+ public function getOrderdProducts($order_id) {
+ 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;
+ }
+
+ public function validate() {
+ if($this->config->get('openbay_amazon_status') != 0 &&
+ $this->config->get('openbay_amazon_token') != '' &&
+ $this->config->get('openbay_amazon_encryption_key') != '' &&
+ $this->config->get('openbay_amazon_encryption_iv') != ''){
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function deleteProduct($product_id){
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "amazon_product_link` WHERE `product_id` = '" . (int)$product_id . "'");
+ }
+
+ public function orderDelete($order_id){
+ /**
+ * @todo
+ */
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazon_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if($qry->num_rows > 0) {
+ return $qry->row;
+ } else {
+ return false;
+ }
+ }
+
+ public function getCarriers() {
+ return array(
+ "USPS",
+ "UPS",
+ "UPSMI",
+ "FedEx",
+ "DHL",
+ "Fastway",
+ "GLS",
+ "GO!",
+ "Hermes Logistik Gruppe",
+ "Royal Mail",
+ "Parcelforce",
+ "City Link",
+ "TNT",
+ "Target",
+ "SagawaExpress",
+ "NipponExpress",
+ "YamatoTransport",
+ "DHL Global Mail",
+ "UPS Mail Innovations",
+ "FedEx SmartPost",
+ "OSM",
+ "OnTrac",
+ "Streamlite",
+ "Newgistics",
+ "Canada Post",
+ "Blue Package",
+ "Chronopost",
+ "Deutsche Post",
+ "DPD",
+ "La Poste",
+ "Parcelnet",
+ "Poste Italiane",
+ "SDA",
+ "Smartmail",
+ "FEDEX_JP",
+ "JP_EXPRESS",
+ "NITTSU",
+ "SAGAWA",
+ "YAMATO",
+ "BlueDart",
+ "AFL/Fedex",
+ "Aramex",
+ "India Post",
+ "Professional",
+ "DTDC",
+ "Overnite Express",
+ "First Flight",
+ "Delhivery",
+ "Lasership",
+ );
+ }
+
+ public function parseCategoryTemplate($xml) {
+ $simplexml = null;
+
+ libxml_use_internal_errors(true);
+ if(($simplexml = simplexml_load_string($xml)) == false) {
+ return false;
+ }
+
+ $category = (string)$simplexml->filename;
+
+ $tabs = array();
+ foreach($simplexml->tabs->tab as $tab) {
+ $attributes = $tab->attributes();
+ $tabs[] = array(
+ 'id' => (string)$attributes['id'],
+ 'name' => (string)$tab->name,
+ );
+ }
+
+ $fields = array();
+ $field_types = array('required', 'desired', 'optional');
+ foreach ($field_types as $type) {
+ foreach ($simplexml->fields->$type->field as $field) {
+ $attributes = $field->attributes();
+ $fields[] = array(
+ 'name' => (string)$attributes['name'],
+ 'title' => (string)$field->title,
+ 'definition' => (string)$field->definition,
+ 'accepted' => (array)$field->accepted,
+ 'type' => (string)$type,
+ 'child' => false,
+ 'order' => (isset($attributes['order'])) ? (string)$attributes['order'] : '',
+ 'tab' => (string)$attributes['tab'],
+ );
+ }
+ foreach ($simplexml->fields->$type->childfield as $field) {
+ $attributes = $field->attributes();
+ $fields[] = array(
+ 'name' => (string)$attributes['name'],
+ 'title' => (string)$field->title,
+ 'definition' => (string)$field->definition,
+ 'accepted' => (array)$field->accepted,
+ 'type' => (string)$type,
+ 'child' => true,
+ 'parent' => (array)$field->parent,
+ 'order' => (isset($attributes['order'])) ? (string)$attributes['order'] : '',
+ 'tab' => (string)$attributes['tab'],
+ );
+ }
+ }
+
+ foreach($fields as $index => $field) {
+ $fields[$index]['unordered_index'] = $index;
+ }
+
+ usort($fields, array('openbay\Amazon','compareFields'));
+
+ return array(
+ 'category' => $category,
+ 'fields' => $fields,
+ 'tabs' => $tabs,
+ );
+ }
+
+ private static function compareFields($field1, $field2) {
+ if($field1['order'] == $field2['order']) {
+ return ($field1['unordered_index'] < $field2['unordered_index']) ? -1 : 1;
+ } else if(!empty($field1['order']) && empty($field2['order'])) {
+ return -1;
+ } else if(!empty($field2['order']) && empty($field1['order'])) {
+ return 1;
+ } else {
+ return ($field1['order'] < $field2['order']) ? -1 : 1;
+ }
+ }
+}
diff --git a/public/system/library/openbay/amazonus.php b/public/system/library/openbay/amazonus.php
new file mode 100644
index 0000000..b8ac34b
--- /dev/null
+++ b/public/system/library/openbay/amazonus.php
@@ -0,0 +1,509 @@
+<?php
+namespace openbay;
+
+final class Amazonus {
+ private $token;
+ private $encryption_key;
+ private $encryption_iv;
+ private $url = 'https://us-amazon.openbaypro.com/';
+ private $registry;
+
+ public function __construct($registry) {
+ $this->registry = $registry;
+ $this->token = $this->config->get('openbay_amazonus_token');
+
+ $this->setEncryptionKey($this->config->get('openbay_amazonus_encryption_key'));
+ $this->setEncryptionIv($this->config->get('openbay_amazonus_encryption_iv'));
+ }
+
+ public function __get($name) {
+ return $this->registry->get($name);
+ }
+
+ public function getEncryptionKey() {
+ return $this->encryption_key;
+ }
+
+ public function setEncryptionKey($key) {
+ $this->encryption_key = $key;
+ }
+
+ public function getEncryptionIv() {
+ return $this->encryption_iv;
+ }
+
+ public function setEncryptionIv($encryption_iv) {
+ $this->encryption_iv = $encryption_iv;
+ }
+
+ public function call($method, $data = array(), $use_json = true) {
+ if (!empty($data)) {
+ if ($use_json) {
+ $string = json_encode($data);
+ } else {
+ $string = $data;
+ }
+
+ $encrypted = $this->openbay->encrypt($string, $this->getEncryptionKey(), $this->getEncryptionIv(), false);
+ } else {
+ $encrypted = '';
+ }
+
+ $post_data = array(
+ 'token' => $this->token,
+ 'data' => base64_encode($encrypted),
+ 'opencart_version' => VERSION
+ );
+
+ $headers = array();
+ $headers[] = 'X-Endpoint-Version: 2';
+
+ $defaults = array(
+ CURLOPT_HEADER => 0,
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_POST => 1,
+ CURLOPT_URL => $this->url . $method,
+ CURLOPT_USERAGENT => 'OpenBay Pro for Amazonus/Opencart',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 30,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query($post_data, '', "&"),
+ );
+
+ $curl = curl_init();
+
+ curl_setopt_array($curl, $defaults);
+
+ $response = curl_exec($curl);
+
+ curl_close($curl);
+
+ return $response;
+ }
+
+ public function callNoResponse($method, $data = array(), $use_json = true) {
+ if (!empty($data)) {
+ if ($use_json) {
+ $string = json_encode($data);
+ } else {
+ $string = $data;
+ }
+
+ $encrypted = $this->openbay->encrypt($string, $this->getEncryptionKey(), $this->getEncryptionIv(), false);
+ } else {
+ $encrypted = '';
+ }
+
+ $post_data = array(
+ 'token' => $this->token,
+ 'data' => base64_encode($encrypted),
+ 'opencart_version' => VERSION
+ );
+
+ $headers = array();
+ $headers[] = 'X-Endpoint-Version: 2';
+
+ $defaults = array(
+ CURLOPT_HEADER => 0,
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_POST => 1,
+ CURLOPT_URL => $this->url . $method,
+ CURLOPT_USERAGENT => 'OpenBay Pro for Amazonus/Opencart',
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 2,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query($post_data, '', "&"),
+ );
+ $curl = curl_init();
+
+ curl_setopt_array($curl, $defaults);
+
+ curl_exec($curl);
+
+ curl_close($curl);
+ }
+
+ public function getServer() {
+ return $this->url;
+ }
+
+ public function productUpdateListen($product_id, $data = array()) {
+ $logger = new \Log('amazonus_stocks.log');
+ $logger->write('productUpdateListen(), product ID: ' . $product_id);
+
+ $product = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "' LIMIT 1")->row;
+
+ if ($this->openbay->addonLoad('openstock') && (isset($product['has_option']) && $product['has_option'] == 1)) {
+ $this->load->model('extension/module/openstock');
+ $logger->write('Variant item');
+
+ $quantity_data = array();
+
+ // check if post data['variant'], if not then call db to get variants
+ if (!isset($data['variant'])) {
+ $variants = $this->model_extension_module_openstock->getVariants($product_id);
+ } else {
+ $variants = $data['variant'];
+ }
+
+ foreach ($variants as $variant) {
+ $amazon_sku_rows = $this->db->query("SELECT `amazonus_sku` FROM `" . DB_PREFIX . "amazonus_product_link` WHERE `product_id` = '" . (int)$product_id . "' AND `var` = '" . $this->db->escape($variant['sku']) . "'")->rows;
+
+ foreach($amazon_sku_rows as $amazon_sku_row) {
+ $quantity_data[$amazon_sku_row['amazonus_sku']] = $variant['stock'];
+ }
+ }
+
+ if(!empty($quantity_data)) {
+ $logger->write('Updating with: ' . print_r($quantity_data, true));
+ $this->updateQuantities($quantity_data);
+ } else {
+ $logger->write('Not required.');
+ }
+ } else {
+ $this->putStockUpdateBulk(array($product_id));
+ }
+
+ $logger->write('productUpdateListen() - finished');
+ }
+
+ public function bulkUpdateOrders($orders) {
+ // Is the module enabled and called from admin?
+ if ($this->config->get('openbay_amazonus_status') != 1 || !defined('HTTPS_CATALOG')) {
+ return;
+ }
+ $this->load->model('extension/openbay/amazonus');
+
+ $log = new \Log('amazonus.log');
+ $log->write('Called bulkUpdateOrders method');
+
+ $request = array(
+ 'orders' => array(),
+ );
+
+ foreach ($orders as $order) {
+ $amazon_order = $this->getOrder($order['order_id']);
+ $amazon_order_products = $this->model_extension_openbay_amazonus->getAmazonusOrderedProducts($order['order_id']);
+
+ $products = array();
+
+ foreach ($amazon_order_products as $amazon_order_product) {
+ $products[] = array(
+ 'amazon_order_item_id' => $amazon_order_product['amazonus_order_item_id'],
+ 'quantity' => $amazon_order_product['quantity'],
+ );
+ }
+
+ $order_info = array(
+ 'amazon_order_id' => $amazon_order['amazonus_order_id'],
+ 'status' => $order['status'],
+ 'products' => $products,
+ );
+
+ if ($order['status'] == 'shipped' && !empty($order['carrier'])) {
+ if ($order['carrier_from_list']) {
+ $order_info['carrier_id'] = $order['carrier'];
+ } else {
+ $order_info['carrier_name'] = $order['carrier'];
+ }
+
+ $order_info['tracking'] = $order['tracking'];
+ }
+
+ $request['orders'][] = $order_info;
+ }
+
+ $log->write('order/bulkUpdate call: ' . print_r($request, 1));
+
+ $response = $this->call('order/bulkUpdate', $request);
+
+ $log->write('order/bulkUpdate response: ' . $response);
+ }
+
+ public function updateOrder($order_id, $order_status_string, $courier_id = '', $courier_from_list = true, $tracking_no = '') {
+
+ if ($this->config->get('openbay_amazonus_status') != 1) {
+ return;
+ }
+
+ /* Is called from admin? */
+ if (!defined('HTTPS_CATALOG')) {
+ return;
+ }
+
+ $amazonus_order = $this->getOrder($order_id);
+
+ if(!$amazonus_order) {
+ return;
+ }
+
+ $amazonus_order_id = $amazonus_order['amazonus_order_id'];
+
+ $log = new \Log('amazonus.log');
+ $log->write("Order's $amazonus_order_id status changed to $order_status_string");
+
+ $this->load->model('extension/openbay/amazonus');
+ $amazonus_order_products = $this->model_extension_openbay_amazonus->getAmazonusOrderedProducts($order_id);
+
+ $request_node = new \SimpleXMLElement('<Request/>');
+
+ $request_node->addChild('AmazonusOrderId', $amazonus_order_id);
+ $request_node->addChild('Status', $order_status_string);
+
+ if(!empty($courier_id)) {
+ if($courier_from_list) {
+ $request_node->addChild('CourierId', $courier_id);
+ } else {
+ $request_node->addChild('CourierOther', $courier_id);
+ }
+ $request_node->addChild('TrackingNo', $tracking_no);
+ }
+
+ $order_items_node = $request_node->addChild('OrderItems');
+
+ foreach ($amazonus_order_products as $product) {
+ $new_order_item = $order_items_node->addChild('OrderItem');
+ $new_order_item->addChild('ItemId', htmlspecialchars($product['amazonus_order_item_id']));
+ $new_order_item->addChild('Quantity', (int)$product['quantity']);
+ }
+
+ $doc = new \DOMDocument('1.0');
+ $doc->preserveWhiteSpace = false;
+ $doc->loadXML($request_node->asXML());
+ $doc->formatOutput = true;
+
+ $this->model_extension_openbay_amazonus->updateAmazonusOrderTracking($order_id, $courier_id, $courier_from_list, !empty($courier_id) ? $tracking_no : '');
+ $log->write('Request: ' . $doc->saveXML());
+ $response = $this->call('order/update2', $doc->saveXML(), false);
+ $log->write("Response for Order's status update: $response");
+ }
+
+ public function getCategoryTemplates() {
+ $result = $this->call("productv2/RequestTemplateList", array('list' => true));
+ if(isset($result)) {
+ return (array)json_decode($result);
+ } else {
+ return array();
+ }
+ }
+
+ public function registerInsertion($data) {
+ $result = $this->call("productv2/RegisterInsertionRequest", $data);
+ if(isset($result)) {
+ return (array)json_decode($result);
+ } else {
+ return array();
+ }
+ }
+
+ public function insertProduct($data) {
+ $result = $this->call("productv2/InsertProductRequest", $data);
+ if(isset($result)) {
+ return (array)json_decode($result);
+ } else {
+ return array();
+ }
+ }
+
+ public function updateQuantities($data) {
+ $result = $this->call("product/UpdateQuantityRequest", $data);
+ if(isset($result)) {
+ return (array)json_decode($result);
+ } else {
+ return array();
+ }
+ }
+
+ public function getStockUpdatesStatus($data) {
+ $result = $this->call("status/StockUpdates", $data);
+ if(isset($result)) {
+ return $result;
+ } else {
+ return false;
+ }
+ }
+
+ public function putStockUpdateBulk($product_id_array, $end_inactive = false){
+ $logger = new \Log('amazonus_stocks.log');
+ $logger->write('putStockUpdateBulk(), End inactive: ' . $end_inactive . ', ids: ' . json_encode($product_id_array));
+
+ $quantity_data = array();
+
+ foreach($product_id_array as $product_id) {
+ $linked_skus = $this->db->query("SELECT `amazonus_sku` FROM `" . DB_PREFIX . "amazonus_product_link` WHERE `product_id` = '" . (int)$product_id . "'")->rows;
+
+ if (!empty($linked_skus)) {
+ foreach($linked_skus as $sku) {
+ $product = $this->db->query("SELECT quantity, status FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "'")->row;
+
+ if(!empty($product)) {
+ if($end_inactive && $product['status'] == '0') {
+ $quantity_data[$sku['amazonus_sku']] = 0;
+ } else {
+ $quantity_data[$sku['amazonus_sku']] = $product['quantity'];
+ }
+ }
+ }
+ } else {
+ $logger->write('No linked SKU');
+ }
+ }
+
+ if(!empty($quantity_data)) {
+ $logger->write('New Qty:' . print_r($quantity_data, true));
+
+ $response = $this->updateQuantities($quantity_data);
+
+ $logger->write('API Response: ' . print_r($response, true));
+ } else {
+ $logger->write('No update needed');
+ }
+ }
+
+ public function getOrderdProducts($order_id) {
+ 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;
+ }
+
+ public function validate() {
+ if ($this->config->get('openbay_amazonus_status') != 0 &&
+ $this->config->get('openbay_amazonus_token') != '' &&
+ $this->config->get('openbay_amazonus_encryption_key') != '' &&
+ $this->config->get('openbay_amazonus_encryption_iv') != '') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function deleteProduct($product_id){
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "amazonus_product_link` WHERE `product_id` = '" . (int)$product_id . "'");
+ }
+
+ public function orderDelete($order_id){
+ /**
+ * @todo
+ */
+ }
+
+ public function getOrder($order_id) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "amazonus_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ return $qry->row;
+ } else {
+ return false;
+ }
+ }
+
+ public function getCarriers() {
+ return array(
+ "Blue Package",
+ "Canada Post",
+ "City Link",
+ "DHL",
+ "DHL Global Mail",
+ "Fastway",
+ "FedEx",
+ "FedEx SmartPost",
+ "GLS",
+ "GO!",
+ "Hermes Logistik Gruppe",
+ "Newgistics",
+ "NipponExpress",
+ "OSM",
+ "OnTrac",
+ "Parcelforce",
+ "Royal Mail",
+ "SagawaExpress",
+ "Streamlite",
+ "TNT",
+ "Target",
+ "UPS",
+ "UPS Mail Innovations",
+ "USPS",
+ "YamatoTransport",
+ );
+ }
+
+ public function parseCategoryTemplate($xml) {
+ $simplexml = null;
+
+ libxml_use_internal_errors(true);
+ if(($simplexml = simplexml_load_string($xml)) == false) {
+ return false;
+ }
+
+ $category = (string)$simplexml->filename;
+
+ $tabs = array();
+ foreach($simplexml->tabs->tab as $tab) {
+ $attributes = $tab->attributes();
+ $tabs[] = array(
+ 'id' => (string)$attributes['id'],
+ 'name' => (string)$tab->name,
+ );
+ }
+
+ $fields = array();
+ $field_types = array('required', 'desired', 'optional');
+ foreach ($field_types as $type) {
+ foreach ($simplexml->fields->$type->field as $field) {
+ $attributes = $field->attributes();
+ $fields[] = array(
+ 'name' => (string)$attributes['name'],
+ 'title' => (string)$field->title,
+ 'definition' => (string)$field->definition,
+ 'accepted' => (array)$field->accepted,
+ 'type' => (string)$type,
+ 'child' => false,
+ 'order' => (isset($attributes['order'])) ? (string)$attributes['order'] : '',
+ 'tab' => (string)$attributes['tab'],
+ );
+ }
+ foreach ($simplexml->fields->$type->childfield as $field) {
+ $attributes = $field->attributes();
+ $fields[] = array(
+ 'name' => (string)$attributes['name'],
+ 'title' => (string)$field->title,
+ 'definition' => (string)$field->definition,
+ 'accepted' => (array)$field->accepted,
+ 'type' => (string)$type,
+ 'child' => true,
+ 'parent' => (array)$field->parent,
+ 'order' => (isset($attributes['order'])) ? (string)$attributes['order'] : '',
+ 'tab' => (string)$attributes['tab'],
+ );
+ }
+ }
+
+ foreach($fields as $index => $field) {
+ $fields[$index]['unordered_index'] = $index;
+ }
+
+ usort($fields, array('openbay\Amazonus','compareFields'));
+
+ return array(
+ 'category' => $category,
+ 'fields' => $fields,
+ 'tabs' => $tabs,
+ );
+ }
+
+ private static function compareFields($field1, $field2) {
+ if($field1['order'] == $field2['order']) {
+ return ($field1['unordered_index'] < $field2['unordered_index']) ? -1 : 1;
+ } else if(!empty($field1['order']) && empty($field2['order'])) {
+ return -1;
+ } else if(!empty($field2['order']) && empty($field1['order'])) {
+ return 1;
+ } else {
+ return ($field1['order'] < $field2['order']) ? -1 : 1;
+ }
+ }
+}
diff --git a/public/system/library/openbay/ebay.php b/public/system/library/openbay/ebay.php
new file mode 100644
index 0000000..f94d48d
--- /dev/null
+++ b/public/system/library/openbay/ebay.php
@@ -0,0 +1,1514 @@
+<?php
+namespace openbay;
+
+final class Ebay {
+ private $token;
+ private $encryption_key;
+ private $encryption_iv;
+ private $url = 'https://uk.openbaypro.com/';
+ private $registry;
+ private $no_log = array('notification/getPublicNotifications/', 'setup/getEbayCategories/', 'item/getItemAllList/', 'account/validate/', 'item/getItemListLimited/');
+ private $logger;
+ private $max_log_size = 50; //max log size in Mb
+
+ public function __construct($registry) {
+ $this->registry = $registry;
+ $this->token = $this->config->get('ebay_token');
+ $this->secret = $this->config->get('ebay_secret');
+ $this->logging = $this->config->get('ebay_logging');
+ $this->tax = $this->config->get('ebay_tax');
+ $this->server = 1;
+ $this->lasterror = '';
+ $this->lastmsg = '';
+
+ if ($this->logging == 1) {
+ $this->setLogger();
+ }
+
+ $this->setEncryptionKey($this->config->get('ebay_encryption_key'));
+ $this->setEncryptionIv($this->config->get('ebay_encryption_iv'));
+ }
+
+ public function __get($name) {
+ return $this->registry->get($name);
+ }
+
+ public function getEncryptionKey() {
+ return $this->encryption_key;
+ }
+
+ public function setEncryptionKey($key) {
+ $this->encryption_key = $key;
+ }
+
+ public function getEncryptionIv() {
+ return $this->encryption_iv;
+ }
+
+ public function setEncryptionIv($encryption_iv) {
+ $this->encryption_iv = $encryption_iv;
+ }
+
+ public function call($call, array $post = null, array $options = array(), $content_type = 'json', $status_override = false) {
+ if ($this->config->get('ebay_status') == 1 || $status_override == true) {
+ $this->lasterror = '';
+ $this->lastmsg = '';
+
+ if (!in_array($call, $this->no_log)) {
+ $this->log('call(' . $call . ') - Data: ' . json_encode($post));
+ }
+
+ if (defined("HTTPS_CATALOG")) {
+ $domain = HTTPS_CATALOG;
+ } else {
+ $domain = $this->config->get('config_url');
+ }
+
+ $headers = array();
+ $headers[] = 'X-Endpoint-Version: 2';
+
+ $data = array('token' => $this->token, 'secret' => $this->secret, 'server' => $this->server, 'domain' => $domain, 'openbay_version' => (int)$this->config->get('feed_openbaypro_version'), 'opencart_version' => VERSION, 'data' => $post, 'content_type' => $content_type, 'language' => $this->config->get('feed_openbaypro_language'));
+
+ $defaults = array(
+ CURLOPT_HEADER => 0,
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_POST => 1,
+ CURLOPT_URL => $this->url . $call,
+ CURLOPT_USERAGENT => "OpenBay Pro for eBay/OpenCart",
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query($data, '', "&")
+ );
+
+ $curl = curl_init();
+ curl_setopt_array($curl, ($options + $defaults));
+ if (! $result = curl_exec($curl)) {
+ $this->log('call() - Curl Failed ' . curl_error($curl) . ' ' . curl_errno($curl));
+ }
+ curl_close($curl);
+
+ if (!in_array($call, $this->no_log)) {
+ $this->log('call() - Result of : "' . $result . '"');
+ }
+
+ if ($content_type == 'json') {
+ $encoding = mb_detect_encoding($result);
+
+ if ($encoding == 'UTF-8') {
+ $result = preg_replace('/[^(\x20-\x7F)]*/', '', $result);
+ }
+
+ $result = json_decode($result, 1);
+ $this->lasterror = $result['error'];
+ $this->lastmsg = $result['msg'];
+
+ if (!empty($result['data'])) {
+ return $result['data'];
+ } else {
+ return false;
+ }
+ }elseif ($content_type == 'xml') {
+ $result = simplexml_load_string($result);
+ $this->lasterror = $result->error;
+ $this->lastmsg = $result->msg;
+
+ if (!empty($result->data)) {
+ return $result->data;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ $this->log('call() - OpenBay Pro not active');
+ }
+ }
+
+ public function callNoResponse($call, array $post = null, array $options = array(), $content_type = 'json') {
+ if ($this->config->get('ebay_status') == 1) {
+ $this->log('openbay_noresponse_call(' . $call . ') - Data :' . json_encode($post));
+
+ if (defined("HTTPS_CATALOG")) {
+ $domain = HTTPS_CATALOG;
+ } else {
+ $domain = $this->config->get('config_url');
+ }
+
+ $headers = array();
+ $headers[] = 'X-Endpoint-Version: 2';
+
+ $data = array('token' => $this->token, 'secret' => $this->secret, 'server' => $this->server, 'domain' => $domain, 'openbay_version' => (int)$this->config->get('feed_openbaypro_version'), 'opencart_version' => VERSION, 'data' => $post, 'content_type' => $content_type, 'language' => $this->config->get('feed_openbaypro_language'));
+
+ $defaults = array(
+ CURLOPT_HEADER => 0,
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_POST => 1,
+ CURLOPT_URL => $this->url . $call,
+ CURLOPT_USERAGENT => "OpenBay Pro for eBay/OpenCart",
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 0,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 5,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_POSTFIELDS => http_build_query($data, '', "&")
+ );
+
+ $curl = curl_init();
+ curl_setopt_array($curl, ($options + $defaults));
+ curl_exec($curl);
+ $this->log(curl_error($curl));
+ curl_close($curl);
+ } else {
+ $this->log('openbay_noresponse_call() - OpenBay Pro not active . ');
+ }
+ }
+
+ private function setLogger() {
+ if(file_exists(DIR_LOGS . 'ebaylog.log')) {
+ if(filesize(DIR_LOGS . 'ebaylog.log') > ($this->max_log_size * 1000000)) {
+ rename(DIR_LOGS . 'ebaylog.log', DIR_LOGS . '_ebaylog_' . date('Y-m-d_H-i-s') . '.log');
+ }
+ }
+
+ $this->logger = new \Log('ebaylog.log');
+ }
+
+ public function log($data, $write = true) {
+ if ($this->logging == 1) {
+ if (function_exists('getmypid')) {
+ $process_id = getmypid();
+ $data = $process_id . ' - ' . print_r($data, true);
+ }
+
+ $this->logger->write($data);
+ }
+ }
+
+ public function getServer() {
+ return $this->url;
+ }
+
+ public function getSetting($key) {
+ $qry = $this->db->query("SELECT `data` FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = '" . $this->db->escape($key) . "' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ return unserialize($qry->row['data']);
+ } else {
+ return false;
+ }
+ }
+
+ public function getEbayItemId($product_id) {
+ $this->log('getEbayItemId() - Product ID: ' . $product_id);
+
+ $qry = $this->db->query("SELECT `ebay_item_id` FROM `" . DB_PREFIX . "ebay_listing` WHERE `product_id` = '" . (int)$product_id . "' AND `status` = '1' LIMIT 1");
+
+ if (!$qry->num_rows) {
+ $this->log('No link found - getEbayItemId()');
+ return false;
+ } else {
+ $this->log('Returning ' . $qry->row['ebay_item_id'] . ' - getEbayItemId()');
+ return $qry->row['ebay_item_id'];
+ }
+ }
+
+ public function getEndedEbayItemId($product_id) {
+ $this->log('getEndedEbayItemId() - ID: ' . $product_id);
+
+ $qry = $this->db->query("SELECT `ebay_item_id` FROM `" . DB_PREFIX . "ebay_listing` WHERE `product_id` = '" . (int)$product_id . "' AND `status` = '0' ORDER BY `ebay_listing_id` DESC LIMIT 1");
+
+ if (!$qry->num_rows) {
+ $this->log('getEndedEbayItemId() - No link');
+ return false;
+ } else {
+ $this->log('getEndedEbayItemId() - Returning ' . $qry->row['ebay_item_id']);
+ return $qry->row['ebay_item_id'];
+ }
+ }
+
+ public function removeItemByItemId($item_id) {
+ $this->log('removeItemByItemId() - ID: ' . $item_id);
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_listing` SET `status` = '0' WHERE `ebay_item_id` = '" . $this->db->escape($item_id) . "'");
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "ebay_stock_reserve` WHERE `item_id` = '" . $this->db->escape($item_id) . "'");
+ }
+
+ public function removeItemByProductId($product_id) {
+ $this->log('removeItemByProductId() - ID: ' . $product_id . '');
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_listing` SET `status` = '0' WHERE `product_id` = '" . (int)$product_id . "'");
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "ebay_stock_reserve` WHERE `product_id` = '" . (int)$product_id . "'");
+ }
+
+ public function deleteProduct($product_id) {
+ $this->log('deleteProduct() - ID: ' . $product_id);
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "ebay_listing` WHERE `product_id` = '" . (int)$product_id . "'");
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "ebay_stock_reserve` WHERE `product_id` = '" . (int)$product_id . "'");
+ }
+
+ public function orderDelete($order_id) {
+ /**
+ * @todo
+ */
+ }
+
+ public function getLiveListingArray() {
+ /*
+ * Returns the list of linked items with eBay from the database
+ * @return array ([product id] = ebay item id)
+ */
+ $this->log('getLiveListingArray()');
+
+ $qry = $this->db->query("SELECT `product_id`, `ebay_item_id` FROM `" . DB_PREFIX . "ebay_listing` WHERE `status` = '1'");
+
+ $data = array();
+ if ($qry->num_rows > 0) {
+ foreach ($qry->rows as $row) {
+ $data[$row['product_id']] = $row['ebay_item_id'];
+ }
+ }
+
+ return $data;
+ }
+
+ public function getEndedListingArray() {
+ $this->log('getEndedListingArray()');
+ $active = $this->getLiveListingArray();
+
+ $qry = $this->db->query("SELECT e.* FROM (SELECT `product_id`, MAX(`ebay_listing_id`) as `ebay_listing_id` FROM `" . DB_PREFIX . "ebay_listing` WHERE `status` = 0 GROUP BY `product_id`) `a` INNER JOIN `" . DB_PREFIX . "ebay_listing` `e` ON (`e`.`ebay_listing_id` = `a`.`ebay_listing_id`)");
+
+ $data = array();
+ if ($qry->num_rows > 0) {
+ foreach ($qry->rows as $row) {
+ $data[$row['product_id']] = $row['ebay_item_id'];
+ }
+ }
+
+ foreach ($active as $k => $v) {
+ if (array_key_exists($k, $data)) {
+ unset($data[$k]);
+ }
+ }
+
+ return $data;
+ }
+
+ public function getLiveProductArray() {
+ /**
+ * Returns the list of linked items with eBay from the database
+ * @return array ([ebay item id] = product id)
+ */
+ $qry = $this->db->query("SELECT `product_id`, `ebay_item_id` FROM `" . DB_PREFIX . "ebay_listing` WHERE `status` = '1'");
+
+ $data = array();
+ if ($qry->num_rows) {
+ foreach ($qry->rows as $row) {
+ $data[$row['ebay_item_id']] = $row['product_id'];
+ }
+ }
+
+ return $data;
+ }
+
+ public function endItem($item_id) {
+ $this->log('endItem() - ID "' . $item_id);
+
+ if ($this->config->get('ebay_enditems') == 1) {
+ $this->call('item/endItem/', array('id' => $item_id));
+ $this->removeItemByItemId($item_id);
+
+ if ($this->lasterror != true) {
+ $this->log('endItem() - OK');
+ return array('error' => false, 'msg' => 'ok');
+ } else {
+ return array('error' => true, 'msg' => $this->lasterror);
+ }
+ } else {
+ $this->removeItemByItemId($item_id);
+ $this->log('endItem() - config has disabled ending items');
+
+ $message = "An item has gone out of stock but your settings are not set to end eBay items automatically.\r\n\r\n";
+ $message.= "You need to ensure you have stock left of this item or end your eBay listing manually.\r\n\r\n";
+ $message.= "eBay item ID: $item_id";
+
+ $this->notifyAdmin('eBay item not ended: ' . $item_id, $message);
+
+ return array('error' => true, 'msg' => 'Settings do not allow you to end items, but the link has been removed . ');
+ }
+ }
+
+ public function ebaySaleStockReduce($product_id, $sku = null) {
+ /**
+ * Gets the product info from an ID and sends to ebay update method.
+ */
+ $this->log('ebaySaleStockReduce() - Is stock update needed (Item ID: ' . $product_id . ',SKU: ' . $sku . ')');
+
+ if (!empty($product_id)) {
+ if ($sku == null) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "' LIMIT 1");
+ $this->log('ebaySaleStockReduce() - Send item ID: "' . $product_id . '", Stock: "' . $query->row['quantity'] . '" to decideEbayStockAction()');
+ $this->decideEbayStockAction($product_id, $query->row['quantity'], $query->row['subtract']);
+ } else {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "product_option_variant` WHERE `product_id` = '" . (int)$product_id . "' AND `sku` = '" . $this->db->escape($sku) . "' LIMIT 1");
+ $this->log('ebaySaleStockReduce() - Send item ID: ' . $product_id . ', VAR: ' . $sku . ', passing ' . $query->row['stock'] . ' to decideEbayStockAction()');
+ $this->decideEbayStockAction($product_id, $query->row['stock'], $query->row['subtract'], $sku);
+ }
+ }
+ }
+
+ public function notifyAdmin($subject, $message) {
+ $this->log('Sending email to: ' . $this->config->get('config_email') . ' - notifyAdmin()');
+
+ $mail = new \Mail();
+ $mail->protocol = $this->config->get('config_mail_protocol');
+ $mail->parameter = $this->config->get('config_mail_parameter');
+ $mail->smtp_hostname = $this->config->get('config_mail_smtp_hostname');
+ $mail->smtp_username = $this->config->get('config_mail_smtp_username');
+ $mail->smtp_password = html_entity_decode($this->config->get('config_mail_smtp_password'), ENT_QUOTES, 'UTF-8');
+ $mail->smtp_port = $this->config->get('config_mail_smtp_port');
+ $mail->smtp_timeout = $this->config->get('config_mail_smtp_timeout');
+
+ $mail->setTo($this->config->get('config_email'));
+ $mail->setFrom($this->config->get('config_email'));
+ $mail->setSender(html_entity_decode($this->config->get('config_name'), ENT_QUOTES, 'UTF-8'));
+ $mail->setSubject(html_entity_decode($subject, ENT_QUOTES, 'UTF-8'));
+ $mail->setText($message);
+ $mail->send();
+ }
+
+ public function validateJsonDecode($data) {
+ $data = (string)$data;
+
+ $encoding = mb_detect_encoding($data);
+
+ if ($encoding == 'UTF-8') {
+ $data = preg_replace('/[^(\x20-\x7F)]*/', '', $data);
+ $data = preg_replace('#\\\\x[0-9a-fA-F]{2,2}#', '', $data);
+ }
+
+ $data = json_decode($data);
+
+ if (function_exists('json_last_error')) {
+ switch (json_last_error()) {
+ case JSON_ERROR_NONE:
+ $this->log('validateJsonDecode() - No json decode errors');
+ break;
+ case JSON_ERROR_DEPTH:
+ $this->log('validateJsonDecode() - Maximum stack depth exceeded');
+ break;
+ case JSON_ERROR_STATE_MISMATCH:
+ $this->log('validateJsonDecode() - Underflow or the modes mismatch');
+ break;
+ case JSON_ERROR_CTRL_CHAR:
+ $this->log('validateJsonDecode() - Unexpected control character found');
+ break;
+ case JSON_ERROR_SYNTAX:
+ $this->log('validateJsonDecode() - Syntax error, malformed JSON');
+ break;
+ case JSON_ERROR_UTF8:
+ $this->log('validateJsonDecode() - Malformed UTF-8 characters, possibly incorrectly encoded');
+ break;
+ default:
+ $this->log('validateJsonDecode() - Unknown error');
+ break;
+ }
+ } else {
+ $this->log('validateJsonDecode() - json_last_error PHP function does not exist');
+ }
+
+ return $data;
+ }
+
+ private function eBayShippingStatus($item, $txn, $status, $tracking_no = '', $carrier_id = '') {
+ $this->log('eBayShippingStatus() - Update order shipping status (Item: ' . $item . ',Txn: ' . $txn . ',Status:' . $status . ',Tracking: ' . $tracking_no . ', Carrier: ' . $carrier_id . ')');
+ return $this->call('order/shippingStatus/', array('item' => $item, 'txn' => $txn, 'status' => $status, 'carrier' => $carrier_id, 'tracking' => $tracking_no));
+ }
+
+ private function eBayPaymentStatus($item, $txn, $status) {
+ $this->log('eBayPaymentStatus() - Updates order payment status (Item: ' . $item . ',Txn: ' . $txn . ',Status:' . $status . ')');
+ return $this->call('order/paymentStatus/', array('item' => $item, 'txn' => $txn, 'status' => $status));
+ }
+
+ private function getSaleRecord($sale_id) {
+ $this->log('getSaleRecord() - Get ebay sale record ID: ' . $sale_id);
+ return $this->call('order/getSmpRecord/', array('id' => $sale_id));
+ }
+
+ public function getEbayActiveListings() {
+ $this->log('getEbayActiveListings() - Get active eBay items from API');
+ return $this->call('item/getItemAllList/');
+ }
+
+ public function getEbayItemList($limit = 100, $page = 1, $filter = array()) {
+ $this->log('getEbayItemList() - Get active eBay items from API');
+ return $this->call('item/getItemListLimited/', array('page' => $page, 'limit' => $limit, 'filter' => $filter));
+ }
+
+ public function disableProduct($product_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "product` SET `status` = 0 WHERE `product_id` = '" . (int)$product_id . "' LIMIT 1");
+ }
+
+ public function disableVariant($product_id, $sku) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "product_option_variant` SET `active` = 0 WHERE `product_id` = '" . (int)$product_id . "' AND `sku` = '" . $this->db->escape($sku) . "' LIMIT 1");
+ }
+
+ public function putStockUpdate($item_id, $stock, $sku = null) {
+ $this->log('putStockUpdate()');
+ $this->log('putStockUpdate() - New local stock: ' . $stock);
+
+ $listing = $this->call('item/getItem', array('itemId' => $item_id));
+ $product_id = $this->getProductId($item_id);
+ $reserve = $this->getReserve($product_id, $item_id, (($sku != null) ? $sku : ''));
+
+ if ($listing['status'] == 1 ) {
+ if ($reserve != false) {
+ $this->log('putStockUpdate() - Reserve stock: ' . $reserve);
+
+ if ($stock > $reserve) {
+ $this->log('putStockUpdate() - Stock is larger than reserve, setting level to reserve');
+ $stock = $reserve;
+ }
+ }
+
+ if ($sku == null) {
+ $this->log('putStockUpdate() - Listing stock: ' . $listing['qty'] . ', new stock: ' . $stock);
+
+ if ($stock <= 0) {
+ if ($this->config->get('ebay_disable_nostock') == 1) {
+ $this->disableProduct($product_id);
+ }
+
+ $this->endItem($item_id);
+ return true;
+ }elseif ($listing['qty'] != $stock) {
+ $this->call('item/reviseStock/', array('itemId' => $item_id, 'stock' => $stock));
+ $this->log('putStockUpdate() - OK');
+ return true;
+ } else {
+ $this->log('putStockUpdate() - No update needed');
+ return false;
+ }
+ } else {
+ // Need to loop over current item check if other variants have stock
+ $variant_stock = false;
+ foreach ($listing['variation']['vars'] as $var) {
+ if (($var['sku'] != $sku) && ($var['qty'] > 0)) {
+ //other variations have stock
+ $variant_stock = true;
+ $this->log('Another variation has stock (SKU: ' . $var['sku'] . ')');
+ break;
+ }
+ }
+
+ if ($stock <= 0) {
+ if ($this->config->get('ebay_disable_nostock') == 1) {
+ $this->disableVariant($product_id, $sku);
+ }
+ }
+
+ if ($variant_stock == true || $stock > 0) {
+ $this->log('putStockUpdate() - Revising item with Item ID "' . $item_id . '" to stock level "' . $stock . '", sku "' . $sku . '"');
+ $this->call('item/reviseStock/', array('itemId' => $item_id, 'stock' => $stock, 'sku' => $sku));
+ return true;
+ } else {
+ $this->log('putStockUpdate() - Sending end for item, no variants have stock!');
+ $this->endItem($item_id);
+ }
+ }
+ } else {
+ $this->removeItemByItemId($item_id);
+
+ if($sku == null) {
+ if ($stock <= 0 && $this->config->get('ebay_disable_nostock') == 1) {
+ $this->disableProduct($product_id);
+ }
+ } else {
+ if ($stock <= 0 && $this->config->get('ebay_disable_nostock') == 1) {
+ $this->disableVariant($product_id, $sku);
+ }
+ }
+
+ $this->log('putStockUpdate() - Listing not active, item id: ' . $item_id . ', status returned: ' . $listing['statusActual']);
+ }
+ }
+
+ public function putStockUpdateBulk($product_id_array, $end_inactive = false) {
+ // We know is that these product ID's have been modified. They should only be passed if the stock has changed so we can assume this.
+ $this->log('putStockUpdateBulk()');
+
+ $openstock = false;
+ if ($this->openbay->addonLoad('openstock') == true) {
+ $this->load->model('extension/module/openstock');
+ $openstock = true;
+ }
+
+ // Get the active OpenCart items that were linked to eBay If they have stock now, relist them.
+ $ended_data = $this->getEndedListingArray();
+
+ /**
+ * Get the active OpenCart items that are also linked
+ * Compare against the stock from eBay
+ * If listing active and local stock = 0, end it
+ * If listing inactive, remove link
+ * If listing active and local stock not the same, update it
+ */
+ $ebay_listings = $this->getEbayActiveListings();
+ $live_data = $this->getLiveListingArray();
+
+ $linked_items = array();
+ $linked_ended_items = array();
+
+ foreach ($product_id_array as $product_id) {
+ if (array_key_exists((int)$product_id, $live_data)) {
+ //product has been passed and is linked to active item
+ $linked_items[] = array('productId' => (int)$product_id, 'itemId' => $live_data[$product_id]);
+ }elseif (array_key_exists((int)$product_id, $ended_data)) {
+ //product has been passed and is not currently active
+ $linked_ended_items[] = array('productId' => (int)$product_id, 'itemId' => $ended_data[$product_id]);
+ } else {
+ //product does not exist in live or ended links so has never been linked.
+ }
+ }
+
+ //loop through ended listings, if back in stock and not multi var - relist it
+ foreach ($linked_ended_items as $item) {
+ if ($openstock == true) {
+ $options = $this->model_extension_module_openstock->getVariants($item['productId']);
+ } else {
+ $options = array();
+ }
+
+ if (empty($options)) {
+ //get the stock level of the linked items
+ $local_stock = $this->getProductStockLevel($item['productId']);
+
+ if ((int)$local_stock['quantity'] > 0 && $local_stock['status'] == 1) {
+ //product has stock and is enabled, so re list it.
+ $reserve = $this->getReserve($item['productId'], $item['itemId']);
+
+ if ($reserve != false) {
+ if ($local_stock['quantity'] > $reserve) {
+ $local_stock['quantity'] = $reserve;
+ }
+ }
+
+ if ($this->config->get('ebay_relistitems') == 1) {
+ //relist item with new stock
+ $this->relistItem($item['itemId'], $item['productId'], (int)$local_stock['quantity']);
+ }
+ }
+ } else {
+ $this->log('putStockUpdateBulk() - options existed for item (' . $item['itemId'] . ') when trying to relist');
+ // @todo - support relisting of variant items, if possible with ebay!
+ }
+ }
+
+ //loop through the active listings and update the store or end the item
+ foreach ($linked_items as $item) {
+ //get the stock level of the linked item
+ $local_stock = $this->getProductStockLevel($item['productId']);
+
+ //check if the itemid was returned by ebay, if not unlink it as it is ended.
+ if (!isset($ebay_listings[$item['itemId']])) {
+ $this->log('eBay item was not returned, removing link (' . $item['itemId'] . ')');
+ $this->removeItemByItemId($item['itemId']);
+ } else {
+ //check if the local item is now inactive - end if it is
+ if ($end_inactive == true && $local_stock['status'] == 0) {
+ $this->endItem($item['itemId']);
+ } else {
+ //get any options that are set for this product
+ if ($openstock == true) {
+ $options = $this->model_extension_module_openstock->getVariants($item['productId']);
+ } else {
+ $options = array();
+ }
+
+ if (empty($options) && empty($ebay_listings[$item['itemId']]['variants'])) {
+ $this->log('putStockUpdateBulk() - Item has no variants');
+
+ //compare to the ebay data get retrieved
+ if ((int)$local_stock['quantity'] != (int)$ebay_listings[$item['itemId']]['qty']) {
+ $reserve = $this->getReserve($item['productId'], $item['itemId']);
+
+ if ($reserve != false) {
+ if ($local_stock['quantity'] > $reserve) {
+ $local_stock['quantity'] = $reserve;
+ }
+ }
+
+ $this->putStockUpdate($item['itemId'], (int)$local_stock['quantity']);
+ }
+ }elseif (!empty($options) && !empty($ebay_listings[$item['itemId']]['variants'])) {
+ // This item has variants
+ $this->log('putStockUpdateBulk() - Variants found');
+
+ //create an index of var codes to search against
+ $var_ids = array();
+ foreach ($options as $k => $v) {
+ $var_ids[$k] = $v['var'];
+ }
+
+ //loop over eBay variants
+ foreach ($ebay_listings[$item['itemId']]['variants'] as $ebay_variant) {
+ $this->log('Checking eBay SKU: ' . $ebay_variant['sku'] . ' for item: ' . $item['itemId']);
+
+ if (in_array($ebay_variant['sku'], $var_ids)) {
+ $option_id = array_search($ebay_variant['sku'], $var_ids);
+
+ //compare the stock - if different trigger update
+ if ($ebay_variant['qty'] != $options[$option_id]['stock']) {
+ $reserve = $this->getReserve($item['productId'], $item['itemId'], $ebay_variant['sku']);
+
+ if ($reserve != false) {
+ if ($options[$option_id]['stock'] > $reserve) {
+ $options[$option_id]['stock'] = $reserve;
+ }
+ }
+
+ $this->log('putStockUpdateBulk() - Revising variant item: ' . $item['itemId'] . ',Stock: ' . $options[$option_id]['stock'] . ', SKU ' . $ebay_variant['sku']);
+ $this->call('item/reviseStock/', array('itemId' => $item['itemId'], 'stock' => $options[$option_id]['stock'], 'sku' => $ebay_variant['sku']));
+ }
+ }
+ }
+ } else {
+ $this->log('Unsure if this item has variants, debug:');
+ $this->log('Local: ' . $options);
+ $this->log('eBay: ' . serialize($ebay_listings[$item['itemId']]['variants']));
+ }
+ }
+ }
+ }
+ }
+
+ public function getProductStockLevel($product_id, $sku = '') {
+ $this->log('getProductStockLevel() - ID: ' . $product_id . ', SKU: ' . $sku);
+
+ if ($sku == '' || $sku == null) {
+ $qry = $this->db->query("SELECT `quantity`, `status` FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "' LIMIT 1");
+
+ return array('quantity' => (int)$qry->row['quantity'], 'status' => ($qry->row['status']));
+ } else {
+ $qry = $this->db->query("SELECT `stock`, `active` FROM `" . DB_PREFIX . "product_option_variant` WHERE `product_id` = '" . (int)$product_id . "' AND `sku` = '" . $this->db->escape($sku) . "' LIMIT 1");
+
+ return array('quantity' => (int)$qry->row['stock'], 'status' => ($qry->row['active']));
+ }
+ }
+
+ public function productUpdateListen($product_id, $data = array()) {
+ $this->log('productUpdateListen(' . $product_id . ')');
+
+ $item_id = $this->getEbayItemId($product_id);
+
+ $product = $this->db->query("SELECT DISTINCT * FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$product_id . "' LIMIT 1")->row;
+
+ if ($item_id != false) {
+ $this->log('productUpdateListen(' . $product_id . ') - listing found (' . $item_id . ')');
+
+ if ($this->openbay->addonLoad('openstock') && (isset($product['has_option']) && $product['has_option'] == 1)) {
+ $this->load->model('extension/module/openstock');
+ $this->load->model('tool/image');
+ $this->load->model('catalog/product');
+
+ $this->log('productUpdateListen(' . $product_id . ') - Variant');
+
+ if (!isset($data['variant'])) {
+ $variants = $this->model_extension_module_openstock->getVariants($product_id);
+ } else {
+ $variants = $data['variant'];
+ }
+
+ $variant_data = array();
+
+ $groups = $this->openbay->getProductOptions($product_id);
+ $variant_data['groups'] = array();
+ $variant_data['related'] = array();
+
+ foreach ($groups as $grp) {
+ $t_tmp = array();
+ foreach ($grp['product_option_value'] as $grp_node) {
+ $t_tmp[$grp_node['option_value_id']] = $grp_node['name'];
+
+ $variant_data['related'][$grp_node['product_option_value_id']] = $grp['name'];
+ }
+ $variant_data['groups'][] = array('name' => $grp['name'], 'child' => $t_tmp);
+ }
+
+ $v = 0;
+ $stock = false;
+
+ foreach ($variants as $option) {
+ if (!empty($option['sku'])) {
+ if ($option['stock'] > 0 || $stock == true) {
+ $stock = true;
+ }
+
+ // PRODUCT RESERVE LEVELS FOR VARIANT ITEMS (DOES NOT PASS THROUGH NORMAL SYSTEM)
+ $reserve = $this->getReserve($product_id, $item_id, $option['sku']);
+ if ($reserve != false) {
+ $this->log('productUpdateListen() / Variant (' . $option['sku'] . ') - Reserve stock: ' . $reserve);
+
+ if ($option['stock'] > $reserve) {
+ $this->log('putStockUpdate() - Stock (' . $option['stock'] . ') is larger than reserve (' . $reserve . '), setting level to reserve');
+ $option['stock'] = $reserve;
+ }
+ }
+
+ $variant_data['opt'][$v]['sku'] = $option['sku'];
+ $variant_data['opt'][$v]['qty'] = $option['stock'];
+ $variant_data['opt'][$v]['active'] = 0;
+
+ if ($option['active'] == 1) {
+ $variant_data['opt'][$v]['active'] = 1;
+ }
+
+ $v++;
+ }
+ }
+
+ $variant_data['groups'] = base64_encode(serialize($variant_data['groups']));
+ $variant_data['related'] = base64_encode(serialize($variant_data['related']));
+ $variant_data['id'] = $item_id;
+
+ //send to the api to process
+ if (!empty($variant_data['opt'])) {
+ if ($stock == true) {
+ $this->log('productUpdateListen() - Sending to API');
+ $response = $this->call('item/reviseStockVariants', $variant_data);
+
+ return $response;
+ } else {
+ $this->log('productUpdateListen() - Ending item');
+ $this->endItem($item_id);
+ }
+ }
+ } else {
+ $this->log('productUpdateListen(' . $product_id . ') - Not a variant');
+
+ $this->decideEbayStockAction($product_id, $product['quantity'], $product['subtract']);
+
+ return array('msg' => 'ok', 'error' => false);
+ }
+ } else {
+ $old_item_id = $this->getEndedEbayItemId($product_id);
+ $this->log('productUpdateListen(' . $product_id . ') - Standard item. Old ID: ' . $old_item_id);
+
+ if ($old_item_id != false) {
+ if ($this->openbay->addonLoad('openstock') && (isset($product['has_option']) && $product['has_option'] == 1)) {
+ $this->log('productUpdateListen(' . $product_id . ') - multi variant items relist not supported');
+ /**
+ * reserved for multi variant products can be relisted automatically.
+ */
+ } else {
+ $this->log('productUpdateListen(' . $product_id . ') - Normal, stock(' . $product['quantity'] . ') > 0');
+ if ($product['quantity'] > 0) {
+ if ($this->config->get('ebay_relistitems') == 1) {
+ $this->relistItem($old_item_id, $product_id, $product['quantity']);
+ }
+ }
+ }
+ } else {
+ $this->log('productUpdateListen() - stoping, nothing found');
+ }
+ }
+ }
+
+ public function orderStatusListen($order_id, $status_id, $data = array()) {
+ $ebay_order = $this->getOrder($order_id);
+
+ if (isset($ebay_order['smp_id'])) {
+ $ebay_id = $ebay_order['smp_id'];
+ } else {
+ $ebay_id = false;
+ }
+
+ $this->log('orderStatusListen() - Order ' . $order_id . ' changed status');
+
+ if ($ebay_id != false) {
+ $this->log('orderStatusListen() - It is an eBay order, new status: ' . $status_id);
+
+ $item_txn_array = $this->getSaleRecord($ebay_id);
+
+ if (!empty($item_txn_array)) {
+ //Has it been marked as paid?
+ if ($status_id == $this->config->get('ebay_status_paid_id')) {
+ $this->log('orderStatusListen() - Updating to paid status');
+ foreach ($item_txn_array as $item) {
+ $tmp = simplexml_load_string($this->eBayPaymentStatus($item['item'], $item['txn'], true));
+ }
+ }
+
+ // Has it been marked as shipped?
+ if ($status_id == $this->config->get('ebay_status_shipped_id')) {
+ $this->log('orderStatusListen() - Updating to shipped status');
+ foreach ($item_txn_array as $item) {
+ $tmp = simplexml_load_string($this->eBayShippingStatus($item['item'], $item['txn'], true, (isset($data['tracking_no']) ? $data['tracking_no'] : ''), (isset($data['carrier_id']) ? $data['carrier_id'] : '')));
+ }
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_order` SET `carrier_id` = '" . $this->db->escape((isset($data['carrier_id']) ? $data['carrier_id'] : '')) . "', `tracking_no` = '" . $this->db->escape((isset($data['tracking_no']) ? $data['tracking_no'] : '')) . "' WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+ }
+
+ //Has it been marked as cancelled?
+ if ($status_id == $this->config->get('ebay_status_cancelled_id')) {
+ $this->log('orderStatusListen() - Updating to cancelled status');
+ foreach ($item_txn_array as $item) {
+ $tmp = simplexml_load_string($this->eBayPaymentStatus($item['item'], $item['txn'], false));
+ }
+
+ foreach ($item_txn_array as $item) {
+ $tmp = simplexml_load_string($this->eBayShippingStatus($item['item'], $item['txn'], false));
+ }
+ }
+
+ //Has it been marked as refunded?
+ if ($status_id == $this->config->get('ebay_status_refunded_id')) {
+ $this->log('orderStatusListen() - Updating to refunded status');
+ foreach ($item_txn_array as $item) {
+ $tmp = simplexml_load_string($this->eBayPaymentStatus($item['item'], $item['txn'], false));
+ }
+
+ foreach ($item_txn_array as $item) {
+ $tmp = simplexml_load_string($this->eBayShippingStatus($item['item'], $item['txn'], false));
+ }
+ }
+ } else {
+ // @todo return error to use here
+ $this->log('orderStatusListen() - The TXN array was empty, could not get order info to update status. ');
+ }
+ } else {
+ $this->log('orderStatusListen() - It is not an eBay order');
+ }
+ }
+
+ public function decideEbayStockAction($product_id, $qty, $subtract, $sku = null) {
+ if ($subtract == 1) {
+ $this->log('decideEbayStockAction() - Product ID: ' . $product_id . ', Current stock: ' . $qty);
+
+ $item_id = $this->getEbayItemId($product_id);
+
+ if ($item_id != false) {
+ $this->putStockUpdate($item_id, $qty, $sku);
+ }
+ } else {
+ $this->log('decideEbayStockAction() - Product ID: ' . $product_id . ' does not subtract stock');
+ }
+ }
+
+ public function getProductId($ebay_item, $status = 0) {
+ $this->log('getProductId() - Item: ' . $ebay_item);
+
+ $status_sql = '';
+ if ($status == 1) {
+ $status_sql = ' AND `status` = 1';
+ }
+
+ $qry = $this->db->query("SELECT `product_id` FROM `" . DB_PREFIX . "ebay_listing` WHERE `ebay_item_id` = '" . $this->db->escape($ebay_item) . "'" . $status_sql . " ORDER BY `status` DESC, `ebay_listing_id` DESC LIMIT 1");
+
+ if (!$qry->num_rows) {
+ return false;
+ } else {
+ return $qry->row['product_id'];
+ }
+ }
+
+ public function getProductIdFromKey($key) {
+ $qry = $this->db->query("SELECT `product_id` FROM `" . DB_PREFIX . "ebay_listing_pending` WHERE `key` = '" . $this->db->escape($key) . "' LIMIT 1");
+
+ if (!$qry->num_rows) {
+ return false;
+ } else {
+ return $qry->row['product_id'];
+ }
+ }
+
+ public function validate() {
+ if ($this->config->get('ebay_status') != 0 && $this->config->get('ebay_token') != '' && $this->config->get('ebay_secret') != '' && $this->config->get('ebay_encryption_key') != '' && $this->config->get('ebay_encryption_iv') != '') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function getAllocatedStock($product_id) {
+ $qry = $this->db->query("SELECT SUM(`qty`) AS `total` FROM `" . DB_PREFIX . "ebay_transaction` WHERE `product_id` = '" . (int)$product_id . "' AND `order_id` = '0' LIMIT 1");
+ return (int)$qry->row['total'];
+ }
+
+ public function getImages() {
+ $this->log('getImages() - Getting product images . ');
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_image_import`");
+
+ if ($qry->num_rows) {
+ foreach ($qry->rows as $img) {
+ $this->log('Image: ' . $img['name']);
+
+ $img_large = str_replace(array('$_1.JPG', '$_01.JPG', '$_12.JPG'), '$_57.JPG', $img['image_original']);
+
+ $header_response = $this->getImageInfo($img_large);
+
+ $copy_status = false;
+
+ if ($header_response == 200) {
+ // a supersize version was found.
+ $copy_status = $this->getImageCopy($img_large, $img['image_new']);
+ } else {
+ // fall back to trying the original image
+ $header_response = $this->getImageInfo($img['image_original']);
+
+ if ($header_response == 200) {
+ $copy_status = $this->getImageCopy($img['image_original'], $img['image_new']);
+ }
+ }
+
+ if ($copy_status == true) {
+ if ($img['imgcount'] == 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "product` SET `image` = 'catalog/" . $img['name'] . "' WHERE `product_id` = '" . (int)$img['product_id'] . "' LIMIT 1");
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "product_image` SET `product_id` = '" . (int)$img['product_id'] . "', `image` = 'catalog/" . $this->db->escape($img['name']) . "', `sort_order` = '" . (int)$img['imgcount'] . "'");
+ }
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "ebay_image_import` WHERE `id` = '" . (int)$img['id'] . "' LIMIT 1");
+ }
+ }
+ }
+ }
+
+ private function getImageInfo($url) {
+ $curl = curl_init($url);
+ curl_setopt($curl, CURLOPT_NOBODY, true);
+
+ if(curl_exec($curl) === false) {
+ $this->log('Curl Error: ' . curl_error($curl));
+ }
+
+ $header_response = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+
+ $this->log($header_response);
+
+ curl_close($curl);
+
+ return $header_response;
+ }
+
+ private function getImageCopy($url, $image_new) {
+ $handle = @fopen($url, 'r');
+
+ if ($handle !== false) {
+ if (!@copy($url, $image_new)) {
+ $this->log('getImages() - FAILED COPY: ' . $url);
+ $this->log(print_r(error_get_last(), true));
+ return false;
+ } else {
+ $this->log('getImages() - Copy OK : ' . $url);
+ return true;
+ }
+ } else {
+ $this->log('getImages() - URL not found : ' . $url);
+ return false;
+ }
+ }
+
+ public function getEbayListing($item_id) {
+ $this->log('getEbayListing()');
+ return $this->call('item/getItem/', array('itemId' => $item_id));
+ }
+
+ public function relistItem($item_id, $product_id, $qty) {
+ $this->log('relistItem() - Starting relist item, ID: ' . $item_id . ', product: ' . $product_id . ', qty: ' . $qty);
+
+ $response = $this->call('listing/relistItem/', array('itemId' => $item_id, 'qty' => $qty));
+
+ if (!empty($response['ItemID'])) {
+ $this->log('relistItem() - Created: ' . $response['ItemID']);
+ $this->createLink($product_id, $response['ItemID'], '');
+ return $response['ItemID'];
+ } else {
+ $this->log('relistItem() - Relisting failed ID: ' . $item_id);
+ return false;
+ }
+ }
+
+ public function createLink($product_id, $item_id, $variant) {
+ $this->deleteProduct($product_id);
+ $this->removeItemByItemId($item_id);
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_listing` SET `product_id` = '" . (int)$product_id . "', `ebay_item_id` = '" . $this->db->escape($item_id) . "', `variant` = '" . (int)$variant . "', `status` = '1'");
+ }
+
+ public function addReserve($data, $item_id, $variant) {
+ if ($variant == 1) {
+ foreach ($data['opt'] as $variation) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "product_option_variant` WHERE `product_id` = '" . (int)$data['product_id'] . "' AND `sku` = '" . $this->db->escape($variation['sku']) . "' LIMIT 1");
+
+ if ($query->row['stock'] != $variation['qty']) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_stock_reserve` SET `product_id` = '" . (int)$data['product_id'] . "', `item_id` = '" . $this->db->escape($item_id) . "', `variant_id` = '" . $this->db->escape($variation['sku']) . "', `reserve` = '" . (int)$variation['qty'] . "'");
+ }
+ }
+ } else {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "product` WHERE `product_id` = '" . (int)$data['product_id'] . "' LIMIT 1");
+
+ if ($query->row['quantity'] != $data['qty'][0]) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_stock_reserve` SET `product_id` = '" . (int)$data['product_id'] . "', `item_id` = '" . $this->db->escape($item_id) . "', `variant_id` = '', `reserve` = '" . (int)$data['qty'][0] . "'");
+ }
+ }
+ }
+
+ public function getReserve($product_id, $item_id, $sku = '') {
+ $this->log('getReserve()');
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_stock_reserve` WHERE `product_id` = '" . (int)$product_id . "' AND `variant_id` = '" . $this->db->escape($sku) . "' AND `item_id` = '" . $this->db->escape($item_id) . "' LIMIT 1");
+
+ if ($query->num_rows > 0) {
+ $this->log('getReserve() - returning: ' . $query->row['reserve']);
+ return $query->row['reserve'];
+ } else {
+ $this->log('getReserve() - none');
+ return false;
+ }
+ }
+
+ public function updateReserve($product_id, $item_id, $reserve, $sku = '', $variant = 0) {
+ $this->log('updateReserve() - start');
+ $this->log('updateReserve() - $product_id: ' . $product_id);
+ $this->log('updateReserve() - $item_id: ' . $item_id);
+ $this->log('updateReserve() - $reserve: ' . $reserve);
+ $this->log('updateReserve() - $sku: ' . $sku);
+ $this->log('updateReserve() - $variant: ' . $variant);
+
+ if ($reserve == 0) {
+ $this->deleteReserve($product_id, $item_id, $sku);
+ } else {
+ if ($this->getReserve($product_id, $item_id, $sku) != false) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_stock_reserve` SET `reserve` = '" . (int)$reserve . "' WHERE `product_id` = '" . (int)$product_id . "' AND `variant_id` = '" . $this->db->escape($sku) . "' AND `item_id` = '" . $this->db->escape($item_id) . "' LIMIT 1");
+ } else {
+ if ($variant == 0) {
+ $this->log('updateReserve() - not a variant');
+ $this->addReserve(array('product_id' => $product_id, 'qty' => array(0 => $reserve)), $item_id, 0);
+ } else {
+ $this->log('updateReserve() - variant');
+ $this->addReserve(array('product_id' => $product_id, 'opt' => array(array('sku' => $sku, 'qty' => $reserve))), $item_id, 1);
+ }
+ }
+ }
+ }
+
+ public function deleteReserve($product_id, $item_id, $sku = '') {
+ $this->log('deleteReserve()');
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "ebay_stock_reserve` WHERE `product_id` = '" . (int)$product_id . "' AND `variant_id` = '" . $this->db->escape($sku) . "' AND `item_id` = '" . $this->db->escape($item_id) . "' LIMIT 1");
+ }
+
+ public function getCarriers() {
+ $qry = $this->db->query("SELECT * FROM " . DB_PREFIX . "ebay_shipping");
+
+ $couriers = array();
+ foreach ($qry->rows as $row) {
+ $couriers[] = $row;
+ }
+
+ return $couriers;
+ }
+
+ public function getOrder($order_id) {
+ if ($this->openbay->testDbTable(DB_PREFIX . "ebay_order") == true) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ return $qry->row;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public function getOrderBySmpId($smp_id) {
+ if ($this->openbay->testDbTable(DB_PREFIX . "ebay_order") == true) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_order` WHERE `smp_id` = '" . (int)$smp_id . "' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ return $qry->row;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public function updateCategories() {
+ $cat_array = $this->call('setup/getEbayCategories/', array(), array(), 'json', true);
+
+ if ($this->lasterror != true) {
+ $this->db->query("TRUNCATE TABLE `" . DB_PREFIX . "ebay_category`");
+
+ if (!empty($cat_array)) {
+ foreach ($cat_array as $cat) {
+ if ($cat['BestOfferEnabled'] == true) {
+ $cat['BestOfferEnabled'] = 1;
+ } else {
+ $cat['BestOfferEnabled'] = 0;
+ }
+
+ if ($cat['AutoPayEnabled'] == true) {
+ $cat['AutoPayEnabled'] = 1;
+ } else {
+ $cat['AutoPayEnabled'] = 0;
+ }
+
+ $this->db->query("
+ INSERT INTO `" . DB_PREFIX . "ebay_category` SET
+ `CategoryID` = '" . (int)$cat['CategoryID'] . "',
+ `CategoryParentID` = '" . (int)$cat['CategoryParentID'] . "',
+ `CategoryLevel` = '" . (int)$cat['CategoryLevel'] . "',
+ `BestOfferEnabled` = '" . (int)$cat['BestOfferEnabled'] . "',
+ `AutoPayEnabled` = '" . (int)$cat['AutoPayEnabled'] . "',
+ `CategoryName` = '" . $this->db->escape((string)$cat['CategoryName']) . "'
+ ");
+ }
+ }
+ }
+
+ return array('msg' => $this->lastmsg, 'error' => $this->lasterror);
+ }
+
+ public function updateSettings() {
+ $response = $this->call('setup/getEbayDetails/', array(), array(), 'json', true);
+
+ $this->log('Getting eBay settings / sync');
+
+ if ($this->lasterror === false) {
+ if (isset($response['listing_restrictions'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'listing_restrictions' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . $this->db->escape(serialize($response['listing_restrictions'])) . "', `last_updated` = now() WHERE `key` = 'listing_restrictions' LIMIT 1");
+ $this->log('Updated listing_restrictions into ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'listing_restrictions', `data` = '" . $this->db->escape(serialize($response['listing_restrictions'])) . "', `last_updated` = now()");
+ $this->log('Inserted listing_restrictions into ebay_setting_option table');
+ }
+ } else {
+ $this->log('listing_restrictions data not set!');
+ }
+
+ if (isset($response['product_details'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'product_details' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . $this->db->escape(serialize($response['product_details'])) . "', `last_updated` = now() WHERE `key` = 'product_details' LIMIT 1");
+ $this->log('Updated product_details into ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'product_details', `data` = '" . $this->db->escape(serialize($response['product_details'])) . "', `last_updated` = now()");
+ $this->log('Inserted product_details into ebay_setting_option table');
+ }
+ } else {
+ $this->log('Non identifier text not set!');
+ }
+
+ if (isset($response['urls']['ViewItemURL'])) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "setting` WHERE `key` = 'ebay_itm_link' LIMIT 1");
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "setting` SET `value` = '" . $this->db->escape((string)$response['urls']['ViewItemURL']) . "', `key` = 'ebay_itm_link', `code` = 'openbay'");
+
+ $this->log('Updated eBay item link');
+ } else {
+ $this->log('Item link URL not set!');
+ }
+
+ //ebay payment methods
+ if (isset($response['payment_options'])) {
+ $this->db->query("TRUNCATE TABLE `" . DB_PREFIX . "ebay_payment_method`");
+ $this->log('Emptied ebay_payment_method table');
+
+ foreach ($response['payment_options'] as $child) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_payment_method` SET `ebay_name` = '" . $this->db->escape((string)$child['PaymentOption']) . "', `local_name` = '" . $this->db->escape((string)$child['Description']) . "'");
+ }
+
+ $this->log('Populated ebay_payment_method table');
+ } else {
+ $this->log('No payment options set!');
+ }
+
+ //ebay shipping
+ if (isset($response['shipping_service'])) {
+ $this->db->query("TRUNCATE TABLE `" . DB_PREFIX . "ebay_shipping`");
+ $this->log('Emptied ebay_shipping table');
+ foreach ($response['shipping_service'] as $service) {
+ if (!empty($service['InternationalService']) && $service['InternationalService'] == 'true') {
+ $service['InternationalService'] = 1;
+ } else {
+ $service['InternationalService'] = 0;
+ }
+
+ if (!empty($service['ValidForSellingFlow'])) {
+ $service['ValidForSellingFlow'] = 1;
+ } else {
+ $service['ValidForSellingFlow'] = 0;
+ }
+
+ if (!empty($service['ShippingTimeMin'])) {
+ $min = (int)$service['ShippingTimeMin'];
+ } else {
+ $min = 1;
+ }
+ if (!empty($service['ShippingTimeMax'])) {
+ $max = (int)$service['ShippingTimeMax'];
+ } else {
+ $max = 21;
+ }
+
+ $this->db->query("
+ INSERT INTO `" . DB_PREFIX . "ebay_shipping` SET
+ `description` = '" . $this->db->escape((string)$service['Description']) . "',
+ `InternationalService` = '" . (int)$service['InternationalService'] . "',
+ `ShippingService` = '" . $this->db->escape((string)$service['ShippingService']) . "' ,
+ `ShippingServiceID` = '" . (int)$service['ShippingServiceID'] . "',
+ `ServiceType` = '" . $this->db->escape(strtolower(implode(',', $service['ServiceType']))) . "' ,
+ `ValidForSellingFlow` = '" . (int)$service['ValidForSellingFlow'] . "',
+ `ShippingCategory` = '" . $this->db->escape((string)$service['ShippingCategory']) . "' ,
+ `ShippingTimeMin` = '" . (int)$min . "',
+ `ShippingTimeMax` = '" . (int)$max . "'
+ ");
+ }
+ $this->log('Populated ebay_shipping table');
+ } else {
+ $this->log('No shiopping details set!');
+ }
+
+ //shipping locations
+ if (isset($response['shipping_location'])) {
+ $this->db->query("TRUNCATE TABLE `" . DB_PREFIX . "ebay_shipping_location`");
+ $this->log('Emptied ebay_shipping_location table');
+ foreach ($response['shipping_location'] as $service) {
+ $this->db->query("
+ INSERT INTO `" . DB_PREFIX . "ebay_shipping_location`
+ SET
+ `description` = '" . $this->db->escape((string)$service['Description']) . "',
+ `detail_version` = '" . $this->db->escape($service['DetailVersion']) . "',
+ `shipping_location` = '" . $this->db->escape((string)$service['ShippingLocation']) . "' ,
+ `update_time` = '" . (int)$service['UpdateTime'] . "'
+ ");
+ }
+ $this->log('Populated ebay_shipping_location table');
+ } else {
+ $this->log('No shipping locations set!');
+ }
+
+ //shipping locations exclude
+ if (isset($response['exclude_shipping_location'])) {
+ $this->db->query("TRUNCATE TABLE `" . DB_PREFIX . "ebay_shipping_location_exclude`");
+ $this->log('Emptied ebay_shipping_location_exclude table');
+ foreach ($response['exclude_shipping_location'] as $service) {
+ $this->db->query("
+ INSERT INTO `" . DB_PREFIX . "ebay_shipping_location_exclude`
+ SET
+ `description` = '" . $this->db->escape((string)$service['Description']) . "',
+ `location` = '" . $this->db->escape((string)$service['Location']) . "',
+ `region` = '" . $this->db->escape((string)$service['Region']) . "'
+ ");
+ }
+ $this->log('Populated exclude_shipping_location table');
+ } else {
+ $this->log('No shipping exclude locations set!');
+ }
+
+ //max dispatch times
+ if (isset($response['dispatch_time_max'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'dispatch_time_max' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . $this->db->escape(serialize($response['dispatch_time_max'])) . "', `last_updated` = now() WHERE `key` = 'dispatch_time_max' LIMIT 1");
+ $this->log('Updated dispatch_time_max into ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'dispatch_time_max', `data` = '" . $this->db->escape(serialize($response['dispatch_time_max'])) . "', `last_updated` = now()");
+ $this->log('Inserted dispatch_time_max into ebay_setting_option table');
+ }
+ } else {
+ $this->log('No dispatch_time_max set!');
+ }
+
+ //countries
+ if (isset($response['countries'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'countries' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . $this->db->escape(serialize($response['countries'])) . "', `last_updated` = now() WHERE `key` = 'countries' LIMIT 1");
+ $this->log('Updated countries into ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'countries', `data` = '" . $this->db->escape(serialize($response['countries'])) . "', `last_updated` = now()");
+ $this->log('Inserted countries into ebay_setting_option table');
+ }
+ } else {
+ $this->log('No countries set!');
+ }
+
+ //returns
+ if (isset($response['returns'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'returns' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . $this->db->escape(serialize($response['returns'])) . "', `last_updated` = now() WHERE `key` = 'returns' LIMIT 1");
+ $this->log('Updated returns info in to ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'returns', `data` = '" . $this->db->escape(serialize($response['returns'])) . "', `last_updated` = now()");
+ $this->log('Inserted returns info in to ebay_setting_option table');
+ }
+ } else {
+ $this->log('No returns set!');
+ }
+
+ //package sizes
+ if (isset($response['package_type'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'package_type' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . $this->db->escape(serialize($response['package_type'])) . "', `last_updated` = now() WHERE `key` = 'package_type' LIMIT 1");
+ $this->log('Updated package_type info in to ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'package_type', `data` = '" . $this->db->escape(serialize($response['package_type'])) . "', `last_updated` = now()");
+ $this->log('Inserted package_type info in to ebay_setting_option table');
+ }
+ } else {
+ $this->log('No package_type set!');
+ }
+
+ //vat enabled
+ if (isset($response['vat_enabled'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'vat_enabled' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . (int)$response['package_type'] . "', `last_updated` = now() WHERE `key` = 'vat_enabled' LIMIT 1");
+ $this->log('Updated vat_enabled in to ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'vat_enabled', `data` = '" . (int)$response['package_type'] . "', `last_updated` = now()");
+ $this->log('Inserted vat_enabled info in to ebay_setting_option table');
+ }
+ } else {
+ $this->log('No vat_enabled set!');
+ }
+
+ //shipping types
+ if (isset($response['shipping_types'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'shipping_types' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . $this->db->escape(serialize($response['shipping_types'])) . "', `last_updated` = now() WHERE `key` = 'shipping_types' LIMIT 1");
+ $this->log('Updated shipping_types info in to ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'shipping_types', `data` = '" . $this->db->escape(serialize($response['shipping_types'])) . "', `last_updated` = now()");
+ $this->log('Inserted shipping_types info in to ebay_setting_option table');
+ }
+ } else {
+ $this->log('No shipping_types set!');
+ }
+
+ //measurement types
+ if (isset($response['measurement_types'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'measurement_types' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . $this->db->escape(serialize($response['measurement_types'])) . "', `last_updated` = now() WHERE `key` = 'measurement_types' LIMIT 1");
+ $this->log('Updated measurement_types info in to ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'measurement_types', `data` = '" . $this->db->escape(serialize($response['measurement_types'])) . "', `last_updated` = now()");
+ $this->log('Inserted measurement_types info in to ebay_setting_option table');
+ }
+ } else {
+ $this->log('No measurement_types set!');
+ }
+
+ // Product details
+ if (isset($response['product_details'])) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_setting_option` WHERE `key` = 'product_details' LIMIT 1");
+
+ if ($qry->num_rows > 0) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "ebay_setting_option` SET `data` = '" . $this->db->escape(serialize($response['product_details'])) . "', `last_updated` = now() WHERE `key` = 'product_details' LIMIT 1");
+ $this->log('Updated product_details info in to ebay_setting_option table');
+ } else {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_setting_option` SET `key` = 'product_details', `data` = '" . $this->db->escape(serialize($response['product_details'])) . "', `last_updated` = now()");
+ $this->log('Inserted product_details info in to ebay_setting_option table');
+ }
+ } else {
+ $this->log('No product_details set!');
+ }
+ }
+
+ return array('msg' => $this->lastmsg, 'error' => $this->lasterror);
+ }
+
+ public function updateStore() {
+ $store = $this->call('setup/getSellerStore/', array(), array(), 'json', true);
+
+ if ($this->lasterror != true) {
+ if ($store['store'] == true) {
+ $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "ebay_store_category`;");
+ $this->db->query("
+ CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "ebay_store_category` (
+ `ebay_store_category_id` int(11) NOT NULL AUTO_INCREMENT,
+ `parent_id` int(11) NOT NULL,
+ `CategoryID` char(100) NOT NULL,
+ `CategoryName` char(100) NOT NULL,
+ PRIMARY KEY (`ebay_store_category_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;");
+
+ if (!empty($store['settings']['categories'])) {
+ foreach ($store['settings']['categories'] as $cat1) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_store_category` SET `CategoryID` = '" . $this->db->escape($cat1['id']) . "', `CategoryName` = '" . $this->db->escape($cat1['name']) . "'");
+ $id1 = $this->db->getLastId();
+
+ if (!empty($cat1['children'])) {
+ foreach ($cat1['children'] as $cat2) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_store_category` SET `CategoryID` = '" . $this->db->escape($cat2['id']) . "', `CategoryName` = '" . $this->db->escape($cat2['name']) . "', `parent_id` = '" . $this->db->escape($id1) . "'");
+ $id2 = $this->db->getLastId();
+
+ if (!empty($cat2['children'])) {
+ foreach ($cat2['children'] as $cat3) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_store_category` SET `CategoryID` = '" . $this->db->escape($cat3['id']) . "', `CategoryName` = '" . $this->db->escape($cat3['name']) . "', `parent_id` = '" . $this->db->escape($id2) . "'");
+ $id3 = $this->db->getLastId();
+
+ if (!empty($cat3['children'])) {
+ foreach ($cat3['children'] as $cat4) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "ebay_store_category` SET `CategoryID` = '" . $this->db->escape($cat4['id']) . "', `CategoryName` = '" . $this->db->escape($cat4['name']) . "', `parent_id` = '" . $this->db->escape($id3) . "'");
+ $id4 = $this->db->getLastId();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return array('msg' => $this->lastmsg, 'error' => $this->lasterror);
+ }
+
+ public function editSetting($group, $data, $store_id = 0) {
+ $this->db->query("DELETE FROM " . DB_PREFIX . "setting WHERE store_id = '" . (int)$store_id . "' AND `code` = '" . $this->db->escape($group) . "'");
+
+ foreach ($data as $key => $value) {
+ if (!is_array($value)) {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "setting SET store_id = '" . (int)$store_id . "', `code` = '" . $this->db->escape($group) . "', `key` = '" . $this->db->escape($key) . "', `value` = '" . $this->db->escape($value) . "'");
+ } else {
+ $this->db->query("INSERT INTO " . DB_PREFIX . "setting SET store_id = '" . (int)$store_id . "', `code` = '" . $this->db->escape($group) . "', `key` = '" . $this->db->escape($key) . "', `value` = '" . $this->db->escape(serialize($value)) . "', serialized = '1'");
+ }
+ }
+ }
+
+ public function getShippingServiceInfo($service_code) {
+ $qry = $this->db->query("SELECT * FROM `" . DB_PREFIX . "ebay_shipping` WHERE `ShippingService` = '" . $this->db->escape($service_code) . "' LIMIT 1");
+
+ if ($qry->num_rows) {
+ return $qry->row;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/public/system/library/openbay/etsy.php b/public/system/library/openbay/etsy.php
new file mode 100644
index 0000000..bf18120
--- /dev/null
+++ b/public/system/library/openbay/etsy.php
@@ -0,0 +1,459 @@
+<?php
+namespace openbay;
+
+final class Etsy {
+ private $token;
+ private $encryption_key;
+ private $encryption_iv;
+ private $url = 'https://api.openbaypro.io/';
+ private $registry;
+ private $logger;
+ private $max_log_size = 50; //max log size in Mb
+
+ public function __construct($registry) {
+ $this->registry = $registry;
+ $this->token = $this->config->get('etsy_token');
+ $this->logging = $this->config->get('etsy_logging');
+
+ if ($this->logging == 1) {
+ $this->setLogger();
+ }
+
+ $this->setEncryptionKey($this->config->get('etsy_encryption_key'));
+ $this->setEncryptionIv($this->config->get('etsy_encryption_iv'));
+ }
+
+ public function __get($name) {
+ return $this->registry->get($name);
+ }
+
+ public function getEncryptionKey() {
+ return $this->encryption_key;
+ }
+
+ public function setEncryptionKey($key) {
+ $this->encryption_key = $key;
+ }
+
+ public function getEncryptionIv() {
+ return $this->encryption_iv;
+ }
+
+ public function setEncryptionIv($encryption_iv) {
+ $this->encryption_iv = $encryption_iv;
+ }
+
+ public function resetConfig($token, $encryption_key) {
+ $this->token = $token;
+ $this->setEncryptionKey($encryption_key);
+ }
+
+ public function call($uri, $method, $data = array()) {
+ if($this->config->get('etsy_status') == 1) {
+ $headers = array ();
+ $headers[] = 'X-Auth-Token: ' . $this->token;
+ $headers[] = 'X-Endpoint-Version: 2';
+ $headers[] = 'Content-Type: application/json';
+ //$headers[] = 'Content-Length: '.strlen(json_encode($data));
+
+ $defaults = array(
+ CURLOPT_HEADER => 0,
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_URL => $this->url . $uri,
+ CURLOPT_USERAGENT => "OpenBay Pro for Etsy/OpenCart",
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 180,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ //CURLOPT_VERBOSE => true,
+ //CURLOPT_STDERR => fopen(DIR_LOGS . 'curl_verbose.log', "w+")
+ );
+
+ if ($method == 'POST') {
+ $defaults[CURLOPT_POST] = 1;
+ $defaults[CURLOPT_POSTFIELDS] = json_encode($data);
+ }
+
+ $curl = curl_init();
+ curl_setopt_array($curl, $defaults);
+
+ $response = array();
+
+ if (! $result = curl_exec($curl)) {
+ $this->log('call() - Curl Failed ' . curl_error($curl) . ' ' . curl_errno($curl));
+
+ return false;
+ } else {
+ $this->log('call() - Result of : "' . print_r($result, true) . '"');
+
+ $encoding = mb_detect_encoding($result);
+
+ if($encoding == 'UTF-8') {
+ $result = preg_replace('/[^(\x20-\x7F)]*/', '', $result);
+ }
+
+ $result = json_decode($result, 1);
+
+ $response['header_code'] = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+
+ if(!empty($result)) {
+ $response['data'] = $result;
+ } else {
+ $response['data'] = '';
+ }
+ }
+
+ curl_close($curl);
+
+ return $response;
+ } else {
+ $this->log('call() - OpenBay Pro / Etsy not active');
+
+ return false;
+ }
+ }
+
+ private function setLogger() {
+ if (file_exists(DIR_LOGS . 'etsylog.log')) {
+ if (filesize(DIR_LOGS . 'etsylog.log') > ($this->max_log_size * 1000000)) {
+ rename(DIR_LOGS . 'etsylog.log', DIR_LOGS . '_etsylog_' . date('Y-m-d_H-i-s') . '.log');
+ }
+ }
+
+ $this->logger = new \Log('etsylog.log');
+ }
+
+ public function log($data, $write = true) {
+ if ($this->logging == 1) {
+ if (function_exists('getmypid')) {
+ $process_id = getmypid();
+ $data = $process_id . ' - ' . print_r($data, true);
+ }
+
+ $this->logger->write($data);
+ }
+ }
+
+ public function getServer() {
+ return $this->url;
+ }
+
+ public function settingsUpdate() {
+ $this->log("settingsUpdate() - start");
+
+ $response = $this->call('v1/etsy/data/type/getSetup/', 'GET');
+
+ if (isset($response['data']) && is_array($response['data'])) {
+ foreach ($response['data'] as $key => $options) {
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "etsy_setting_option` WHERE `key` = '" . $this->db->escape($key) . "' LIMIT 1");
+
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "etsy_setting_option` SET `data` = '" . $this->db->escape(json_encode($options)) . "', `key` = '" . $this->db->escape($key) . "', `last_updated` = now()");
+
+ $this->log("settingsUpdate() - updated option: " . $key);
+ }
+
+ $this->log("settingsUpdate() - complete");
+ } else {
+ $this->log("settingsUpdate() - failed - no data response");
+ }
+ }
+
+ public function getSetting($key) {
+ $this->log("getSetting() - " . $key);
+
+ $qry = $this->db->query("SELECT `data` FROM `" . DB_PREFIX . "etsy_setting_option` WHERE `key` = '" . $this->db->escape($key) . "' LIMIT 1");
+
+ if($qry->num_rows > 0) {
+ $this->log("getSetting() - Found setting");
+
+ return json_decode($qry->row['data']);
+ } else {
+ return false;
+ }
+ }
+
+ public function getLinks($product_id, $status = 0, $limit = null) {
+ $this->log("getLinks() - Product_id: " . $product_id . " status: " . $status . " limit:" . $limit);
+
+ if ($limit != null) {
+ $sql_limit = ' LIMIT 1';
+ } else {
+ $sql_limit = '';
+ }
+
+ $qry = $this->db->query("SELECT `el`.*, `p`.`quantity` FROM `" . DB_PREFIX . "etsy_listing` `el` LEFT JOIN `" . DB_PREFIX . "product` `p` ON `el`.`product_id` = `p`.`product_id` WHERE `el`.`product_id` = '" . (int)$product_id . "' AND `el`.`status` = '" . (int)$status . "' ORDER BY `el`.`created` DESC" . $sql_limit);
+
+ if ($qry->num_rows) {
+ $this->log("getLinks() - " . $qry->num_rows . " found");
+
+ $links = array();
+
+ foreach ($qry->rows as $row) {
+ $links[] = $row;
+ }
+
+ return $links;
+ } else {
+ $this->log("getLinks() - no links found");
+
+ return false;
+ }
+ }
+
+ public function getLinkedProduct($etsy_item_id) {
+ $this->log("getLinkedProduct() - etsy_item_id: " . $etsy_item_id);
+
+ $qry = $this->db->query("SELECT `p`.`quantity`, `p`.`product_id`, `p`.`model`, `el`.`etsy_listing_id`, `el`.`status` AS `link_status` FROM `" . DB_PREFIX . "etsy_listing` `el` LEFT JOIN `" . DB_PREFIX . "product` `p` ON `p`.`product_id` = `el`.`product_id` WHERE `el`.`etsy_item_id` = '" . (int)$etsy_item_id . "' AND `el`.`status` = 1");
+
+ if($qry->num_rows) {
+ $this->log("getLinkedProduct() - " . $qry->num_rows . " found");
+
+ return $qry->row;
+ } else {
+ $this->log("getLinkedProduct() - no link found");
+
+ return false;
+ }
+ }
+
+ public function updateListingStock($etsy_item_id, $new_stock, $status) {
+ $this->log("updateListingStock() - ItemID: " . $etsy_item_id . ", new stock: " . $new_stock . ", status: " . $status);
+
+ if ($new_stock > 0) {
+ $this->log("updateListingStock() - stock > 0 - update stock");
+
+ if ($status == 'edit') {
+ $status = 'inactive';
+ }
+
+ $response = $this->call('v1/etsy/product/listing/' . (int)$etsy_item_id . '/updateStock/', 'POST', array('quantity' => $new_stock, 'state' => $status));
+
+ if (isset($response['data']['error'])) {
+ return $response;
+ } else {
+ return true;
+ }
+ } else {
+ $this->log("updateListingStock() - stock > 0 - set to inactive");
+
+ $this->deleteLink(null, $etsy_item_id);
+
+ $response = $this->call('v1/etsy/product/listing/' . (int)$etsy_item_id . '/inactive/', 'POST');
+
+ if (isset($response['data']['error'])) {
+ $this->log("updateListingStock() - Error: " . json_encode($response));
+
+ return $response;
+ } else {
+ $this->log("updateListingStock() - Item ended OK");
+
+ return true;
+ }
+ }
+ }
+
+ public function deleteProduct($product_id) {
+ $this->log("deleteProduct() - Product ID: " . $product_id);
+
+ $this->db->query("DELETE FROM `" . DB_PREFIX . "etsy_listing` WHERE `product_id` = '" . (int)$product_id . "'");
+ }
+
+ public function deleteLink($etsy_listing_id = null, $etsy_item_id = null) {
+ $this->log("deleteLink() - Listing ID: " . $etsy_listing_id . ", item ID" . $etsy_item_id);
+
+ if ($etsy_listing_id != null) {
+ $this->log("deleteLink() - Listing ID is not null");
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "etsy_listing` SET `status` = 0 WHERE `etsy_listing_id` = '" . (int)$etsy_listing_id . "' LIMIT 1");
+ } elseif ($etsy_item_id != null) {
+ $this->log("deleteLink() - Item ID is not null");
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "etsy_listing` SET `status` = 0 WHERE `etsy_item_id` = '" . (int)$etsy_item_id . "' LIMIT 1");
+ }
+ }
+
+ public function productUpdateListen($product_id, $data = array()) {
+ $this->log("productUpdateListen() - " . $product_id . ", Data: " . json_encode($data));
+
+ $links = $this->getLinks($product_id, 1);
+
+ if (!empty($links)) {
+ foreach ($links as $link) {
+ $this->log("productUpdateListen() - Item ID: " . $link['etsy_item_id']);
+
+ $etsy_listing = $this->getEtsyItem($link['etsy_item_id']);
+
+ if ($etsy_listing != false && isset($etsy_listing['state']) && ($etsy_listing['state'] == 'active' || $etsy_listing['state'] == 'private' || $etsy_listing['state'] == 'draft' || $etsy_listing['state'] == 'edit')) {
+ $this->log("productUpdateListen() - Listing state seems valid");
+
+ if ($etsy_listing['quantity'] != $link['quantity']) {
+ $this->log("productUpdateListen() - Stock is different, do update");
+
+ $this->updateListingStock($link['etsy_item_id'], $link['quantity'], $etsy_listing['state']);
+ } else {
+ $this->log("productUpdateListen() - Stock is the same: " . $etsy_listing['quantity'] . " " . $link['quantity']);
+ }
+ } else {
+ $this->log("productUpdateListen() - Listing state seems invalid");
+ $this->log("productUpdateListen() - " . json_encode($etsy_listing));
+
+ $this->deleteLink($link['etsy_listing_id']);
+ }
+ }
+ } else {
+ $this->log("productUpdateListen() - No links");
+ }
+ }
+
+ public function orderFind($order_id = null, $receipt_id = null) {
+ $this->log("orderFind() - OrderID: " . $order_id . ", Receipt ID: " . $receipt_id);
+
+ if ($order_id != null) {
+ $this->log("orderFind() - Order ID is not null");
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "etsy_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if($query->num_rows > 0) {
+ $this->log('orderFind() - Found');
+ return $query->row;
+ } else {
+ $this->log('orderFind() - Not found');
+ return false;
+ }
+ } elseif ($receipt_id != null) {
+ $this->log("orderFind() - Receipt ID is not null");
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "etsy_order` WHERE `receipt_id` = '" . (int)$receipt_id . "' LIMIT 1");
+
+ if($query->num_rows > 0) {
+ $this->log('orderFind() - Found');
+ return $query->row;
+ } else {
+ $this->log('orderFind() - Not found');
+ return false;
+ }
+ }
+ }
+
+ public function orderDelete($order_id) {
+ $this->log("orderDelete() - ID: " . $order_id);
+
+ if(!$this->orderFind($order_id)) {
+ $query = $this->db->query("SELECT `p`.`product_id` FROM `" . DB_PREFIX . "order_product` `op` LEFT JOIN `" . DB_PREFIX . "product` `p` ON `op`.`product_id` = `p`.`product_id` WHERE `op`.`order_id` = '" . (int)$order_id . "'");
+
+ if($query->num_rows > 0) {
+ $this->log("orderDelete() - " . $query->num_rows . " products");
+
+ foreach ($query->rows as $product) {
+ $this->log("orderDelete() - Processing ID: " . $product['product_id']);
+
+ $this->productUpdateListen((int)$product['product_id']);
+ }
+ } else {
+ $this->log("orderDelete() - No products in order");
+ }
+ } else {
+ $this->log("orderDelete() - Not an Etsy order");
+ }
+ }
+
+ public function orderUpdatePaid($receipt_id, $status) {
+ $this->log("orderUpdatePaid() - Receipt ID: " . $receipt_id . ", Status: " . $status);
+
+ $response = $this->openbay->etsy->call('v1/etsy/order/update/payment/', 'POST', array('receipt_id' => $receipt_id, 'status' => $status));
+
+ if (isset($response['data']['error'])) {
+ $this->log("orderUpdatePaid() - Error: " . json_encode($response));
+
+ return $response;
+ } else {
+ $this->log("orderUpdatePaid() - OK");
+
+ return true;
+ }
+ }
+
+ public function orderUpdateShipped($receipt_id, $status) {
+ $this->log("orderUpdateShipped() - Receipt ID: " . $receipt_id . ", Status: " . $status);
+
+ $response = $this->openbay->etsy->call('v1/etsy/order/update/shipping/', 'POST', array('receipt_id' => $receipt_id, 'status' => $status));
+
+ if (isset($response['data']['error'])) {
+ $this->log("orderUpdateShipped() - Error: " . json_encode($response));
+
+ return $response;
+ } else {
+ $this->log("orderUpdateShipped() - OK");
+
+ return true;
+ }
+ }
+
+ public function putStockUpdateBulk($product_id_array, $end_inactive) {
+ $this->log("putStockUpdateBulk() - ok");
+ $this->log("putStockUpdateBulk() - Item count: " . count($product_id_array));
+
+ foreach($product_id_array as $product_id) {
+ $this->log("putStockUpdateBulk() - Product ID: " . $product_id);
+
+ $links = $this->getLinks($product_id, 1);
+
+ if (!empty($links)) {
+ $this->log("putStockUpdateBulk() - Links found: " . count($links));
+
+ foreach ($links as $link) {
+ $etsy_listing = $this->getEtsyItem($link['etsy_item_id']);
+
+ if ($etsy_listing != false && isset($etsy_listing['state']) && ($etsy_listing['state'] == 'active' || $etsy_listing['state'] == 'private' || $etsy_listing['state'] == 'draft' || $etsy_listing['state'] == 'edit')) {
+ $this->log("putStockUpdateBulk() - Listing state seems valid");
+
+ if ($etsy_listing['quantity'] != $link['quantity']) {
+ $this->log("putStockUpdateBulk() - Stock is different, do update");
+
+ $this->updateListingStock($link['etsy_item_id'], $link['quantity'], $etsy_listing['state']);
+ } else {
+ $this->log("putStockUpdateBulk() - Stock is the same: " . $etsy_listing['quantity'] . " " . $link['quantity']);
+ }
+ } else {
+ $this->log("putStockUpdateBulk() - Listing state seems invalid");
+ $this->log("putStockUpdateBulk() - " . json_encode($etsy_listing));
+
+ $this->deleteLink($link['etsy_listing_id']);
+ }
+ }
+ } else {
+ $this->log("putStockUpdateBulk() - No link found");
+ }
+ }
+ }
+
+ public function getEtsyItem($listing_id) {
+ $this->log("getEtsyItem(): " . $listing_id);
+
+ $response = $this->openbay->etsy->call('v1/etsy/product/listing/' . $listing_id . '/', 'GET');
+
+ if (isset($response['data']['error'])) {
+ $this->log("getEtsyItem() error: ". $response['data']['error']);
+
+ return $response;
+ } else {
+ $this->log("getEtsyItem() - OK : " . json_encode($response));
+
+ return $response['data']['results'][0];
+ }
+ }
+
+ public function validate() {
+ if ($this->config->get('etsy_token') && $this->config->get('etsy_encryption_key') && $this->config->get('etsy_encryption_iv')) {
+ $this->log("Etsy details valid");
+
+ return true;
+ } else {
+ $this->log("Etsy details are not valid");
+
+ return false;
+ }
+ }
+}
diff --git a/public/system/library/openbay/fba.php b/public/system/library/openbay/fba.php
new file mode 100644
index 0000000..aded084
--- /dev/null
+++ b/public/system/library/openbay/fba.php
@@ -0,0 +1,305 @@
+<?php
+namespace openbay;
+
+final class fba {
+ private $api_key;
+ private $api_account_id;
+ private $encryption_key;
+ private $encryption_iv;
+ private $url = 'https://api.openbaypro.io/';
+ private $registry;
+
+ private $logging = 1;
+ private $logging_verbose = 1;
+ private $max_log_size = 50;
+
+ /**
+ * Status IDs =
+ * 0 = new
+ * 1 = error
+ * 2 = held
+ * 3 = shipped
+ * 4 = cancelled
+ */
+
+ /**
+ * Type IDs =
+ * 0 = new
+ * 1 = shipping
+ * 2 = cancel
+ */
+
+ public function __construct($registry) {
+ $this->registry = $registry;
+
+ $this->api_key = $this->config->get('openbay_fba_api_key');
+ $this->api_account_id = $this->config->get('openbay_fba_api_account_id');
+ $this->logging = $this->config->get('openbay_fba_debug_log');
+
+ $this->setEncryptionKey($this->config->get('openbay_fba_encryption_key'));
+ $this->setEncryptionIv($this->config->get('openbay_fba_encryption_iv'));
+
+ if ($this->logging == 1) {
+ $this->setLogger();
+ }
+ }
+
+ public function __get($name) {
+ return $this->registry->get($name);
+ }
+
+ public function getEncryptionKey() {
+ return $this->encryption_key;
+ }
+
+ public function setEncryptionKey($key) {
+ $this->encryption_key = $key;
+ }
+
+ public function getEncryptionIv() {
+ return $this->encryption_iv;
+ }
+
+ public function setEncryptionIv($encryption_iv) {
+ $this->encryption_iv = $encryption_iv;
+ }
+
+ public function setApiKey($api_key) {
+ $this->api_key = $api_key;
+ }
+
+ public function setAccountId($api_account_id) {
+ $this->api_account_id = $api_account_id;
+ }
+
+ public function call($uri, $data = array(), $request_type = 'GET') {
+ $this->log("Request: " . $request_type . " : " . $this->url . $uri);
+
+ $headers = array();
+ $headers[] = 'X-Auth-Token: ' . $this->api_key;
+ $headers[] = 'X-Account-ID: ' . $this->api_account_id;
+ $headers[] = 'X-Endpoint-Version: 2';
+ $headers[] = 'Content-Type: application/json';
+
+ $defaults = array(
+ CURLOPT_HEADER => 0,
+ CURLOPT_HTTPHEADER => $headers,
+ CURLOPT_URL => $this->url . $uri,
+ CURLOPT_USERAGENT => "OpenBay Pro for Fulfillment by Amazon/OpenCart",
+ CURLOPT_FRESH_CONNECT => 1,
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_FORBID_REUSE => 1,
+ CURLOPT_TIMEOUT => 30,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_SSL_VERIFYHOST => 0,
+ );
+
+ if ($this->logging_verbose == 1) {
+ $defaults[CURLOPT_VERBOSE] = 1;
+ $defaults[CURLOPT_STDERR] = fopen(DIR_LOGS . 'fba_verbose.log', "a+");
+ }
+
+ if ($request_type == "POST") {
+ $this->log('Request body:');
+ $this->log(print_r($data, true));
+ $defaults[CURLOPT_POST] = json_encode($data);
+ $defaults[CURLOPT_POSTFIELDS] = json_encode($data);
+ } else {
+ $defaults[CURLOPT_CUSTOMREQUEST] = "GET";
+ }
+
+ $curl = curl_init();
+
+ curl_setopt_array($curl, $defaults);
+
+ $result = curl_exec($curl);
+
+ if (!$result) {
+ $this->log('call() - Curl Failed ' . curl_error($curl) . ' ' . curl_errno($curl));
+
+ $response = array('error' => true, 'error_messages' => array(curl_error($curl) . ' ' . curl_errno($curl)), 'body' => null, 'response_http' => 0);
+ } else {
+ $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+
+ $this->log("Response: " . $http_code . " : " . strlen($result) . " bytes");
+
+ $encoding = mb_detect_encoding($result);
+
+ if ($encoding == 'UTF-8') {
+ $result = preg_replace('/[^(\x20-\x7F)]*/', '', $result);
+ }
+
+ $result_parsed = json_decode($result, 1);
+
+ $this->log('Raw json response:');
+ $this->log($result);
+
+ $this->log('Parsed response:');
+ $this->log(print_r($result_parsed, true));
+
+ $response = array(
+ 'error' => false,
+ 'error_messages' => array(),
+ 'body' => (isset($result_parsed['result']) ? $result_parsed['result'] : ''),
+ 'response_http' => $http_code
+ );
+
+ if (isset($result_parsed['errors']) && !empty($result_parsed['errors'])) {
+ $response['error'] = true;
+ $response['error_messages'] = $result_parsed['errors'];
+ }
+ }
+
+ curl_close($curl);
+
+ return $response;
+ }
+
+ public function getServerUrl() {
+ return $this->url;
+ }
+
+ public function validate() {
+ if ($this->config->get('openbay_fba_api_account_id') && $this->config->get('openbay_fba_api_key') && $this->config->get('openbay_fba_encryption_key') && $this->config->get('openbay_fba_encryption_iv')) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private function setLogger() {
+ if(file_exists(DIR_LOGS . 'fulfillment_by_amazon.log')) {
+ if(filesize(DIR_LOGS . 'fulfillment_by_amazon.log') > ($this->max_log_size * 1000000)) {
+ rename(DIR_LOGS . 'fulfillment_by_amazon.log', DIR_LOGS . '_fulfillment_by_amazon_' . date('Y-m-d_H-i-s') . '.log');
+ }
+ }
+
+ $this->logger = new \Log('fulfillment_by_amazon.log');
+ }
+
+ public function log($data) {
+ if ($this->logging == 1) {
+ if (function_exists('getmypid')) {
+ $process_id = getmypid();
+ $data = $process_id . ' - ' . $data;
+ }
+
+ $this->logger->write($data);
+ }
+ }
+
+ public function createFBAOrderID($order_id) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "fba_order` SET `order_id` = '" . (int)$order_id . "', `status` = 0, `created` = now()");
+
+ return $this->db->getLastId();
+ }
+
+ public function updateFBAOrderStatus($order_id, $status_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "fba_order` SET `status` = '" . (int)$status_id . "' WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+ }
+
+ public function updateFBAOrderRef($order_id, $ref) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "fba_order` SET `fba_order_fulfillment_ref` = '" . $this->db->escape($ref) . "' WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+ }
+
+ public function updateFBAOrderFulfillmentID($order_id, $fba_order_fulfillment_id) {
+ $this->db->query("UPDATE `" . DB_PREFIX . "fba_order` SET `fba_order_fulfillment_id` = '" . (int)$fba_order_fulfillment_id . "' WHERE `order_id` = '" . (int)$order_id . "'");
+ }
+
+ public function createFBAFulfillmentID($order_id, $type) {
+ $this->db->query("INSERT INTO `" . DB_PREFIX . "fba_order_fulfillment` SET `created` = now(), `order_id` = '" . (int)$order_id . "', `type` = '" . (int)$type . "'");
+
+ $id = $this->db->getLastId();
+
+ $this->db->query("UPDATE `" . DB_PREFIX . "fba_order` SET `fba_order_fulfillment_id` = '" . (int)$id . "' WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ return $id;
+ }
+
+ public function populateFBAFulfillment($request_body, $response_body, $header_code, $fba_order_fulfillment_id) {
+ $this->db->query("
+ UPDATE `" . DB_PREFIX . "fba_order_fulfillment`
+ SET
+ `request_body` = '" . $this->db->escape($request_body) . "',
+ `response_body` = '" . $this->db->escape($response_body) . "',
+ `response_header_code` = '" . (int)$header_code . "'
+ WHERE
+ `fba_order_fulfillment_id` = '" . (int)$fba_order_fulfillment_id . "'
+ ");
+
+ $insert_id = $this->db->getLastId();
+
+ return $insert_id;
+ }
+
+ public function getFBAOrders($filter) {
+ $sql = "";
+
+ // start date filter
+ if (isset($filter['filter_start'])) {
+ $sql .= " AND `created` >= '".$filter['filter_start']."'";
+ }
+ // end date filter
+ if (isset($filter['filter_end'])) {
+ $sql .= " AND `created` <= '".$filter['filter_end']."'";
+ }
+ // status filter
+ if (isset($filter['filter_status'])) {
+ $sql .= " AND `status` = '".$filter['filter_status']."'";
+ }
+
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "fba_order` WHERE 1 ".$sql." ORDER BY `created` DESC");
+
+ if ($query->num_rows == 0) {
+ return false;
+ } else {
+ return $query->rows;
+ }
+ }
+
+ public function getFBAOrder($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "fba_order` WHERE `order_id` = '" . (int)$order_id . "' LIMIT 1");
+
+ if ($query->num_rows == 0) {
+ return false;
+ } else {
+ $fba_order = $query->row;
+ $fba_order['fulfillments'] = $this->getFBAOrderFulfillments($order_id);
+
+ return $fba_order;
+ }
+ }
+
+ public function getFBAOrderByRef($ref) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "fba_order` WHERE `fba_order_fulfillment_ref` = '" . $this->db->escape($ref) . "' LIMIT 1");
+
+ if ($query->num_rows == 0) {
+ return false;
+ } else {
+ $fba_order = $query->row;
+ $fba_order['fulfillments'] = $fba_order['order_id'];
+
+ return $fba_order;
+ }
+ }
+
+ public function getFBAOrderFulfillments($order_id) {
+ $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "fba_order_fulfillment` WHERE `order_id` = '" . (int)$order_id . "' ORDER BY `created` DESC");
+
+ if ($query->num_rows == 0) {
+ return false;
+ } else {
+ return $query->rows;
+ }
+ }
+
+ public function hasOrderFBAItems($order_id) {
+ $query = $this->db->query("SELECT COUNT(*) AS `total` FROM `" . DB_PREFIX . "order_product` `op` LEFT JOIN `" . DB_PREFIX . "product` `p` ON `op`.`product_id` = `p`.`product_id` WHERE `p`.`location` = 'FBA' AND `op`.`order_id` = '".(int)$order_id."'");
+
+ if ($query->num_rows == 0) {
+ return false;
+ } else {
+ return $query->row['total'];
+ }
+ }
+}