diff --git a/README.md b/README.md
index bf64bb2..db6a944 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
Opecart module
-=============
+==============
Opencart module for interaction with [IntaroCRM](http://www.intarocrm.com) through [REST API](http://docs.intarocrm.ru/rest-api/).
@@ -9,47 +9,6 @@ Module allows:
* Configure relations between dictionaries of IntaroCRM and Opencart (statuses, payments, delivery types and etc)
* Generate [ICML](http://docs.intarocrm.ru/index.php?n=Пользователи.ФорматICML) (IntaroCRM Markup Language) for catalog loading by IntaroCRM
-Installation
--------------
-
-### 1. Manual installation
-
-
-#### Clone module.
-```
-git clone git@github.com:/intarocrm/opencart-module.git
-```
-
-#### Install Rest API Client.
-
-```
-cd opencart-module/system/library/intarocrm
-./composer.phar install
-```
-
-#### Install module
-```
-cp -r opencart-module/* /path/to/opecart/instance
-```
-
-#### Activate via Admin interface.
-
-Go to Modules -> Intstall module.
-
-#### Export
-
-Catalog export script will be here
-```
-/index.php?route=export/intarocrm
-```
-
-#### Exchange setup
-
-Look into example folder
-
-#### TODO
-* Edit order hook
-* Export old customers & orders
-* Generate static xml
-* New customers export
-
+* [Install](doc/Install.md)
+* [Changelog](doc/Changelog.md)
+* [TODO](doc/TODO.md)
diff --git a/admin/controller/module/intarocrm.php b/admin/controller/module/intarocrm.php
index c4b6b8f..2c04773 100644
--- a/admin/controller/module/intarocrm.php
+++ b/admin/controller/module/intarocrm.php
@@ -4,6 +4,7 @@ require_once __DIR__ . '/../../../system/library/intarocrm/vendor/autoload.php';
class ControllerModuleIntarocrm extends Controller {
private $error = array();
+ protected $dd, $eCategories, $eOffers;
public function install() {
$this->load->model('setting/setting');
@@ -204,6 +205,10 @@ class ControllerModuleIntarocrm extends Controller {
$this->load->model('setting/setting');
$this->load->model('setting/store');
$this->load->model('sale/order');
+ $this->load->model('sale/customer');
+
+
+
$settings = $this->model_setting_setting->getSetting('intarocrm');
$settings['domain'] = parse_url(HTTP_SERVER, PHP_URL_HOST);
@@ -211,112 +216,172 @@ class ControllerModuleIntarocrm extends Controller {
include_once __DIR__ . '/../../../system/library/intarocrm/apihelper.php';
$crm = new ApiHelper($settings);
$orders = $crm->orderHistory();
- $forFix = array();
+ $ordersIdsFix = array();
+ $customersIdsFix = array();
+ $subtotalSettings = $this->model_setting_setting->getSetting('sub_total');
+ $totalSettings = $this->model_setting_setting->getSetting('total');
+ $shippingSettings = $this->model_setting_setting->getSetting('shipping');
foreach ($orders as $order)
{
- $data = array();
+ if (!isset($order['deleted']) || !$order['deleted']) {
- $delivery = array_flip($settings['intarocrm_delivery']);
- $payment = array_flip($settings['intarocrm_payment']);
- $status = array_flip($settings['intarocrm_status']);
+ $data = array();
- $ocPayment = $this->getOpercartPaymentTypes();
- $ocDelivery = $this->getOpercartDeliveryMethods();
+ $customer_id = (isset($order['customer']['externalId']))
+ ? $order['customer']['externalId']
+ : ''
+ ;
- $data['store_id'] = ($this->config->get('config_store_id') == null) ? 0 : $this->config->get('config_store_id');
- $data['customer'] = $order['customer']['firstName'];
- $data['customer_id'] = (isset($order['customer']['externalId'])) ? $order['customer']['externalId']: '';
- $data['customer_group_id'] = '1';
- $data['firstname'] = $order['customer']['firstName'];
- $data['lastname'] = (isset($order['customer']['lastName'])) ? $order['customer']['lastName'] : ' ';
- $data['email'] = $order['customer']['email'];
- $data['telephone'] = (isset($order['customer']['phones'][0]['number'])) ? $order['customer']['phones'][0]['number'] : ' ';
- $data['comment'] = $order['customerComment'];
+ if ($customer_id == '') {
+ $cData = array(
+ 'customer_group_id' => '1',
+ 'firstname' => $order['customer']['firstName'],
+ 'lastname' => (isset($order['customer']['lastName'])) ? $order['customer']['lastName'] : ' ',
+ 'email' => $order['customer']['email'],
+ 'telephone' => (isset($order['customer']['phones'][0]['number'])) ? $order['customer']['phones'][0]['number'] : ' ',
+ 'newsletter' => 0,
+ 'password' => 'tmppass',
+ 'status' => 1,
+ 'address' => array(
+ 'firstname' => $order['customer']['firstName'],
+ 'lastname' => (isset($order['customer']['lastName'])) ? $order['customer']['lastName'] : ' ',
+ 'address_1' => $order['customer']['address']['text'],
+ 'city' => $order['customer']['address']['city'],
+ 'postcode' => $order['customer']['address']['index']
+ ),
+ );
- $data['payment_address'] = '0';
- $data['payment_firstname'] = $order['firstName'];
- $data['payment_lastname'] = (isset($order['lastName'])) ? $order['lastName'] : ' ';
- $data['payment_address_1'] = $order['customer']['address']['text'];
- $data['payment_city'] = $order['customer']['address']['city'];
- $data['payment_postcode'] = $order['customer']['address']['index'];
+ $this->model_sale_customer->addCustomer($cData);
- /*
- * TODO: add country & zone id detection
- */
- //$data['payment_country_id'] = '176';
- //$data['payment_zone_id'] = '2778';
- //$data['shipping_country_id'] = '176';
- //$data['shipping_zone_id'] = '2778';
+ if (isset($order['customer']['email']) && $order['customer']['email'] != '') {
+ $tryToFind = $this->model_sale_customer->getCustomerByEmail($order['customer']['email']);
+ $customer_id = $tryToFind['customer_id'];
+ } else {
+ $last = $this->model_sale_customer->getCustomers($data = array('order' => 'DESC', 'limit' => 1));
+ $customer_id = $last[0]['customer_id'];
+ }
- $data['shipping_address'] = '0';
- $data['shipping_firstname'] = $order['customer']['firstName'];
- $data['shipping_lastname'] = (isset($order['customer']['lastName'])) ? $order['customer']['lastName'] : ' ';
- $data['shipping_address_1'] = $order['delivery']['address']['text'];
- $data['shipping_city'] = $order['delivery']['address']['city'];
- $data['shipping_postcode'] = $order['delivery']['address']['index'];
+ $customersIdsFix[] = array('id' => $order['customer']['id'], 'externalId' => (int) $customer_id);
+ }
- $data['shipping'] = $delivery[$order['delivery']['code']];
- $data['shipping_method'] = $ocDelivery[$data['shipping']];
- $data['shipping_code'] = $delivery[$order['delivery']['code']];
- $data['payment'] = $payment[$order['paymentType']];
- $data['payment_method'] = $ocPayment[$data['payment']];
- $data['payment_code'] = $payment[$order['paymentType']];
- $data['order_status_id'] = $status[$order['status']];
-
- $data['order_product'] = array();
+ $delivery = array_flip($settings['intarocrm_delivery']);
+ $payment = array_flip($settings['intarocrm_payment']);
+ $status = array_flip($settings['intarocrm_status']);
- $subtotal = 0;
- $shipping = isset($order['delivery']['cost']) ? $order['delivery']['cost'] : 0;
+ $ocPayment = $this->getOpercartPaymentTypes();
+ $ocDelivery = $this->getOpercartDeliveryMethods();
- foreach($order['items'] as $item) {
- $data['order_product'][] = array(
- 'product_id' => $item['offer']['externalId'],
- 'name' => $item['offer']['name'],
- 'quantity' => $item['quantity'],
- 'price' => $item['initialPrice'],
- 'total' => $item['initialPrice'] * $item['quantity'],
+ $data['store_id'] = ($this->config->get('config_store_id') == null) ? 0 : $this->config->get('config_store_id');
+ $data['customer'] = $order['customer']['firstName'];
+ $data['customer_id'] = $customer_id;
+ $data['firstname'] = $order['customer']['firstName'];
+ $data['lastname'] = (isset($order['customer']['lastName'])) ? $order['customer']['lastName'] : ' ';
+ $data['email'] = $order['customer']['email'];
+ $data['telephone'] = (isset($order['customer']['phones'][0]['number'])) ? $order['customer']['phones'][0]['number'] : ' ';
+ $data['comment'] = $order['customerComment'];
+
+ $data['payment_address'] = '0';
+ $data['payment_firstname'] = $order['firstName'];
+ $data['payment_lastname'] = (isset($order['lastName'])) ? $order['lastName'] : ' ';
+ $data['payment_address_1'] = $order['customer']['address']['text'];
+ $data['payment_city'] = $order['customer']['address']['city'];
+ $data['payment_postcode'] = $order['customer']['address']['index'];
+
+ /*
+ * TODO: add country & zone id detection
+ */
+ //$data['payment_country_id'] = '176';
+ //$data['payment_zone_id'] = '2778';
+ //$data['shipping_country_id'] = '176';
+ //$data['shipping_zone_id'] = '2778';
+
+ $data['shipping_address'] = '0';
+ $data['shipping_firstname'] = $order['customer']['firstName'];
+ $data['shipping_lastname'] = (isset($order['customer']['lastName'])) ? $order['customer']['lastName'] : ' ';
+ $data['shipping_address_1'] = $order['delivery']['address']['text'];
+ $data['shipping_city'] = $order['delivery']['address']['city'];
+ $data['shipping_postcode'] = $order['delivery']['address']['index'];
+
+ $data['shipping'] = $delivery[$order['delivery']['code']];
+ $data['shipping_method'] = $ocDelivery[$data['shipping']];
+ $data['shipping_code'] = $delivery[$order['delivery']['code']];
+ $data['payment'] = $payment[$order['paymentType']];
+ $data['payment_method'] = $ocPayment[$data['payment']];
+ $data['payment_code'] = $payment[$order['paymentType']];
+ $data['order_status_id'] = $status[$order['status']];
+
+ $data['order_product'] = array();
+
+ foreach($order['items'] as $item) {
+ $data['order_product'][] = array(
+ 'product_id' => $item['offer']['externalId'],
+ 'name' => $item['offer']['name'],
+ 'quantity' => $item['quantity'],
+ 'price' => $item['initialPrice'],
+ 'total' => $item['initialPrice'] * $item['quantity'],
+ );
+ }
+
+ $deliveryCost = isset($order['delivery']['cost']) ? $order['delivery']['cost'] : 0;
+
+ $data['order_total'] = array(
+ array(
+ 'order_total_id' => '',
+ 'code' => 'sub_total',
+ 'value' => $order['summ'],
+ 'sort_order' => $subtotalSettings['sub_total_sort_order']
+ ),
+ array(
+ 'order_total_id' => '',
+ 'code' => 'shipping',
+ 'value' => $deliveryCost,
+ 'sort_order' => $shippingSettings['shipping_sort_order']
+ ),
+ array(
+ 'order_total_id' => '',
+ 'code' => 'total',
+ 'value' => isset($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $deliveryCost,
+ 'sort_order' => $totalSettings['total_sort_order']
+ )
);
- $subtotal += $item['initialPrice'] * $item['quantity'];
- }
+ if (isset($order['externalId'])) {
+ /*
+ * opercart developers believe that to remove all
+ * products from the order during the editing is a good idea...
+ *
+ * so we have to get all the goods before orders are breaks
+ *
+ */
+ $items = $crm->getOrderItems($order['externalId']);
+ $data['order_product'] = array();
- $subtotalSettings = $this->model_setting_setting->getSetting('sub_total');
- $totalSettings = $this->model_setting_setting->getSetting('total');
- $shippingSettings = $this->model_setting_setting->getSetting('shipping');
+ foreach($items as $item) {
+ $data['order_product'][] = array(
+ 'product_id' => $item['offer']['externalId'],
+ 'name' => $item['offer']['name'],
+ 'quantity' => $item['quantity'],
+ 'price' => $item['initialPrice'],
+ 'total' => $item['initialPrice'] * $item['quantity'],
+ );
+ }
- $data['order_total'] = array(
- array(
- 'order_total_id' => '',
- 'code' => 'sub_total',
- 'value' => $subtotal,
- 'sort_order' => $subtotalSettings['sub_total_sort_order']
- ),
- array(
- 'order_total_id' => '',
- 'code' => 'shipping',
- 'value' => $shipping,
- 'sort_order' => $shippingSettings['shipping_sort_order']
- ),
- array(
- 'order_total_id' => '',
- 'code' => 'total',
- 'value' => $subtotal + $shipping,
- 'sort_order' => $totalSettings['total_sort_order']
- )
- );
-
- if (isset($order['externalId'])) {
- $this->model_sale_order->editOrder($order['externalId'], $data);
- } else {
- $this->model_sale_order->addOrder($data);
- $last = $this->model_sale_order->getOrders($data = array('order' => 'DESC', 'limit' => 1));
- $forFix[] = array('id' => $order['id'], 'externalId' => (int) $last[0]['order_id']);
+ $this->model_sale_order->editOrder($order['externalId'], $data);
+ } else {
+ $this->model_sale_order->addOrder($data);
+ $last = $this->model_sale_order->getOrders($data = array('order' => 'DESC', 'limit' => 1));
+ $ordersIdsFix[] = array('id' => $order['id'], 'externalId' => (int) $last[0]['order_id']);
+ }
}
}
- if (!empty($forFix)) {
- $crm->orderFixExternalIds($forFix);
+ if (!empty($customersIdsFix)) {
+ $crm->customerFixExternalIds($customersIdsFix);
+ }
+
+ if (!empty($ordersIdsFix)) {
+ $crm->orderFixExternalIds($ordersIdsFix);
}
} else {
@@ -324,6 +389,10 @@ class ControllerModuleIntarocrm extends Controller {
}
}
+ public function export() {
+ file_put_contents(__DIR__ . '/../../../download/intarocrm.xml', $this->xml());
+ }
+
private function validate() {
if (!$this->user->hasPermission('modify', 'module/intarocrm')) {
$this->error['warning'] = $this->language->get('error_permission');
@@ -381,5 +450,115 @@ class ControllerModuleIntarocrm extends Controller {
return $paymentTypes;
}
+
+ private function xml()
+ {
+ $this->dd = new DOMDocument();
+ $this->dd->loadXML('
+
+
+ '.$this->config->get('config_name').'
+
+
+
+
+ ');
+
+ $this->eCategories = $this->dd->getElementsByTagName('categories')->item(0);
+ $this->eOffers = $this->dd->getElementsByTagName('offers')->item(0);
+
+ $this->addCategories();
+ $this->addOffers();
+ return $this->dd->saveXML();
+ }
+
+ private function addCategories()
+ {
+ $this->load->model('catalog/category');
+
+ foreach ($this->model_catalog_category->getCategories(array()) as $category) {
+ $e = $this->eCategories->appendChild($this->dd->createElement('category', $category['name']));
+ $e->setAttribute('id',$category['category_id']);
+ }
+
+ }
+
+ private function addOffers()
+ {
+ $this->load->model('catalog/product');
+ $this->load->model('catalog/manufacturer');
+ $this->load->model('tool/image');
+
+ $offerManufacturers = array();
+
+ $manufacturers = $this->model_catalog_manufacturer->getManufacturers(array());
+
+ foreach ($manufacturers as $manufacturer) {
+ $offerManufacturers[$manufacturer['manufacturer_id']] = $manufacturer['name'];
+ }
+
+ foreach ($this->model_catalog_product->getProducts(array()) as $offer) {
+
+ $e = $this->eOffers->appendChild($this->dd->createElement('offer'));
+ $e->setAttribute('id', $offer['product_id']);
+ $e->setAttribute('productId', $offer['product_id']);
+ $e->setAttribute('quantity', $offer['quantity']);
+ $e->setAttribute('available', $offer['status'] ? 'true' : 'false');
+
+ /*
+ * DIRTY HACK, NEED TO REFACTOR
+ */
+
+ $sql = "SELECT * FROM `" . DB_PREFIX . "product_to_category` WHERE `product_id` = " .$offer['product_id']. ";";
+ $result = $this->db->query($sql);
+ foreach ($result->rows as $row) {
+ $e->appendChild($this->dd->createElement('categoryId', $row['category_id']));
+ }
+
+ $e->appendChild($this->dd->createElement('name'))->appendChild($this->dd->createTextNode($offer['name']));
+ $e->appendChild($this->dd->createElement('productName'))->appendChild($this->dd->createTextNode($offer['name']));
+ if ($offer['manufacturer_id'] != 0) {
+ $e->appendChild($this->dd->createElement('vendor'))->appendChild($this->dd->createTextNode($offerManufacturers[$offer['manufacturer_id']]));
+ }
+ $e->appendChild($this->dd->createElement('price', $offer['price']));
+
+ if ($offer['image']) {
+ $e->appendChild(
+ $this->dd->createElement(
+ 'picture',
+ $this->model_tool_image->resize($offer['image'], $this->config->get('config_image_product_width'), $this->config->get('config_image_product_height'))
+ )
+ );
+ }
+
+ $e->appendChild($this->dd->createElement('url'))->appendChild(
+ $this->dd->createTextNode(
+ $this->url->link('product/product&product_id=' . $offer['product_id'])
+ )
+ );
+
+ if ($offer['sku'] != '') {
+ $sku = $this->dd->createElement('param');
+ $sku->setAttribute('name', 'article');
+ $sku->appendChild($this->dd->createTextNode($offer['sku']));
+ $e->appendChild($sku);
+ }
+
+ if ($offer['weight'] != '') {
+ $weight = $this->dd->createElement('param');
+ $weight->setAttribute('name', 'weight');
+ $weightValue = (isset($offer['weight_class'])) ? $offer['weight'] . ' ' . $offer['weight_class'] : $offer['weight'];
+ $weight->appendChild($this->dd->createTextNode($weightValue));
+ $e->appendChild($weight);
+ }
+
+ if ($offer['length'] != '' && $offer['width'] != '' && $offer['height'] != '') {
+ $size = $this->dd->createElement('param');
+ $size->setAttribute('name', 'size');
+ $size->appendChild($this->dd->createTextNode($offer['length'] .'x'. $offer['width'] .'x'. $offer['height']));
+ $e->appendChild($size);
+ }
+ }
+ }
}
?>
\ No newline at end of file
diff --git a/catalog/controller/export/intarocrm.php b/catalog/controller/export/intarocrm.php
deleted file mode 100644
index 9966965..0000000
--- a/catalog/controller/export/intarocrm.php
+++ /dev/null
@@ -1,113 +0,0 @@
-xml();
- }
-
- private function xml()
- {
- $this->dd = new DOMDocument();
- $this->dd->loadXML('
-
-
- '.$this->config->get('config_name').'
-
-
-
-
- ');
-
- $this->eCategories = $this->dd->getElementsByTagName('categories')->item(0);
- $this->eOffers = $this->dd->getElementsByTagName('offers')->item(0);
-
- $this->addCategories();
- $this->addOffers();
- return $this->dd->saveXML();
- }
-
- private function addCategories()
- {
- $this->language->load('product/category');
- $this->load->model('catalog/category');
-
- foreach ($this->model_catalog_category->getCategories() as $category) {
- $e = $this->eCategories->appendChild($this->dd->createElement('category', $category['name']));
- $e->setAttribute('id',$category['category_id']);
- }
-
- }
-
- private function addOffers()
- {
- $this->load->model('catalog/product');
- $this->load->model('tool/image');
-
- foreach ($this->model_catalog_product->getProducts(array()) as $offer) {
- $e = $this->eOffers->appendChild($this->dd->createElement('offer'));
- $e->setAttribute('id', $offer['product_id']);
- $e->setAttribute('productId', $offer['product_id']);
- $e->setAttribute('quantity', $offer['quantity']);
- $e->setAttribute('available', $offer['status'] ? 'true' : 'false');
-
- /*
- * DIRTY HACK, NEED TO REFACTOR
- */
-
- $sql = "SELECT * FROM `" . DB_PREFIX . "product_to_category` WHERE `product_id` = " .$offer['product_id']. ";";
- $result = $this->db->query($sql);
- foreach ($result->rows as $row) {
- $e->appendChild($this->dd->createElement('categoryId', $row['category_id']));
- }
-
- $e->appendChild($this->dd->createElement('name'))->appendChild($this->dd->createTextNode($offer['name']));
- $e->appendChild($this->dd->createElement('productName'))->appendChild($this->dd->createTextNode($offer['name']));
- $e->appendChild($this->dd->createElement('vendor'))->appendChild($this->dd->createTextNode($offer['manufacturer']));
- $e->appendChild($this->dd->createElement('price', $offer['price']));
-
- if ($offer['image']) {
- $e->appendChild(
- $this->dd->createElement(
- 'picture',
- $this->model_tool_image->resize($offer['image'], $this->config->get('config_image_product_width'), $this->config->get('config_image_product_height'))
- )
- );
- }
-
- $e->appendChild($this->dd->createElement('url'))->appendChild(
- $this->dd->createTextNode(
- $this->url->link('product/product&product_id=' . $offer['product_id'])
- )
- );
-
- if ($offer['sku'] != '') {
- $sku = $this->dd->createElement('param');
- $sku->setAttribute('name', 'article');
- $sku->appendChild($this->dd->createTextNode($offer['sku']));
- $e->appendChild($sku);
- }
-
- if ($offer['weight'] != '') {
- $weight = $this->dd->createElement('param');
- $weight->setAttribute('name', 'weight');
- $weightValue = (isset($offer['weight_class'])) ? $offer['weight'] . ' ' . $offer['weight_class'] : $offer['weight'];
- $weight->appendChild($this->dd->createTextNode($weightValue));
- $e->appendChild($weight);
- }
-
- if ($offer['length'] != '' && $offer['width'] != '' && $offer['height'] != '') {
- $size = $this->dd->createElement('param');
- $size->setAttribute('name', 'size');
- $size->appendChild($this->dd->createTextNode($offer['length'] .'x'. $offer['width'] .'x'. $offer['height']));
- $e->appendChild($size);
- }
- }
- }
-
-}
-?>
diff --git a/cli/cli_dispatch.php b/cli/cli_dispatch.php
new file mode 100644
index 0000000..8baa5e4
--- /dev/null
+++ b/cli/cli_dispatch.php
@@ -0,0 +1,141 @@
+write("ERROR: cli $cli_action call attempted by non-cli.");
+ http_response_code(400);
+ exit;
+}
+
+// Ensure $cli_action is set
+if (!isset($cli_action)) {
+ echo 'ERROR: $cli_action must be set in calling script.';
+ $log->write('ERROR: $cli_action must be set in calling script.');
+ http_response_code(400);
+ exit;
+}
+
+// Version
+define('VERSION', '1.5.6');
+
+// Configuration (note we're using the admin config)
+require_once(__DIR__ . '/../admin/config.php');
+
+// Configuration check
+if (!defined('DIR_APPLICATION')) {
+ echo "ERROR: cli $cli_action call missing configuration.";
+ $log->write("ERROR: cli $cli_action call missing configuration.");
+ http_response_code(400);
+ exit;
+}
+
+// Startup
+require_once(DIR_SYSTEM . 'startup.php');
+
+// Application Classes
+require_once(DIR_SYSTEM . 'library/currency.php');
+require_once(DIR_SYSTEM . 'library/user.php');
+require_once(DIR_SYSTEM . 'library/weight.php');
+require_once(DIR_SYSTEM . 'library/length.php');
+
+// Registry
+$registry = new Registry();
+
+// Loader
+$loader = new Loader($registry);
+$registry->set('load', $loader);
+
+// Config
+$config = new Config();
+$registry->set('config', $config);
+
+// Database
+$db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
+$registry->set('db', $db);
+
+// Settings
+$query = $db->query("SELECT * FROM " . DB_PREFIX . "setting WHERE store_id = '0'");
+
+foreach ($query->rows as $setting) {
+ if (!$setting['serialized']) {
+ $config->set($setting['key'], $setting['value']);
+ } else {
+ $config->set($setting['key'], unserialize($setting['value']));
+ }
+}
+
+// Url
+$url = new Url(HTTP_SERVER, HTTPS_SERVER);
+$registry->set('url', $url);
+
+// Log
+$log = new Log($config->get('config_error_filename'));
+$registry->set('log', $log);
+
+function error_handler($errno, $errstr, $errfile, $errline) {
+ global $log, $config;
+
+ switch ($errno) {
+ case E_NOTICE:
+ case E_USER_NOTICE:
+ $error = 'Notice';
+ break;
+ case E_WARNING:
+ case E_USER_WARNING:
+ $error = 'Warning';
+ break;
+ case E_ERROR:
+ case E_USER_ERROR:
+ $error = 'Fatal Error';
+ break;
+ default:
+ $error = 'Unknown';
+ break;
+ }
+
+ if ($config->get('config_error_display')) {
+ echo "\n".'PHP ' . $error . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline."\n";
+ }
+
+ if ($config->get('config_error_log')) {
+ $log->write('PHP ' . $error . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline);
+ }
+
+ return true;
+}
+set_error_handler('error_handler');
+$request = new Request();
+$registry->set('request', $request);
+$response = new Response();
+$response->addHeader('Content-Type: text/html; charset=utf-8');
+$registry->set('response', $response);
+$cache = new Cache();
+$registry->set('cache', $cache);
+$session = new Session();
+$registry->set('session', $session);
+$languages = array();
+
+$query = $db->query("SELECT * FROM " . DB_PREFIX . "language");
+foreach ($query->rows as $result) {
+ $languages[$result['code']] = $result;
+}
+$config->set('config_language_id', $languages[$config->get('config_admin_language')]['language_id']);
+$language = new Language($languages[$config->get('config_admin_language')]['directory']);
+$language->load($languages[$config->get('config_admin_language')]['filename']);
+$registry->set('language', $language);
+
+$document = new Document();
+$registry->set('document', $document);
+
+$registry->set('currency', new Currency($registry));
+$registry->set('weight', new Weight($registry));
+$registry->set('length', new Length($registry));
+$registry->set('user', new User($registry));
+
+$controller = new Front($registry);
+$action = new Action($cli_action);
+$controller->dispatch($action, new Action('error/not_found'));
+
+// Output
+$response->output();
+?>
\ No newline at end of file
diff --git a/cli/cli_export.php b/cli/cli_export.php
new file mode 100644
index 0000000..095a52c
--- /dev/null
+++ b/cli/cli_export.php
@@ -0,0 +1,3 @@
+ Intstall module. Before running exchange you must configure module.
+
+### Export
+
+Setup cron job for periodically catalog export
+
+```
+0 */12 0 0 0 /usr/bin/php /path/to/opencart/instance/cli/cli_export.php >> /path/to/opencart/instance/system/logs/cronjob_export.log 2>&1
+```
+
+### Exchange setup
+
+
+#### Export new order from shop to CRM
+
+Open /catalog/model/checkout/order.php script. Into addOrder method add this line before return statement:
+
+```
+$this->crmOrderAction($data, $order_id, 'create');
+```
+
+In the end of this file add method:
+
+```
+protected function crmOrderAction($order, $order_id, $action=null)
+{
+ $this->load->model('setting/setting');
+ $settings = $this->model_setting_setting->getSetting('intarocrm');
+ $settings['domain'] = parse_url(HTTP_SERVER, PHP_URL_HOST);
+
+ if(isset($settings['intarocrm_url']) && $settings['intarocrm_url'] != '' && isset($settings['intarocrm_apikey']) && $settings['intarocrm_apikey'] != '') {
+ include_once __DIR__ . '/../../../system/library/intarocrm/apihelper.php';
+
+ $order['order_id'] = $order_id;
+ $crm = new ApiHelper($settings);
+
+ if ($action != null) {
+ $method = 'order' . ucfirst($action);
+ $crm->$method($order);
+ }
+ }
+
+}
+```
+
+#### Export new order from CRM to shop
+
+Setup cron job for exchange between CRM & your shop
+
+```
+*/5 0 0 0 0 /usr/bin/php /path/to/opencart/instance/cli/cli_export.php >> /path/to/opencart/instance/system/logs/cronjob_history.log 2>&1
+```
\ No newline at end of file
diff --git a/doc/TODO.md b/doc/TODO.md
new file mode 100644
index 0000000..4b1d6c0
--- /dev/null
+++ b/doc/TODO.md
@@ -0,0 +1,6 @@
+TODO
+====
+
+* Edit order hook
+* Export old customers & orders
+* New customers export
\ No newline at end of file
diff --git a/example/catalog/model/checkout/order.php b/example/catalog/model/checkout/order.php
deleted file mode 100644
index 21eecf4..0000000
--- a/example/catalog/model/checkout/order.php
+++ /dev/null
@@ -1,82 +0,0 @@
-db->query("INSERT INTO `" . DB_PREFIX . "order` SET invoice_prefix = '" . $this->db->escape($data['invoice_prefix']) . "', store_id = '" . (int)$data['store_id'] . "', store_name = '" . $this->db->escape($data['store_name']) . "', store_url = '" . $this->db->escape($data['store_url']) . "', customer_id = '" . (int)$data['customer_id'] . "', customer_group_id = '" . (int)$data['customer_group_id'] . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', fax = '" . $this->db->escape($data['fax']) . "', payment_firstname = '" . $this->db->escape($data['payment_firstname']) . "', payment_lastname = '" . $this->db->escape($data['payment_lastname']) . "', payment_company = '" . $this->db->escape($data['payment_company']) . "', payment_company_id = '" . $this->db->escape($data['payment_company_id']) . "', payment_tax_id = '" . $this->db->escape($data['payment_tax_id']) . "', payment_address_1 = '" . $this->db->escape($data['payment_address_1']) . "', payment_address_2 = '" . $this->db->escape($data['payment_address_2']) . "', payment_city = '" . $this->db->escape($data['payment_city']) . "', payment_postcode = '" . $this->db->escape($data['payment_postcode']) . "', payment_country = '" . $this->db->escape($data['payment_country']) . "', payment_country_id = '" . (int)$data['payment_country_id'] . "', payment_zone = '" . $this->db->escape($data['payment_zone']) . "', payment_zone_id = '" . (int)$data['payment_zone_id'] . "', payment_address_format = '" . $this->db->escape($data['payment_address_format']) . "', payment_method = '" . $this->db->escape($data['payment_method']) . "', payment_code = '" . $this->db->escape($data['payment_code']) . "', shipping_firstname = '" . $this->db->escape($data['shipping_firstname']) . "', shipping_lastname = '" . $this->db->escape($data['shipping_lastname']) . "', shipping_company = '" . $this->db->escape($data['shipping_company']) . "', shipping_address_1 = '" . $this->db->escape($data['shipping_address_1']) . "', shipping_address_2 = '" . $this->db->escape($data['shipping_address_2']) . "', shipping_city = '" . $this->db->escape($data['shipping_city']) . "', shipping_postcode = '" . $this->db->escape($data['shipping_postcode']) . "', shipping_country = '" . $this->db->escape($data['shipping_country']) . "', shipping_country_id = '" . (int)$data['shipping_country_id'] . "', shipping_zone = '" . $this->db->escape($data['shipping_zone']) . "', shipping_zone_id = '" . (int)$data['shipping_zone_id'] . "', shipping_address_format = '" . $this->db->escape($data['shipping_address_format']) . "', shipping_method = '" . $this->db->escape($data['shipping_method']) . "', shipping_code = '" . $this->db->escape($data['shipping_code']) . "', comment = '" . $this->db->escape($data['comment']) . "', total = '" . (float)$data['total'] . "', affiliate_id = '" . (int)$data['affiliate_id'] . "', commission = '" . (float)$data['commission'] . "', language_id = '" . (int)$data['language_id'] . "', currency_id = '" . (int)$data['currency_id'] . "', currency_code = '" . $this->db->escape($data['currency_code']) . "', currency_value = '" . (float)$data['currency_value'] . "', ip = '" . $this->db->escape($data['ip']) . "', forwarded_ip = '" . $this->db->escape($data['forwarded_ip']) . "', user_agent = '" . $this->db->escape($data['user_agent']) . "', accept_language = '" . $this->db->escape($data['accept_language']) . "', date_added = NOW(), date_modified = NOW()");
-
- $order_id = $this->db->getLastId();
-
- foreach ($data['products'] as $product) {
- $this->db->query("INSERT INTO " . DB_PREFIX . "order_product SET order_id = '" . (int)$order_id . "', product_id = '" . (int)$product['product_id'] . "', name = '" . $this->db->escape($product['name']) . "', model = '" . $this->db->escape($product['model']) . "', quantity = '" . (int)$product['quantity'] . "', price = '" . (float)$product['price'] . "', total = '" . (float)$product['total'] . "', tax = '" . (float)$product['tax'] . "', reward = '" . (int)$product['reward'] . "'");
-
- $order_product_id = $this->db->getLastId();
-
- foreach ($product['option'] as $option) {
- $this->db->query("INSERT INTO " . DB_PREFIX . "order_option SET order_id = '" . (int)$order_id . "', order_product_id = '" . (int)$order_product_id . "', product_option_id = '" . (int)$option['product_option_id'] . "', product_option_value_id = '" . (int)$option['product_option_value_id'] . "', name = '" . $this->db->escape($option['name']) . "', `value` = '" . $this->db->escape($option['value']) . "', `type` = '" . $this->db->escape($option['type']) . "'");
- }
-
- foreach ($product['download'] as $download) {
- $this->db->query("INSERT INTO " . DB_PREFIX . "order_download SET order_id = '" . (int)$order_id . "', order_product_id = '" . (int)$order_product_id . "', name = '" . $this->db->escape($download['name']) . "', filename = '" . $this->db->escape($download['filename']) . "', mask = '" . $this->db->escape($download['mask']) . "', remaining = '" . (int)($download['remaining'] * $product['quantity']) . "'");
- }
- }
-
- foreach ($data['vouchers'] as $voucher) {
- $this->db->query("INSERT INTO " . DB_PREFIX . "order_voucher SET order_id = '" . (int)$order_id . "', description = '" . $this->db->escape($voucher['description']) . "', code = '" . $this->db->escape($voucher['code']) . "', from_name = '" . $this->db->escape($voucher['from_name']) . "', from_email = '" . $this->db->escape($voucher['from_email']) . "', to_name = '" . $this->db->escape($voucher['to_name']) . "', to_email = '" . $this->db->escape($voucher['to_email']) . "', voucher_theme_id = '" . (int)$voucher['voucher_theme_id'] . "', message = '" . $this->db->escape($voucher['message']) . "', amount = '" . (float)$voucher['amount'] . "'");
- }
-
- foreach ($data['totals'] as $total) {
- $this->db->query("INSERT INTO " . DB_PREFIX . "order_total SET order_id = '" . (int)$order_id . "', code = '" . $this->db->escape($total['code']) . "', title = '" . $this->db->escape($total['title']) . "', text = '" . $this->db->escape($total['text']) . "', `value` = '" . (float)$total['value'] . "', sort_order = '" . (int)$total['sort_order'] . "'");
- }
-
- /*
- * This is integration code
- */
- $this->crmOrderAction($data, $order_id, 'create');
-
- /*
- * This is original code again
- */
- return $order_id;
- }
-
-
-
- /*
- * Crm order action method. Add it into the end of class code.
- *
- * @param $action string values: edit, create
- */
- protected function crmOrderAction($order, $order_id, $action=null)
- {
- $this->load->model('setting/setting');
- $settings = $this->model_setting_setting->getSetting('intarocrm');
- $settings['domain'] = parse_url(HTTP_SERVER, PHP_URL_HOST);
-
- if(isset($settings['intarocrm_url']) && $settings['intarocrm_url'] != '' && isset($settings['intarocrm_apikey']) && $settings['intarocrm_apikey'] != '') {
- include_once __DIR__ . '/../../../system/library/intarocrm/apihelper.php';
-
- $order['order_id'] = $order_id;
- $crm = new ApiHelper($settings);
-
- if ($action == null) {
- $crm->dumperData($order);
- } else {
- $method = 'order' . ucfirst($action);
- $crm->$method($order);
- }
- }
-
- }
-
-}
-?>
\ No newline at end of file
diff --git a/system/library/intarocrm/.gitignore b/system/library/intarocrm/.gitignore
new file mode 100644
index 0000000..61ead86
--- /dev/null
+++ b/system/library/intarocrm/.gitignore
@@ -0,0 +1 @@
+/vendor
diff --git a/system/library/intarocrm/apihelper.php b/system/library/intarocrm/apihelper.php
index 453ba57..75938ee 100644
--- a/system/library/intarocrm/apihelper.php
+++ b/system/library/intarocrm/apihelper.php
@@ -157,6 +157,41 @@ class ApiHelper
}
}
+ public function customerFixExternalIds($data)
+ {
+ try {
+ $this->intaroApi->customerFixExternalIds($data);
+ } catch (ApiException $e) {
+ $this->log->addError('['.$this->domain.'] RestApi::customerFixExternalIds:' . $e->getMessage());
+ $this->log->addError('['.$this->domain.'] RestApi::customerFixExternalIds:' . json_encode($data));
+
+ return false;
+ } catch (CurlException $e) {
+ $this->log->addError('['.$this->domain.'] RestApi::customerFixExternalIds::Curl:' . $e->getMessage());
+
+ return false;
+ }
+ }
+
+ public function getOrderItems($order_id)
+ {
+ try {
+ $order = $this->intaroApi->orderGet($order_id);
+
+ return $order['items'];
+ } catch (ApiException $e) {
+ $this->log->addError('['.$this->domain.'] RestApi::orderFixExternalIds:' . $e->getMessage());
+ $this->log->addError('['.$this->domain.'] RestApi::orderFixExternalIds:' . json_encode($data));
+
+ return false;
+ } catch (CurlException $e) {
+ $this->log->addError('['.$this->domain.'] RestApi::orderFixExternalIds::Curl:' . $e->getMessage());
+
+ return false;
+ }
+
+ }
+
private function saveDate($date) {
file_put_contents($this->fileDate, $date, LOCK_EX);
}
diff --git a/system/library/intarocrm/composer.lock b/system/library/intarocrm/composer.lock
new file mode 100644
index 0000000..d035da2
--- /dev/null
+++ b/system/library/intarocrm/composer.lock
@@ -0,0 +1,231 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "de9234b1e9e1ac5b5aaa5c5377eaafce",
+ "packages": [
+ {
+ "name": "intarocrm/rest-api-client",
+ "version": "v1.2.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/intarocrm/rest-api-client",
+ "reference": "b54350ff2f09d8202cf2931895bba8dced4dcf21"
+ },
+ "require": {
+ "ext-curl": "*",
+ "php": ">=5.2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "IntaroCrm\\": "lib/"
+ }
+ },
+ "authors": [
+ {
+ "name": "Kruglov Kirill",
+ "email": "kruglov@intaro.ru",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP Client for IntaroCRM REST API",
+ "homepage": "http://www.intarocrm.ru/",
+ "keywords": [
+ "Intaro CRM",
+ "api",
+ "rest"
+ ],
+ "support": {
+ "email": "support@intarocrm.ru"
+ },
+ "time": "2014-04-13 09:58:37"
+ },
+ {
+ "name": "monolog/monolog",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/monolog.git",
+ "reference": "12545cda2f7a0bd82a110f742ef455fe735e60cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/12545cda2f7a0bd82a110f742ef455fe735e60cf",
+ "reference": "12545cda2f7a0bd82a110f742ef455fe735e60cf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "psr/log": "~1.0"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0.0"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "~2.4, >2.4.8",
+ "doctrine/couchdb": "~1.0@dev",
+ "graylog2/gelf-php": "~1.0",
+ "phpunit/phpunit": "~3.7.0",
+ "raven/raven": "~0.5",
+ "ruflin/elastica": "0.90.*",
+ "videlalvaro/php-amqplib": "~2.4"
+ },
+ "suggest": {
+ "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+ "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+ "ext-mongo": "Allow sending log messages to a MongoDB server",
+ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+ "raven/raven": "Allow sending log messages to a Sentry server",
+ "rollbar/rollbar": "Allow sending log messages to Rollbar",
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
+ "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.11.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Monolog\\": "src/Monolog"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+ "homepage": "http://github.com/Seldaek/monolog",
+ "keywords": [
+ "log",
+ "logging",
+ "psr-3"
+ ],
+ "time": "2014-07-31 22:12:22"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Psr\\Log\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2012-12-21 11:40:51"
+ },
+ {
+ "name": "symfony/console",
+ "version": "dev-master",
+ "target-dir": "Symfony/Component/Console",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Console.git",
+ "reference": "919345e2757aa3d3aca1d1ce5a8f53f65d1990ef"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Console/zipball/919345e2757aa3d3aca1d1ce5a8f53f65d1990ef",
+ "reference": "919345e2757aa3d3aca1d1ce5a8f53f65d1990ef",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/event-dispatcher": "~2.1",
+ "symfony/process": "~2.1"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Console\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Symfony Console Component",
+ "homepage": "http://symfony.com",
+ "time": "2014-08-14 16:37:29"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {
+ "symfony/console": 20,
+ "monolog/monolog": 20
+ },
+ "prefer-stable": false,
+ "platform": {
+ "php": ">=5.3"
+ },
+ "platform-dev": []
+}