From 9d9218cf7724583069b798052b93d3bdb22a410a Mon Sep 17 00:00:00 2001 From: Dmitry Akolzin Date: Wed, 22 Mar 2017 11:52:11 +0300 Subject: [PATCH] new files for 2.3 --- .../controller/extension/module/retailcrm.php | 348 ++++++++++++++ .../en-gb/extension/module/retailcrm.php | 31 ++ .../ru-ru/extension/module/retailcrm.php | 31 ++ .../model/extension/retailcrm/custom/.gitkeep | 0 admin/model/extension/retailcrm/customer.php | 51 ++ admin/model/extension/retailcrm/history.php | 455 ++++++++++++++++++ admin/model/extension/retailcrm/icml.php | 336 +++++++++++++ admin/model/extension/retailcrm/order.php | 116 +++++ .../model/extension/retailcrm/references.php | 138 ++++++ .../template/extension/module/retailcrm.tpl | 110 +++++ .../controller/extension/module/retailcrm.php | 108 +++++ .../model/extension/retailcrm/customer.php | 42 ++ catalog/model/extension/retailcrm/order.php | 262 ++++++++++ 13 files changed, 2028 insertions(+) create mode 100644 admin/controller/extension/module/retailcrm.php create mode 100644 admin/language/en-gb/extension/module/retailcrm.php create mode 100644 admin/language/ru-ru/extension/module/retailcrm.php create mode 100644 admin/model/extension/retailcrm/custom/.gitkeep create mode 100644 admin/model/extension/retailcrm/customer.php create mode 100644 admin/model/extension/retailcrm/history.php create mode 100644 admin/model/extension/retailcrm/icml.php create mode 100644 admin/model/extension/retailcrm/order.php create mode 100644 admin/model/extension/retailcrm/references.php create mode 100644 admin/view/template/extension/module/retailcrm.tpl create mode 100644 catalog/controller/extension/module/retailcrm.php create mode 100644 catalog/model/extension/retailcrm/customer.php create mode 100644 catalog/model/extension/retailcrm/order.php diff --git a/admin/controller/extension/module/retailcrm.php b/admin/controller/extension/module/retailcrm.php new file mode 100644 index 0000000..fc5500f --- /dev/null +++ b/admin/controller/extension/module/retailcrm.php @@ -0,0 +1,348 @@ + + * @license https://opensource.org/licenses/MIT MIT License + * @link http://www.retailcrm.ru/docs/Developers/ApiVersion3 + */ +class ControllerExtensionModuleRetailcrm extends Controller +{ + private $_error = array(); + protected $log, $statuses, $payments, $deliveryTypes, $retailcrm; + public $children, $template; + + /** + * Install method + * + * @return void + */ + public function install() + { + $this->load->model('setting/setting'); + $this->model_setting_setting + ->editSetting('retailcrm', array('retailcrm_status' => 1)); + + $this->load->model('extension/event'); + + $this->model_extension_event + ->addEvent( + 'retailcrm', + 'catalog/model/checkout/order/addOrder/after', + 'extension/module/retailcrm/order_create' + ); + + $this->model_extension_event + ->addEvent( + 'retailcrm', + 'catalog/model/checkout/order/addOrderHistory/after', + 'extension/module/retailcrm/order_edit' + ); + + $this->model_extension_event + ->addEvent( + 'retailcrm', + 'catalog/model/account/customer/addCustomer/after', + 'extension/module/retailcrm/customer_create' + ); + + $this->model_extension_event + ->addEvent( + 'retailcrm', + 'catalog/model/checkout/order/editOrder/after', + 'extension/module/retailcrm/order_edit' + ); + } + + /** + * Uninstall method + * + * @return void + */ + public function uninstall() + { + $this->load->model('setting/setting'); + $this->model_setting_setting + ->editSetting('retailcrm', array('retailcrm_status' => 0)); + + $this->load->model('extension/event'); + $this->model_extension_event->deleteEvent('retailcrm'); + } + + /** + * Setup page + * + * @return void + */ + public function index() + { + + $this->load->model('setting/setting'); + $this->load->model('extension/module'); + $this->load->model('extension/retailcrm/references'); + $this->load->language('extension/module/retailcrm'); + $this->document->setTitle($this->language->get('heading_title')); + $this->document->addStyle('/admin/view/stylesheet/retailcrm.css'); + + if ($this->request->server['REQUEST_METHOD'] == 'POST' && $this->validate()) { + if (parse_url($this->request->post['retailcrm_url'])){ + $crm_url = parse_url($this->request->post['retailcrm_url'], PHP_URL_HOST); + $this->request->post['retailcrm_url'] = 'https://'.$crm_url; + } + $this->model_setting_setting->editSetting( + 'retailcrm', + $this->request->post + ); + + $this->session->data['success'] = $this->language->get('text_success'); + $redirect = $this->url->link( + 'extension/module/retailcrm', 'token=' . $this->session->data['token'], + 'SSL' + ); + + $this->response->redirect($redirect); + } + + $text_strings = array( + 'heading_title', + 'text_enabled', + 'text_disabled', + 'button_save', + 'button_cancel', + 'text_notice', + 'retailcrm_title', + 'retailcrm_url', + 'retailcrm_apikey', + 'retailcrm_base_settings', + 'retailcrm_dict_settings', + 'retailcrm_dict_delivery', + 'retailcrm_dict_status', + 'retailcrm_dict_payment', + ); + + $this->load->model('extension/extension'); + $_data = &$data; + + foreach ($text_strings as $text) { + $_data[$text] = $this->language->get($text); + } + + $_data['retailcrm_errors'] = array(); + $_data['saved_settings'] = $this->model_setting_setting + ->getSetting('retailcrm'); + + $url = isset($_data['saved_settings']['retailcrm_url']) + ? $_data['saved_settings']['retailcrm_url'] + : null; + $key = isset($_data['saved_settings']['retailcrm_apikey']) + ? $_data['saved_settings']['retailcrm_apikey'] + : null; + + if (!empty($url) && !empty($key)) { + + $this->retailcrm = new RetailcrmProxy( + $url, + $key, + DIR_SYSTEM . 'storage/logs/retailcrm.log' + ); + + $_data['delivery'] = $this->model_extension_retailcrm_references + ->getDeliveryTypes(); + $_data['statuses'] = $this->model_extension_retailcrm_references + ->getOrderStatuses(); + $_data['payments'] = $this->model_extension_retailcrm_references + ->getPaymentTypes(); + + } + + $config_data = array( + 'retailcrm_status' + ); + + foreach ($config_data as $conf) { + if (isset($this->request->post[$conf])) { + $_data[$conf] = $this->request->post[$conf]; + } else { + $_data[$conf] = $this->config->get($conf); + } + } + + if (isset($this->error['warning'])) { + $_data['error_warning'] = $this->error['warning']; + } else { + $_data['error_warning'] = ''; + } + + $_data['breadcrumbs'] = array(); + + $_data['breadcrumbs'][] = array( + 'text' => $this->language->get('text_home'), + 'href' => $this->url->link( + 'common/home', + 'token=' . $this->session->data['token'], 'SSL' + ), + 'separator' => false + ); + + $_data['breadcrumbs'][] = array( + 'text' => $this->language->get('text_module'), + 'href' => $this->url->link( + 'extension/extension/module', + 'token=' . $this->session->data['token'], 'SSL' + ), + 'separator' => ' :: ' + ); + + $_data['breadcrumbs'][] = array( + 'text' => $this->language->get('retailcrm_title'), + 'href' => $this->url->link( + 'extension/module/retailcrm', + 'token=' . $this->session->data['token'], 'SSL' + ), + 'separator' => ' :: ' + ); + + $_data['action'] = $this->url->link( + 'extension/module/retailcrm', + 'token=' . $this->session->data['token'], 'SSL' + ); + + $_data['cancel'] = $this->url->link( + 'extension/extension', + 'token=' . $this->session->data['token'], 'SSL' + ); + + $_data['modules'] = array(); + + if (isset($this->request->post['retailcrm_module'])) { + $_data['modules'] = $this->request->post['retailcrm_module']; + } elseif ($this->config->get('retailcrm_module')) { + $_data['modules'] = $this->config->get('retailcrm_module'); + } + + $this->load->model('design/layout'); + $_data['layouts'] = $this->model_design_layout->getLayouts(); + + $_data['header'] = $this->load->controller('common/header'); + $_data['column_left'] = $this->load->controller('common/column_left'); + $_data['footer'] = $this->load->controller('common/footer'); + + $this->response->setOutput( + $this->load->view('extension/module/retailcrm.tpl', $_data) + ); + } + + /** + * History method + * + * @return void + */ + public function history() + { + if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/history.php')) { + $this->load->model('extension/retailcrm/custom/history'); + $this->model_extension_retailcrm_custom_history->request(); + } else { + $this->load->model('extension/retailcrm/history'); + $this->model_extension_retailcrm_history->request(); + } + } + + /** + * ICML generation + * + * @return void + */ + public function icml() + { + if (file_exists(DIR_APPLICATION . 'model/extension/retailcrm/custom/icml.php')) { + $this->load->model('extension/retailcrm/custom/icml'); + $this->model_extension_retailcrm_custom_icml->generateICML(); + } else { + $this->load->model('extension/retailcrm/icml'); + $this->model_extension_retailcrm_icml->generateICML(); + } + } + + /** + * Create order on event + * + * @param int $order_id order identificator + * + * @return void + */ + public function order_create($order_id) + { + $this->load->model('checkout/order'); + $this->load->model('account/order'); + + $data = $this->model_checkout_order->getOrder($order_id); + $data['products'] = $this->model_account_order->getOrderProducts($order_id); + + if (!isset($data['fromApi'])) { + $this->load->model('setting/setting'); + $status = $this->model_setting_setting->getSetting('retailcrm'); + $data['order_status'] = $status['retailcrm_status'][$data['order_status_id']]; + + $this->load->model('extension/retailcrm/order'); + $this->model_extension_retailcrm_order->sendToCrm($data, $data['order_id']); + } + } + + /** + * Export orders + * + * + */ + public function export() { + + $this->load->model('customer/customer'); + $customers = $this->model_customer_customer->getCustomers(); + + $this->load->model('extension/retailcrm/customer'); + $this->model_extension_retailcrm_customer->uploadToCrm($customers); + + $this->load->model('sale/order'); + $orders = $this->model_sale_order->getOrders(); + + $fullOrders = array(); + foreach($orders as $order) { + $fullOrder = $this->model_sale_order->getOrder($order['order_id']); + + $fullOrder['order_total'] = $this->model_sale_order->getOrderTotals($order['order_id']); + + $fullOrder['products'] = $this->model_sale_order->getOrderProducts($order['order_id']); + foreach($fullOrder['products'] as $key=>$product) { + $fullOrder['products'][$key]['option'] = $this->model_sale_order->getOrderOptions($product['order_id'], $product['order_product_id']); + } + + $fullOrders[] = $fullOrder; + } + + $this->load->model('extension/retailcrm/order'); + $this->model_extension_retailcrm_order->uploadToCrm($fullOrders); + } + + /** + * Validate + * + * @return bool + */ + private function validate() + { + if (!$this->user->hasPermission('modify', 'extension/module/retailcrm')) { + $this->_error['warning'] = $this->language->get('error_permission'); + } + + if (!$this->_error) { + return true; + } else { + return false; + } + } +} diff --git a/admin/language/en-gb/extension/module/retailcrm.php b/admin/language/en-gb/extension/module/retailcrm.php new file mode 100644 index 0000000..f1baabb --- /dev/null +++ b/admin/language/en-gb/extension/module/retailcrm.php @@ -0,0 +1,31 @@ +load->model('setting/setting'); + $settings = $this->model_setting_setting->getSetting('retailcrm'); + + if(empty($customers)) + return false; + if(empty($settings['retailcrm_url']) || empty($settings['retailcrm_apikey'])) + return false; + + require_once DIR_SYSTEM . 'library/retailcrm/bootstrap.php'; + + $this->retailcrmApi = new RetailcrmProxy( + $settings['retailcrm_url'], + $settings['retailcrm_apikey'], + DIR_SYSTEM . 'storage/logs/retailcrm.log' + ); + + $customersToCrm = array(); + + foreach($customers as $customer) { + $customersToCrm[] = $this->process($customer); + } + + $chunkedCustomers = array_chunk($customersToCrm, 50); + + foreach($chunkedCustomers as $customersPart) { + $this->retailcrmApi->customersUpload($customersPart); + } + } + + private function process($customer) { + $customerToCrm = array( + 'externalId' => $customer['customer_id'], + 'firstName' => $customer['firstname'], + 'lastName' => $customer['lastname'], + 'email' => $customer['email'], + 'phones' => array( + array( + 'number' => $customer['telephone'] + ) + ), + 'createdAt' => $customer['date_added'] + ); + + return $customerToCrm; + } +} diff --git a/admin/model/extension/retailcrm/history.php b/admin/model/extension/retailcrm/history.php new file mode 100644 index 0000000..eb19ffb --- /dev/null +++ b/admin/model/extension/retailcrm/history.php @@ -0,0 +1,455 @@ +load->model('setting/setting'); + $this->load->model('setting/store'); + $this->load->model('user/api'); + $this->load->model('sale/order'); + $this->load->model('customer/customer'); + $this->load->model('extension/retailcrm/references'); + $this->load->model('catalog/product'); + $this->load->model('catalog/option'); + $this->load->model('localisation/zone'); + + $this->load->language('extension/module/retailcrm'); + + $settings = $this->model_setting_setting->getSetting('retailcrm'); + $history = $this->model_setting_setting->getSetting('retailcrm_history'); + $settings['domain'] = parse_url(HTTP_SERVER, PHP_URL_HOST); + + $url = isset($settings['retailcrm_url']) ? $settings['retailcrm_url'] : null; + $key = isset($settings['retailcrm_apikey']) ? $settings['retailcrm_apikey'] : null; + + if (empty($url) || empty($key)) { + $this->log->addNotice('You need to configure retailcrm module first.'); + return false; + } + + $this->opencartApiClient = new OpencartApiClient($this->registry); + + $crm = new RetailcrmProxy( + $settings['retailcrm_url'], + $settings['retailcrm_apikey'], + DIR_SYSTEM . 'storage/logs/retailcrm.log' + ); + + $lastRun = !empty($history['retailcrm_history']) + ? new DateTime($history['retailcrm_history']) + : new DateTime(date('Y-m-d H:i:s', strtotime('-1 days', strtotime(date('Y-m-d H:i:s'))))); + + $packs = $crm->ordersHistory(array( + 'startDate' => $lastRun->format('Y-m-d H:i:s'), + ), 1, 100); + if(!$packs->isSuccessful() && count($packs->history) <= 0) + return false; + $orders = RetailcrmHistoryHelper::assemblyOrder($packs->history); + + $generatedAt = $packs['generatedAt']; + + $this->subtotalSettings = $this->model_setting_setting->getSetting('sub_total'); + $this->totalSettings = $this->model_setting_setting->getSetting('total'); + $this->shippingSettings = $this->model_setting_setting->getSetting('shipping'); + + $this->delivery = array_flip($settings['retailcrm_delivery']); + $this->payment = array_flip($settings['retailcrm_payment']); + $this->status = array_flip($settings['retailcrm_status']); + + $this->ocPayment = $this->model_extension_retailcrm_references + ->getOpercartPaymentTypes(); + + $this->ocDelivery = $this->model_extension_retailcrm_references + ->getOpercartDeliveryTypes(); + + $this->zones = $this->model_localisation_zone->getZones(); + + $updatedOrders = array(); + $newOrders = array(); + + foreach ($orders as $order) { + + if (isset($order['deleted'])) continue; + + if (isset($order['externalId'])) { + $updatedOrders[] = $order['id']; + } else { + $newOrders[] = $order['id']; + } + } + + unset($orders); + + if (!empty($newOrders)) { + $orders = $crm->ordersList($filter = array('ids' => $newOrders)); + if ($orders) { + $this->createResult = $this->createOrders($orders['orders']); + } + } + + if (!empty($updatedOrders)) { + $orders = $crm->ordersList($filter = array('ids' => $updatedOrders)); + if ($orders) { + $this->updateOrders($orders['orders']); + } + } + + $this->model_setting_setting->editSetting('retailcrm_history', array('retailcrm_history' => $generatedAt)); + + if (!empty($this->createResult['customers'])) { + $crm->customersFixExternalIds($this->createResult['customers']); + } + + if (!empty($this->createResult['orders'])) { + $crm->ordersFixExternalIds($this->createResult['orders']); + } + } + + protected function updateOrders($orders) + { + foreach ($orders as $order) { + $store = $this->config->get('config_store_id'); + + $data = array(); + + $data['store_id'] = $store == null ? 0 : $store; + $data['customer'] = $order['firstName']; + $data['customer_id'] = (!empty($order['customer']['externalId'])) ? $order['customer']['externalId'] : 0; + $data['customer_group_id'] = 1; + $data['firstname'] = $order['firstName']; + $data['lastname'] = (!empty($order['lastName'])) ? $order['lastName'] : ' '; + $data['email'] = $order['email']; + $data['telephone'] = (!empty($order['phone'])) ? $order['phone'] : ''; + $data['comment'] = !empty($order['customerComment']) ? $order['customerComment'] : ''; + $data['fax'] = ''; + + $data['payment_address'] = '0'; + $data['payment_firstname'] = $order['firstName']; + $data['payment_lastname'] = (!empty($order['lastName'])) ? $order['lastName'] : ' '; + $data['payment_address_1'] = isset($order['customer']['address']) ? $order['customer']['address']['text'] : ''; + $data['payment_address_2'] = ''; + $data['payment_company'] = ''; + $data['payment_company_id'] = ''; + $data['payment_city'] = !empty($order['customer']['address']['city']) ? $order['customer']['address']['city'] : $order['delivery']['address']['city']; + $data['payment_postcode'] = !empty( $order['customer']['address']['index'] ) ? $order['customer']['address']['index'] : $order['delivery']['address']['index']; + + $region = ''; + + if (is_int($order['delivery']['address']['region'])) { + $region = $order['delivery']['address']['region']; + } else { + foreach ($this->zones as $zone) { + if ($order['delivery']['address']['region'] == $zone['name']) { + $region = $zone['zone_id']; + } + } + } + + $data['payment_country_id'] = !empty($order['delivery']['address']['country']) ? $order['delivery']['address']['country'] : 0; + $data['payment_zone_id'] = !empty($order['delivery']['address']['region']) ? $order['delivery']['address']['region'] : $region; + + $data['shipping_country_id'] = !empty($order['delivery']['address']['country']) ? $order['delivery']['address']['country'] : 0; + $data['shipping_zone_id'] = $region; + + $data['shipping_address'] = '0'; + $data['shipping_firstname'] = $order['firstName']; + $data['shipping_lastname'] = (!empty($order['lastName'])) ? $order['lastName'] : ' '; + $data['shipping_address_1'] = $order['delivery']['address']['text']; + $data['shipping_address_2'] = ''; + $data['shipping_company'] = ''; + $data['shipping_company_id'] = ''; + $data['shipping_city'] = $order['delivery']['address']['city']; + $data['shipping_postcode'] = $order['delivery']['address']['index']; + + $data['shipping'] = $this->delivery[$order['delivery']['code']]; + $data['shipping_method'] = $this->ocDelivery[$data['shipping']]; + $data['shipping_code'] = $this->delivery[$order['delivery']['code']]; + + $data['payment'] = $this->payment[$order['paymentType']]; + $data['payment_method'] = $this->ocPayment[$data['payment']]; + $data['payment_code'] = $this->payment[$order['paymentType']]; + + // this data will not retrive from crm for now + $data['tax'] = ''; + $data['tax_id'] = ''; + $data['product'] = ''; + $data['product_id'] = ''; + $data['reward'] = ''; + $data['affiliate'] = ''; + $data['affiliate_id'] = ''; + $data['payment_tax_id'] = ''; + $data['order_product_id'] = ''; + $data['payment_company'] = ''; + $data['payment_company_id'] = ''; + $data['company'] = ''; + $data['company_id'] = ''; + + $data['order_product'] = array(); + + foreach ($order['items'] as $item) { + //$product = $this->model_catalog_product->getProduct($item['offer']['externalId']); + $productId = $item['offer']['externalId']; + $options = array(); + if(mb_strpos($item['offer']['externalId'], '#') > 1) { + $offer = explode('#', $item['offer']['externalId']); + $productId = $offer[0]; + $optionsFromCRM = explode('_', $offer[1]); + + foreach($optionsFromCRM as $optionFromCRM) { + $optionData = explode('-', $optionFromCRM); + $productOptionId = $optionData[0]; + $optionValueId = $optionData[1]; + + $productOptions = $this->model_catalog_product->getProductOptions($productId); + + foreach($productOptions as $productOption) { + if($productOptionId == $productOption['product_option_id']) { + foreach($productOption['product_option_value'] as $productOptionValue) { + if($productOptionValue['option_value_id'] == $optionValueId) { + $options[$productOptionId] = $productOptionValue['product_option_value_id']; + } + } + } + } + } + } + $data['order_product'][] = array( + 'product_id' => $productId, + 'quantity' => $item['quantity'], + 'option' => $options + ); + } + + $deliveryCost = !empty($order['delivery']['cost']) ? $order['delivery']['cost'] : 0; + + $data['order_total'] = array( + array( + 'order_total_id' => '', + 'code' => 'sub_total', + 'title' => $this->language->get('product_summ'), + 'value' => $order['summ'], + 'text' => $order['summ'], + 'sort_order' => $this->subtotalSettings['sub_total_sort_order'] + ), + array( + 'order_total_id' => '', + 'code' => 'shipping', + 'title' => $this->ocDelivery[$data['shipping_code']], + 'value' => $deliveryCost, + 'text' => $deliveryCost, + 'sort_order' => $this->shippingSettings['shipping_sort_order'] + ), + array( + 'order_total_id' => '', + 'code' => 'total', + 'title' => $this->language->get('column_total'), + 'value' => isset($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $deliveryCost, + 'text' => isset($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $deliveryCost, + 'sort_order' => $this->totalSettings['total_sort_order'] + ) + ); + + $data['fromApi'] = true; + + if (array_key_exists($order['status'], $this->status)) { + $data['order_status_id'] = $this->status[$order['status']]; + } else { + $tmpOrder = $this->model_sale_order->getOrder($order['externalId']); + $data['order_status_id'] = $tmpOrder['order_status_id']; + } + + $this->opencartApiClient->editOrder($order['externalId'], $data); + } + } + + protected function createOrders($orders) + { + $customersIdsFix = array(); + $ordersIdsFix = array(); + + foreach ($orders as $order) { + $store = $this->config->get('config_store_id'); + + $customer_id = (!empty($order['customer']['externalId'])) + ? $order['customer']['externalId'] + : 0; + + $data = array(); + + if ($customer_id == 0) { + $cData = array( + 'store_id' => 0, + 'customer_group_id' => '1', + 'firstname' => $order['firstName'], + 'lastname' => (!empty($order['lastName'])) ? $order['lastName'] : ' ', + 'email' => $order['email'], + 'telephone' => (!empty($order['customer']['phones'][0]['number']) ) ? $order['customer']['phones'][0]['number'] : ' ', + 'fax' => '', + 'newsletter' => 0, + 'password' => 'tmppass', + 'status' => 1, + 'address' => array( + array( + 'firstname' => $order['firstName'], + 'lastname' => (!empty($order['lastName'])) ? $order['lastName'] : ' ', + 'address_1' => $order['customer']['address']['text'], + 'address_2' => ' ', + 'city' => !empty($order['customer']['address']['city']) ? $order['customer']['address']['city'] : $order['delivery']['address']['city'], + 'postcode' => isset($order['customer']['address']['index']) ? $order['customer']['address']['index'] : $order['delivery']['address']['index'], + 'tax_id' => '1', + 'company' => '', + 'company_id' => '', + 'zone_id' => '0', + 'country_id' => 0 + ) + ), + ); + + + $this->model_customer_customer->addCustomer($cData); + + if (!empty($order['email'])) { + $tryToFind = $this->model_customer_customer->getCustomerByEmail($order['email']); + $customer_id = $tryToFind['customer_id']; + } else { + $last = $this->model_customer_customer->getCustomers($data = array('order' => 'DESC', 'limit' => 1)); + $customer_id = $last[0]['customer_id']; + } + + $customersIdsFix[] = array('id' => $order['customer']['id'], 'externalId' => (int)$customer_id); + } + + $data['store_id'] = $store == null ? 0 : $store; + $data['customer'] = $order['firstName']; + $data['customer_id'] = $customer_id; + $data['customer_group_id'] = 1; + $data['firstname'] = $order['firstName']; + $data['lastname'] = (!empty($order['lastName'])) ? $order['lastName'] : ' '; + $data['email'] = $order['email']; + $data['telephone'] = (!empty($order['customer']['phones'][0]['number'])) ? $order['customer']['phones'][0]['number'] : ' '; + $data['comment'] = !empty($order['customerComment']) ? $order['customerComment'] : ''; + $data['fax'] = ''; + $data['payment_address'] = '0'; + $data['payment_firstname'] = $order['firstName']; + $data['payment_lastname'] = (!empty($order['lastName'])) ? $order['lastName'] : ' '; + $data['payment_address_1'] = $order['customer']['address']['text']; + $data['payment_address_2'] = ''; + $data['payment_company'] = ''; + $data['payment_company_id'] = ''; + $data['payment_city'] = !empty($order['customer']['address']['city']) ? $order['customer']['address']['city'] : $order['delivery']['address']['city']; + $data['payment_postcode'] = !empty($order['customer']['address']['index']) ? $order['customer']['address']['index'] : $order['delivery']['address']['index']; + + $region = ''; + + if (!empty($order['delivery']['address']['region']) && is_int($order['delivery']['address']['region'])) { + $region = $order['delivery']['address']['region']; + } else { + foreach ($this->zones as $zone) { + if ($order['delivery']['address']['region'] == $zone['name']) { + $region = $zone['zone_id']; + } + } + } + + $data['payment_country_id'] = !empty($order['delivery']['address']['country']) ? $order['delivery']['address']['country'] : 0; + $data['payment_zone_id'] = !empty($order['delivery']['address']['region']) ? $order['delivery']['address']['region'] : $region; + $data['shipping_country_id'] = !empty($order['delivery']['address']['country']) ? $order['delivery']['address']['country'] : 0; + $data['shipping_zone_id'] = $region; + $data['shipping_address'] = '0'; + $data['shipping_firstname'] = $order['firstName']; + $data['shipping_lastname'] = (!empty($order['lastName'])) ? $order['lastName'] : ' '; + $data['shipping_address_1'] = $order['delivery']['address']['text']; + $data['shipping_address_2'] = ''; + $data['shipping_company'] = ''; + $data['shipping_company_id'] = ''; + $data['shipping_city'] = $order['delivery']['address']['city']; + $data['shipping_postcode'] = $order['delivery']['address']['index']; + + $data['shipping'] = $this->delivery[$order['delivery']['code']]; + $data['shipping_method'] = $this->ocDelivery[$data['shipping']]; + $data['shipping_code'] = $this->delivery[$order['delivery']['code']]; + $data['payment'] = $this->payment[$order['paymentType']]; + $data['payment_method'] = $this->ocPayment[$data['payment']]; + $data['payment_code'] = $this->payment[$order['paymentType']]; + + // this data will not retrive from crm for now + $data['tax'] = ''; + $data['tax_id'] = ''; + $data['product'] = ''; + $data['product_id'] = ''; + $data['reward'] = ''; + $data['affiliate'] = ''; + $data['affiliate_id'] = ''; + $data['payment_tax_id'] = ''; + $data['order_product_id'] = ''; + $data['payment_company'] = ''; + $data['payment_company_id'] = ''; + $data['company'] = ''; + $data['company_id'] = ''; + + $data['order_product'] = array(); + + foreach ($order['items'] as $item) { + $product = $this->model_catalog_product->getProduct($item['offer']['externalId']); + $data['order_product'][] = array( + 'product_id' => $item['offer']['externalId'], + 'name' => $item['offer']['name'], + 'quantity' => $item['quantity'], + 'price' => $item['initialPrice'], + 'total' => $item['initialPrice'] * $item['quantity'], + 'model' => $product['model'], + + // this data will not retrive from crm + 'order_product_id' => '', + 'tax' => 0, + 'reward' => 0 + ); + } + + $deliveryCost = !empty($order['delivery']['cost']) ? $order['delivery']['cost'] : 0; + + $data['order_total'] = array( + array( + 'order_total_id' => '', + 'code' => 'sub_total', + 'title' => $this->language->get('product_summ'), + 'value' => $order['summ'], + 'text' => $order['summ'], + 'sort_order' => $this->subtotalSettings['sub_total_sort_order'] + ), + array( + 'order_total_id' => '', + 'code' => 'shipping', + 'title' => $this->ocDelivery[$data['shipping_code']], + 'value' => $deliveryCost, + 'text' => $deliveryCost, + 'sort_order' => $this->shippingSettings['shipping_sort_order'] + ), + array( + 'order_total_id' => '', + 'code' => 'total', + 'title' => $this->language->get('column_total'), + 'value' => !empty($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $deliveryCost, + 'text' => isset($order['totalSumm']) ? $order['totalSumm'] : $order['summ'] + $deliveryCost, + 'sort_order' => $this->totalSettings['total_sort_order'] + ) + ); + + $data['fromApi'] = true; + $data['order_status_id'] = 1; + + $this->opencartApiClient->addOrder($data); + + $last = $this->model_sale_order->getOrders($data = array('order' => 'DESC', 'limit' => 1, 'start' => 0)); + + $ordersIdsFix[] = array('id' => $order['id'], 'externalId' => (int) $last[0]['order_id']); + } + + return array('customers' => $customersIdsFix, 'orders' => $ordersIdsFix); + } +} diff --git a/admin/model/extension/retailcrm/icml.php b/admin/model/extension/retailcrm/icml.php new file mode 100644 index 0000000..f2f3d47 --- /dev/null +++ b/admin/model/extension/retailcrm/icml.php @@ -0,0 +1,336 @@ +load->language('extension/module/retailcrm'); + $this->load->model('catalog/category'); + $this->load->model('catalog/product'); + $this->load->model('catalog/option'); + $this->load->model('catalog/manufacturer'); + + $string = ' + + + '.$this->config->get('config_name').' + + + + + '; + + $xml = new SimpleXMLElement( + $string, + LIBXML_NOENT |LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_PARSEHUGE + ); + + $this->dd = new DOMDocument(); + $this->dd->preserveWhiteSpace = false; + $this->dd->formatOutput = true; + $this->dd->loadXML($xml->asXML()); + + $this->eCategories = $this->dd + ->getElementsByTagName('categories')->item(0); + $this->eOffers = $this->dd + ->getElementsByTagName('offers')->item(0); + + $this->addCategories(); + $this->addOffers(); + + $this->dd->saveXML(); + + $downloadPath = DIR_SYSTEM . '/../'; + + if (!file_exists($downloadPath)) { + mkdir($downloadPath, 0755); + } + + $this->dd->save($downloadPath . 'retailcrm.xml'); + } + + /** + * + */ + private function addCategories() + { + $categories = $this->model_catalog_category->getCategories(array()); + foreach($categories as $category) { + $category = $this->model_catalog_category->getCategory($category['category_id']); + + $e = $this->eCategories->appendChild( + $this->dd->createElement( + 'category', $category['name'] + ) + ); + + $e->setAttribute('id', $category['category_id']); + + if ($category['parent_id'] > 0) { + $e->setAttribute('parentId', $category['parent_id']); + } + } + + } + + private function addOffers() + { + $offerManufacturers = array(); + + $manufacturers = $this->model_catalog_manufacturer + ->getManufacturers(array()); + + foreach ($manufacturers as $manufacturer) { + $offerManufacturers[ + $manufacturer['manufacturer_id'] + ] = $manufacturer['name']; + } + + $products = $this->model_catalog_product->getProducts(array()); + + foreach ($products as $product) { + // Формируем офферы отнсительно доступных опций + $options = $this->model_catalog_product->getProductOptions($product['product_id']); + $offerOptions = array('select', 'radio'); + $requiredOptions = array(); + $notRequiredOptions = array(); + // Оставляем опции связанные с вариациями товаров, сортируем по параметру обязательный или нет + foreach($options as $option) { + if(in_array($option['type'], $offerOptions)) { + if($option['required']) { + $requiredOptions[] = $option; + } else { + $notRequiredOptions[] = $option; + } + } + } + $offers = array(); + // Сначала совмещаем все обязательные опции + foreach($requiredOptions as $requiredOption) { + // Если первая итерация + if(empty($offers)) { + foreach($requiredOption['product_option_value'] as $optionValue) { + $offers[$requiredOption['product_option_id'].':'.$requiredOption['option_id'].'-'.$optionValue['option_value_id']] = (float)$optionValue['price']; + } + } else { + foreach($offers as $optionKey => $optionCost) { + unset($offers[$optionKey]); // Работая в контексте обязательных опций не забываем удалять прошлые обязательные опции, т.к. они должны быть скомбинированы с другими обязательными опциями + foreach($requiredOption['product_option_value'] as $optionValue) { + $offers[$optionKey.'_'.$requiredOption['product_option_id'].':'.$requiredOption['option_id'].'-'.$optionValue['option_value_id']] = $optionCost + (float)$optionValue['price']; + } + } + } + } + // Совмещаем или добавляем необязательные опции, учитывая тот факт что обязательных опций может и не быть. + foreach($notRequiredOptions as $notRequiredOption) { + // Если обязательных опцией не оказалось и первая итерация + if(empty($offers)) { + $offers['0:0-0'] = 0; // В случае работы с необязательными опциями мы должны учитывать товарное предложение без опций, поэтому создадим "пустую" опцию + foreach($notRequiredOption['product_option_value'] as $optionValue) { + $offers[$notRequiredOption['product_option_id'].':'.$notRequiredOption['option_id'].'-'.$optionValue['option_value_id']] = (float)$optionValue['price']; + } + } else { + foreach($offers as $optionKey => $optionCost) { + foreach($notRequiredOption['product_option_value'] as $optionValue) { + $offers[$optionKey.'_'.$notRequiredOption['product_option_id'].':'.$notRequiredOption['option_id'].'-'.$optionValue['option_value_id']] = $optionCost + (float)$optionValue['price']; + } + } + } + } + if(empty($offers)) { + $offers = array('0:0-0' => '0'); + } + + foreach($offers as $optionsString => $optionsTotalCost) { + $optionsString = explode('_', $optionsString); + $options = array(); + foreach($optionsString as $optionString) { + $option = explode('-', $optionString); + $optionIds = explode(':', $option[0]); + if($optionString != '0:0-0') { + $optionData = $this->getOptionData($optionIds[1], $option[1]); + $options[$optionIds[0]] = array( + 'name' => $optionData['optionName'], + 'value' => $optionData['optionValue'], + 'value_id' => $option[1] + ); + } + } + ksort($options); + $offerId = array(); + foreach($options as $optionKey => $optionData) { + $offerId[] = $optionKey.'-'.$optionData['value_id']; + } + $offerId = implode('_', $offerId); + $e = $this->eOffers->appendChild($this->dd->createElement('offer')); + if(!empty($offerId)) + $e->setAttribute('id', $product['product_id'].'#'.$offerId); + else + $e->setAttribute('id', $product['product_id']); + $e->setAttribute('productId', $product['product_id']); + $e->setAttribute('quantity', $product['quantity']); + /** + * Offer activity + */ + $activity = $product['status'] == 1 ? 'Y' : 'N'; + $e->appendChild( + $this->dd->createElement('productActivity') + )->appendChild( + $this->dd->createTextNode($activity) + ); + /** + * Offer categories + */ + $categories = $this->model_catalog_product + ->getProductCategories($product['product_id']); + if (!empty($categories)) { + foreach ($categories as $category) { + $e->appendChild($this->dd->createElement('categoryId')) + ->appendChild( + $this->dd->createTextNode($category) + ); + } + } + /** + * Name & price + */ + $e->appendChild($this->dd->createElement('productName')) + ->appendChild($this->dd->createTextNode($product['name'])); + if(!empty($options)) { + $optionsString = array(); + foreach($options as $option) { + $optionsString[] = $option['name'].': '.$option['value']; + } + $optionsString = ' ('.implode(', ', $optionsString).')'; + $e->appendChild($this->dd->createElement('name')) + ->appendChild($this->dd->createTextNode($product['name'].$optionsString)); + } else { + $e->appendChild($this->dd->createElement('name')) + ->appendChild($this->dd->createTextNode($product['name'])); + } + $e->appendChild($this->dd->createElement('price')) + ->appendChild($this->dd->createTextNode($product['price'] + $optionsTotalCost)); + /** + * Vendor + */ + if ($product['manufacturer_id'] != 0) { + $e->appendChild($this->dd->createElement('vendor')) + ->appendChild( + $this->dd->createTextNode( + $offerManufacturers[$product['manufacturer_id']] + ) + ); + } + /** + * Image + */ + if ($product['image']) { + $image = $this->generateImage($product['image']); + $e->appendChild($this->dd->createElement('picture')) + ->appendChild($this->dd->createTextNode($image)); + } + /** + * Url + */ + $this->url = new Url( + HTTP_CATALOG, + $this->config->get('config_secure') + ? HTTP_CATALOG + : HTTPS_CATALOG + ); + $e->appendChild($this->dd->createElement('url')) + ->appendChild( + $this->dd->createTextNode( + $this->url->link( + 'product/product&product_id=' . $product['product_id'] + ) + ) + ); + // Options + if(!empty($options)) { + foreach($options as $optionKey => $optionData) { + $param = $this->dd->createElement('param'); + $param->setAttribute('code', $optionKey); + $param->setAttribute('name', $optionData['name']); + $param->appendChild($this->dd->createTextNode($optionData['value'])); + $e->appendChild($param); + } + } + if ($product['sku']) { + $sku = $this->dd->createElement('param'); + $sku->setAttribute('code', 'article'); + $sku->setAttribute('name', $this->language->get('article')); + $sku->appendChild($this->dd->createTextNode($product['sku'])); + $e->appendChild($sku); + } + if ($product['weight'] != '') { + $weight = $this->dd->createElement('param'); + $weight->setAttribute('code', 'weight'); + $weight->setAttribute('name', $this->language->get('weight')); + $weightValue = (isset($offer['weight_class'])) + ? round($product['weight'], 3) . ' ' . $product['weight_class'] + : round($product['weight'], 3) + ; + $weight->appendChild($this->dd->createTextNode($weightValue)); + $e->appendChild($weight); + } + } + } + } + + /** + * @param $image + * @return mixed + */ + private function generateImage($image) + { + $this->load->model('tool/image'); + + $currentTheme = $this->config->get('config_theme'); + $width = $this->config->get($currentTheme . '_image_related_width') ? $this->config->get($currentTheme . '_image_related_width') : 200; + $height = $this->config->get($currentTheme . '_image_related_height') ? $this->config->get($currentTheme . '_image_related_height') : 200; + + return $this->model_tool_image->resize( + $image, + $width, + $height + ); + + + return $this->model_tool_image->resize( + $image, + $this->config->get('config_image_product_width'), + $this->config->get('config_image_product_height') + ); + } + + private function getOptionData($optionId, $optionValueId) { + if(!empty($this->options[$optionId])) { + $option = $this->options[$optionId]; + } else { + $option = $this->model_catalog_option->getOption($optionId); + $this->options[$optionId] = $option; + } + if(!empty($this->optionValues[$optionValueId])) { + $optionValue = $this->optionValues[$optionValueId]; + } else { + $optionValue = $this->model_catalog_option->getOptionValue($optionValueId); + $this->optionValues[$optionValueId] = $optionValue; + } + return array( + 'optionName' => $option['name'], + 'optionValue' => $optionValue['name'] + ); + } +} diff --git a/admin/model/extension/retailcrm/order.php b/admin/model/extension/retailcrm/order.php new file mode 100644 index 0000000..77fa54d --- /dev/null +++ b/admin/model/extension/retailcrm/order.php @@ -0,0 +1,116 @@ +load->model('catalog/product'); + + $this->load->model('setting/setting'); + $this->settings = $this->model_setting_setting->getSetting('retailcrm'); + + $ordersToCrm = array(); + + foreach($orders as $order) { + $ordersToCrm[] = $this->process($order); + } + + $chunkedOrders = array_chunk($ordersToCrm, 50); + + foreach($chunkedOrders as $ordersPart) { + $this->retailcrmApi->ordersUpload($ordersPart); + } + } + + private function process($order_data) { + $order = array(); + + $payment_code = $order_data['payment_code']; + $delivery_code = $order_data['shipping_code']; + + $order['externalId'] = $order_data['order_id']; + $order['firstName'] = $order_data['firstname']; + $order['lastName'] = $order_data['lastname']; + $order['phone'] = $order_data['telephone']; + $order['customerComment'] = $order_data['comment']; + + if(!empty($order_data['email'])) { + $order['email'] = $order_data['email']; + } + + $order['customer']['externalId'] = $order_data['customer_id']; + + $deliveryCost = 0; + $orderTotals = isset($order_data['totals']) ? $order_data['totals'] : $order_data['order_total'] ; + + foreach ($orderTotals as $totals) { + if ($totals['code'] == 'shipping') { + $deliveryCost = $totals['value']; + } + } + + $order['createdAt'] = $order_data['date_added']; + $order['paymentType'] = $this->settings['retailcrm_payment'][$payment_code]; + + $country = (isset($order_data['shipping_country'])) ? $order_data['shipping_country'] : '' ; + + $order['delivery'] = array( + 'code' => !empty($delivery_code) ? $this->settings['retailcrm_delivery'][$delivery_code] : '', + 'cost' => $deliveryCost, + 'address' => array( + 'index' => $order_data['shipping_postcode'], + 'city' => $order_data['shipping_city'], + 'country' => $order_data['shipping_country_id'], + 'region' => $order_data['shipping_zone_id'], + 'text' => implode(', ', array( + $order_data['shipping_postcode'], + $country, + $order_data['shipping_city'], + $order_data['shipping_address_1'], + $order_data['shipping_address_2'] + )) + ) + ); + + $orderProducts = isset($order_data['products']) ? $order_data['products'] : $order_data['order_product']; + $offerOptions = array('select', 'radio'); + + foreach ($orderProducts as $product) { + $offerId = ''; + + if(!empty($product['option'])) { + $options = array(); + + $productOptions = $this->model_catalog_product->getProductOptions($product['product_id']); + + foreach($product['option'] as $option) { + if(!in_array($option['type'], $offerOptions)) continue; + foreach($productOptions as $productOption) { + if($productOption['product_option_id'] = $option['product_option_id']) { + foreach($productOption['product_option_value'] as $productOptionValue) { + if($productOptionValue['product_option_value_id'] == $option['product_option_value_id']) { + $options[$option['product_option_id']] = $productOptionValue['option_value_id']; + } + } + } + } + } + + ksort($options); + + $offerId = array(); + foreach($options as $optionKey => $optionValue) { + $offerId[] = $optionKey.'-'.$optionValue; + } + $offerId = implode('_', $offerId); + } + + $order['items'][] = array( + 'productId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id'], + 'productName' => $product['name'], + 'initialPrice' => $product['price'], + 'quantity' => $product['quantity'], + ); + } + + return $order; + } +} diff --git a/admin/model/extension/retailcrm/references.php b/admin/model/extension/retailcrm/references.php new file mode 100644 index 0000000..b764c55 --- /dev/null +++ b/admin/model/extension/retailcrm/references.php @@ -0,0 +1,138 @@ + $this->getOpercartDeliveryTypes(), + 'retailcrm' => $this->getApiDeliveryTypes() + ); + } + + public function getOrderStatuses() + { + return array( + 'opencart' => $this->getOpercartOrderStatuses(), + 'retailcrm' => $this->getApiOrderStatuses() + ); + } + + public function getPaymentTypes() + { + return array( + 'opencart' => $this->getOpercartPaymentTypes(), + 'retailcrm' => $this->getApiPaymentTypes() + ); + } + + public function getOpercartDeliveryTypes() + { + $deliveryMethods = array(); + $files = glob(DIR_APPLICATION . 'controller/extension/shipping/*.php'); + + if ($files) { + foreach ($files as $file) { + $extension = basename($file, '.php'); + + $this->load->language('extension/shipping/' . $extension); + + if ($this->config->get($extension . '_status')) { + $deliveryMethods[$extension.'.'.$extension] = strip_tags( + $this->language->get('heading_title') + ); + } + } + } + + return $deliveryMethods; + } + + public function getOpercartOrderStatuses() + { + $this->load->model('localisation/order_status'); + + return $this->model_localisation_order_status + ->getOrderStatuses(array()); + } + + public function getOpercartPaymentTypes() + { + $paymentTypes = array(); + $files = glob(DIR_APPLICATION . 'controller/extension/payment/*.php'); + + if ($files) { + foreach ($files as $file) { + $extension = basename($file, '.php'); + + $this->load->language('extension/payment/' . $extension); + + if ($this->config->get($extension . '_status')) { + $paymentTypes[$extension] = strip_tags( + $this->language->get('heading_title') + ); + } + } + } + + return $paymentTypes; + } + + public function getApiDeliveryTypes() + { + $this->load->model('setting/setting'); + $settings = $this->model_setting_setting->getSetting('retailcrm'); + + if(!empty($settings['retailcrm_url']) && !empty($settings['retailcrm_apikey'])) { + $this->retailcrm = new RetailcrmProxy( + $settings['retailcrm_url'], + $settings['retailcrm_apikey'], + DIR_SYSTEM . 'storage/logs/retailcrm.log' + ); + + $response = $this->retailcrm->deliveryTypesList(); + + return ($response === false) ? array() : $response->deliveryTypes; + } + } + + public function getApiOrderStatuses() + { + $this->load->model('setting/setting'); + $settings = $this->model_setting_setting->getSetting('retailcrm'); + + if(!empty($settings['retailcrm_url']) && !empty($settings['retailcrm_apikey'])) { + $this->retailcrm = new RetailcrmProxy( + $settings['retailcrm_url'], + $settings['retailcrm_apikey'], + DIR_SYSTEM . 'storage/logs/retailcrm.log' + ); + + $response = $this->retailcrm->statusesList(); + + return ($response === false) ? array() : $response->statuses; + } + } + + public function getApiPaymentTypes() + { + $this->load->model('setting/setting'); + $settings = $this->model_setting_setting->getSetting('retailcrm'); + + if(!empty($settings['retailcrm_url']) && !empty($settings['retailcrm_apikey'])) { + $this->retailcrm = new RetailcrmProxy( + $settings['retailcrm_url'], + $settings['retailcrm_apikey'], + DIR_SYSTEM . 'storage/logs/retailcrm.log' + ); + + $response = $this->retailcrm->paymentTypesList(); + + return ($response === false) ? array() : $response->paymentTypes; + } + } +} diff --git a/admin/view/template/extension/module/retailcrm.tpl b/admin/view/template/extension/module/retailcrm.tpl new file mode 100644 index 0000000..144f68b --- /dev/null +++ b/admin/view/template/extension/module/retailcrm.tpl @@ -0,0 +1,110 @@ + + + +
+ +
+ +
+ + +
+ + + + + + +
+
+
+ + +

+
+
+ +
+
+
+ +
+ + + + + +
+ + +

+ +

+ $value): ?> +
+ + +
+ + +

+ + +
+ + +
+ + +

+ $value): ?> +
+ + +
+ + + + + +
+
+
+
+
+ + diff --git a/catalog/controller/extension/module/retailcrm.php b/catalog/controller/extension/module/retailcrm.php new file mode 100644 index 0000000..7b8455d --- /dev/null +++ b/catalog/controller/extension/module/retailcrm.php @@ -0,0 +1,108 @@ + + * @license https://opensource.org/licenses/MIT MIT License + * @link http://www.retailcrm.ru/docs/Developers/ApiVersion3 + */ +class ControllerExtensionModuleRetailcrm extends Controller +{ + /** + * Create order on event + * + * @param int $order_id order identificator + * + * @return void + */ + public function order_create($parameter1, $parameter2 = null, $parameter3 = null) + { + $this->load->model('checkout/order'); + $this->load->model('account/order'); + + $order_id = $parameter3; + + $data = $this->model_checkout_order->getOrder($order_id); + + $data['products'] = $this->model_account_order->getOrderProducts($order_id); + foreach($data['products'] as $key => $product) { + $productOptions = $this->model_account_order->getOrderOptions($order_id, $product['order_product_id']); + + if(!empty($productOptions)) + $data['products'][$key]['option'] = $productOptions; + } + + if (!isset($data['fromApi'])) { + $this->load->model('setting/setting'); + $status = $this->model_setting_setting->getSetting('retailcrm'); + if ($data['order_status_id'] > 0) { + $data['order_status'] = $status['retailcrm_status'][$data['order_status_id']]; + } + + $data['totals'][] = array( + 'code' => 'shipping', + 'value' => $this->session->data['shipping_method']['cost'] + ); + + $this->load->model('extension/retailcrm/order'); + $this->model_extension_retailcrm_order->sendToCrm($data, $data['order_id']); + } + } + + public function order_edit($parameter1, $parameter2 = null) { + $order_id = $parameter2[0]; + + $this->load->model('checkout/order'); + $this->load->model('account/order'); + + $data = $this->model_checkout_order->getOrder($order_id); + + if($data['order_status_id'] == 0) return; + + $data['products'] = $this->model_account_order->getOrderProducts($order_id); + + foreach($data['products'] as $key => $product) { + $productOptions = $this->model_account_order->getOrderOptions($order_id, $product['order_product_id']); + + if(!empty($productOptions)) + $data['products'][$key]['option'] = $productOptions; + } + + if (!isset($data['fromApi'])) { + $this->load->model('setting/setting'); + $status = $this->model_setting_setting->getSetting('retailcrm'); + + if ($data['order_status_id'] > 0) { + $data['order_status'] = $status['retailcrm_status'][$data['order_status_id']]; + } + + $data['totals'][] = array( + 'code' => 'shipping', + 'value' => isset($this->session->data['shipping_method']) ? $this->session->data['shipping_method']['cost'] : '' + ); + + $this->load->model('extension/retailcrm/order'); + $this->model_extension_retailcrm_order->changeInCrm($data, $data['order_id']); + } + } + + /** + * Create customer on event + * + * @param int $customerId customer identificator + * + * @return void + */ + public function customer_create($parameter1, $parameter2 = null, $parameter3 = null) { + $customerId = $parameter3; + + $this->load->model('account/customer'); + $customer = $this->model_account_customer->getCustomer($customerId); + + $this->load->model('extension/retailcrm/customer'); + $this->model_extension_retailcrm_customer->sendToCrm($customer); + } +} diff --git a/catalog/model/extension/retailcrm/customer.php b/catalog/model/extension/retailcrm/customer.php new file mode 100644 index 0000000..1b1f768 --- /dev/null +++ b/catalog/model/extension/retailcrm/customer.php @@ -0,0 +1,42 @@ +load->model('setting/setting'); + $settings = $this->model_setting_setting->getSetting('retailcrm'); + + if(empty($customer)) + return false; + if(empty($settings['retailcrm_url']) || empty($settings['retailcrm_apikey'])) + return false; + + require_once DIR_SYSTEM . 'library/retailcrm/bootstrap.php'; + + $this->retailcrmApi = new RetailcrmProxy( + $settings['retailcrm_url'], + $settings['retailcrm_apikey'], + DIR_SYSTEM . 'storage/logs/retailcrm.log' + ); + + $customerToCrm = $this->process($customer); + + $this->retailcrmApi->customersCreate($customerToCrm); + } + + private function process($customer) { + $customerToCrm = array( + 'externalId' => $customer['customer_id'], + 'firstName' => $customer['firstname'], + 'lastName' => $customer['lastname'], + 'email' => $customer['email'], + 'phones' => array( + array( + 'number' => $customer['telephone'] + ) + ), + 'createdAt' => $customer['date_added'] + ); + + return $customerToCrm; + } +} diff --git a/catalog/model/extension/retailcrm/order.php b/catalog/model/extension/retailcrm/order.php new file mode 100644 index 0000000..873d2ff --- /dev/null +++ b/catalog/model/extension/retailcrm/order.php @@ -0,0 +1,262 @@ +request->post['fromApi'])) return; + + $this->load->model('setting/setting'); + $settings = $this->model_setting_setting->getSetting('retailcrm'); + + if(!empty($settings['retailcrm_url']) && !empty($settings['retailcrm_apikey'])) { + $this->load->model('catalog/product'); + + require_once DIR_SYSTEM . 'library/retailcrm/bootstrap.php'; + + $this->retailcrm = new RetailcrmProxy( + $settings['retailcrm_url'], + $settings['retailcrm_apikey'], + DIR_SYSTEM . 'storage/logs/retailcrm.log' + ); + + $order = array(); + + $customers = $this->retailcrm->customersList( + array( + 'name' => $order_data['telephone'], + 'email' => $order_data['email'] + ), + 1, + 100 + ); + + if($customers) { + foreach ($customers['customers'] as $customer) { + $order['customer']['id'] = $customer['id']; + } + } + + unset($customers); + + $order['externalId'] = $order_id; + $order['firstName'] = $order_data['firstname']; + $order['lastName'] = $order_data['lastname']; + $order['phone'] = $order_data['telephone']; + $order['customerComment'] = $order_data['comment']; + + if(!empty($order_data['email'])) { + $order['email'] = $order_data['email']; + } + + $deliveryCost = 0; + $altTotals = isset($order_data['order_total']) ? $order_data['order_total'] : ""; + $orderTotals = isset($order_data['totals']) ? $order_data['totals'] : $altTotals ; + + if (!empty($orderTotals)) { + foreach ($orderTotals as $totals) { + if ($totals['code'] == 'shipping') { + $deliveryCost = $totals['value']; + } + } + } + + $order['createdAt'] = $order_data['date_added']; + + $payment_code = $order_data['payment_code']; + $order['paymentType'] = $settings['retailcrm_payment'][$payment_code]; + + if(!isset($order_data['shipping_iso_code_2']) && isset($order_data['shipping_country_id'])) { + $this->load->model('localisation/country'); + $shipping_country = $this->model_localisation_country->getCountry($order_data['shipping_country_id']); + $order_data['shipping_iso_code_2'] = $shipping_country['iso_code_2']; + } + + $delivery_code = $order_data['shipping_code']; + $order['delivery'] = array( + 'code' => !empty($delivery_code) ? $settings['retailcrm_delivery'][$delivery_code] : '', + 'cost' => $deliveryCost, + 'address' => array( + 'index' => $order_data['shipping_postcode'], + 'city' => $order_data['shipping_city'], + 'countryIso' => $order_data['shipping_iso_code_2'], + 'region' => $order_data['shipping_zone'], + 'text' => implode(', ', array( + $order_data['shipping_postcode'], + (isset($order_data['shipping_country'])) ? $order_data['shipping_country'] : '', + $order_data['shipping_city'], + $order_data['shipping_address_1'], + $order_data['shipping_address_2'] + )) + ) + ); + + $orderProducts = isset($order_data['products']) ? $order_data['products'] : $order_data['order_product']; + $offerOptions = array('select', 'radio'); + + foreach ($orderProducts as $product) { + $offerId = ''; + + if(!empty($product['option'])) { + $options = array(); + + $productOptions = $this->model_catalog_product->getProductOptions($product['product_id']); + + foreach($product['option'] as $option) { + if(!in_array($option['type'], $offerOptions)) continue; + foreach($productOptions as $productOption) { + if($productOption['product_option_id'] = $option['product_option_id']) { + foreach($productOption['product_option_value'] as $productOptionValue) { + if($productOptionValue['product_option_value_id'] == $option['product_option_value_id']) { + $options[$option['product_option_id']] = $productOptionValue['option_value_id']; + } + } + } + } + } + + ksort($options); + + $offerId = array(); + foreach($options as $optionKey => $optionValue) { + $offerId[] = $optionKey.'-'.$optionValue; + } + $offerId = implode('_', $offerId); + } + + $order['items'][] = array( + 'offer' => array( + 'externalId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id'] + ), + 'productName' => $product['name'], + 'initialPrice' => $product['price'], + 'quantity' => $product['quantity'], + ); + } + + if (isset($order_data['order_status_id']) && $order_data['order_status_id'] > 0) { + $order['status'] = $settings['retailcrm_status'][$order_data['order_status_id']]; + } + + $this->retailcrm->ordersCreate($order); + } + } + + public function changeInCrm($order_data, $order_id) + { + if(isset($this->request->post['fromApi'])) return; + + $this->load->model('setting/setting'); + $settings = $this->model_setting_setting->getSetting('retailcrm'); + + if(!empty($settings['retailcrm_url']) && !empty($settings['retailcrm_apikey'])) { + $this->load->model('catalog/product'); + + require_once DIR_SYSTEM . 'library/retailcrm/bootstrap.php'; + + $this->retailcrm = new RetailcrmProxy( + $settings['retailcrm_url'], + $settings['retailcrm_apikey'], + DIR_SYSTEM . 'storage/logs/retailcrm.log' + ); + + $order = array(); + + $payment_code = $order_data['payment_code']; + $delivery_code = $order_data['shipping_code']; + + $order['externalId'] = $order_id; + $order['firstName'] = $order_data['firstname']; + $order['lastName'] = $order_data['lastname']; + $order['phone'] = $order_data['telephone']; + $order['customerComment'] = $order_data['comment']; + + if(!empty($order_data['email'])) { + $order['email'] = $order_data['email']; + } + + $deliveryCost = 0; + $orderTotals = isset($order_data['totals']) ? $order_data['totals'] : $order_data['order_total'] ; + + foreach ($orderTotals as $totals) { + if ($totals['code'] == 'shipping') { + $deliveryCost = $totals['value']; + } + } + + $order['createdAt'] = $order_data['date_added']; + $order['paymentType'] = $settings['retailcrm_payment'][$payment_code]; + + $country = (isset($order_data['shipping_country'])) ? $order_data['shipping_country'] : '' ; + + $order['delivery'] = array( + 'code' => !empty($delivery_code) ? $settings['retailcrm_delivery'][$delivery_code] : '', + 'address' => array( + 'index' => $order_data['shipping_postcode'], + 'city' => $order_data['shipping_city'], + 'country' => $order_data['shipping_country_id'], + 'region' => $order_data['shipping_zone_id'], + 'text' => implode(', ', array( + $order_data['shipping_postcode'], + $country, + $order_data['shipping_city'], + $order_data['shipping_address_1'], + $order_data['shipping_address_2'] + )) + ) + ); + if(!empty($deliveryCost)){ + $order['delivery']['cost'] = $deliveryCost; + } + + $orderProducts = isset($order_data['products']) ? $order_data['products'] : $order_data['order_product']; + $offerOptions = array('select', 'radio'); + + foreach ($orderProducts as $product) { + $offerId = ''; + + if(!empty($product['option'])) { + $options = array(); + + $productOptions = $this->model_catalog_product->getProductOptions($product['product_id']); + + foreach($product['option'] as $option) { + if(!in_array($option['type'], $offerOptions)) continue; + foreach($productOptions as $productOption) { + if($productOption['product_option_id'] = $option['product_option_id']) { + foreach($productOption['product_option_value'] as $productOptionValue) { + if($productOptionValue['product_option_value_id'] == $option['product_option_value_id']) { + $options[$option['product_option_id']] = $productOptionValue['option_value_id']; + } + } + } + } + } + + ksort($options); + + $offerId = array(); + foreach($options as $optionKey => $optionValue) { + $offerId[] = $optionKey.'-'.$optionValue; + } + $offerId = implode('_', $offerId); + } + + $order['items'][] = array( + 'offer' => array( + 'externalId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id'] + ), + 'productName' => $product['name'], + 'initialPrice' => $product['price'], + 'quantity' => $product['quantity'], + ); + } + + if (isset($order_data['order_status_id']) && $order_data['order_status_id'] > 0) { + $order['status'] = $settings['retailcrm_status'][$order_data['order_status_id']]; + } + + $this->retailcrm->ordersEdit($order); + } + } +}