diff --git a/README.md b/README.md index 78b7f5d..efa3e3e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Opencart module =============== -Module allows integrate CMS Opencart with [retailCRM](http://retailcrm.pro) +Module allows integrate CMS Opencart 2.x with [retailCRM](http://retailcrm.pro) #### Features: @@ -23,56 +23,6 @@ cp -r opencart-module/* /path/to/site/root * Fill you api url & api key * Specify directories matching - -#### Export orders to retailCRM (for opencart 1.5.x, for version 2.x this step is unnecessary) - -##### VQmod - -Copy _retailcrm_create_order.xml_ into _/path/to/site/root/vqmod/xml_. - -For VQmod cache renewal you may need to delete files _/path/to/site/root/vqmod/vqcache/vq2-admin_model_sale_order.php_ & _/path/to/site/root/vqmod/vqcache/vq2-catalog_model_checkout_order.php_ - -##### Manual setup - -In the file: - -``` -/catalog/model/checkout/order.php -``` - -add theese lines into addOrder method right before return statement: - -```php -$this->load->model('retailcrm/order'); -$this->model_retailcrm_order->sendToCrm($data, $order_id); -``` - -In the file: - -``` -/admin/model/sale/order.php -``` - -add theese lines into addOrder & editOrder methods right before return statement: - -```php -if (!isset($data['fromApi'])) { - $this->load->model('setting/setting'); - $status = $this->model_setting_setting->getSetting('retailcrm'); - - if (!empty($data['order_status_id'])) { - $data['order_status'] = $status['retailcrm_status'][$data['order_status_id']]; - } - - $this->load->model('retailcrm/order'); - if (isset ($order_query)) { - $this->model_retailcrm_order->changeInCrm($data, $order_id); - } else { - $this->model_retailcrm_order->sendToCrm($data, $order_id); - } -} -``` - #### Getting changes in orders Add to cron: @@ -94,3 +44,8 @@ Your export file will be available by following url ``` http://youropencartsite.com/retailcrm.xml ``` + +#### Export existing orders and customers + +You want to run this command onecly: +/usr/bin/php /path/to/opencart/system/cron/export.php diff --git a/README.ru.md b/README.ru.md index 44a8723..44bc3ef 100644 --- a/README.ru.md +++ b/README.ru.md @@ -1,7 +1,7 @@ Opencart module =============== -Модуль интеграции CMS Openacart c [RetailCRM](http://retailcrm.ru) +Модуль интеграции CMS Openacart 2.x c [RetailCRM](http://retailcrm.ru) #### Модуль позволяет: @@ -26,56 +26,6 @@ cp -r opencart-module/* /path/to/site/root На странице настроек модуля укажите URL Вашей CRM и ключ авторизации, после сохранения этих данных укажите соответствия справочников типов доставок, оплат и статусов заказа. - -#### Выгрузка новых заказов в CRM (для версии opencart 1.5.x.x, для версии 2.0 и старше не требуется) - -##### VQmod - -Скопируйте файл _retailcrm_create_order.xml_ в _/path/to/site/root/vqmod/xml_. - -Для обновления кеша VQmod может потрбоваться удалить файлы _/path/to/site/root/vqmod/vqcache/vq2-admin_model_sale_order.php_ и _/path/to/site/root/vqmod/vqcache/vq2-catalog_model_checkout_order.php_ - -##### Ручная установка - -В файле: - -``` -/catalog/model/checkout/order.php -``` - -Добавьте следующие строки в метод addOrder непосредственно перед языковой конструкцией return: - -```php -$this->load->model('retailcrm/order'); -$this->model_retailcrm_order->sendToCrm($data, $order_id); -``` - -В файле: - -``` -/admin/model/sale/order.php -``` - -Добавьте следующие строки в методы addOrder и editOrder в самом конце каждого метода: - -```php -if (!isset($data['fromApi'])) { - $this->load->model('setting/setting'); - $status = $this->model_setting_setting->getSetting('retailcrm'); - - if (!empty($data['order_status_id'])) { - $data['order_status'] = $status['retailcrm_status'][$data['order_status_id']]; - } - - $this->load->model('retailcrm/order'); - if (isset ($order_query)) { - $this->model_retailcrm_order->changeInCrm($data, $order_id); - } else { - $this->model_retailcrm_order->sendToCrm($data, $order_id); - } -} -``` - #### Получение измений из CRM Для получения изменений и новых данных добавьте в cron следующую запись: @@ -97,3 +47,8 @@ if (!isset($data['fromApi'])) { ``` http://youropencartsite.com/retailcrm.xml ``` + +#### Выгрузка существующих заказов и покупателей + +Запустите команду единожды: +/usr/bin/php /path/to/opencart/system/cron/export.php diff --git a/admin/controller/module/retailcrm.php b/admin/controller/module/retailcrm.php index 3df6c4b..3daf847 100644 --- a/admin/controller/module/retailcrm.php +++ b/admin/controller/module/retailcrm.php @@ -43,6 +43,13 @@ class ControllerModuleRetailcrm extends Controller version_compare(VERSION, '2.2', '>=') ? 'catalog/model/checkout/order/addOrderHistory/after' : 'post.order.history.add', 'module/retailcrm/order_edit' ); + + $this->model_extension_event + ->addEvent( + 'retailcrm', + version_compare(VERSION, '2.2', '>=') ? 'catalog/model/account/customer/addCustomer/after' : 'post.customer.add', + 'module/retailcrm/customer_create' + ); } /** @@ -276,6 +283,44 @@ class ControllerModuleRetailcrm extends Controller } } + /** + * Export orders + * + * + */ + public function export() { + if(version_compare(VERSION, '2.1', '<')) { + $this->load->model('sale/customer'); + $customers = $this->model_sale_customer->getCustomers(); + } else { + $this->load->model('customer/customer'); + $customers = $this->model_customer_customer->getCustomers(); + } + + $this->load->model('retailcrm/customer'); + $this->model_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('retailcrm/order'); + $this->model_retailcrm_order->uploadToCrm($fullOrders); + } + /** * Validate * diff --git a/admin/model/retailcrm/customer.php b/admin/model/retailcrm/customer.php new file mode 100644 index 0000000..a18c6c8 --- /dev/null +++ b/admin/model/retailcrm/customer.php @@ -0,0 +1,51 @@ +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 . '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/retailcrm/history.php b/admin/model/retailcrm/history.php index 0907b06..7dccee0 100644 --- a/admin/model/retailcrm/history.php +++ b/admin/model/retailcrm/history.php @@ -48,7 +48,13 @@ class ModelRetailcrmHistory extends Model ? 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'))))); - $orders = $crm->ordersHistory($lastRun); + $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 = $orders['generatedAt']; $this->subtotalSettings = $this->model_setting_setting->getSetting('sub_total'); @@ -70,7 +76,7 @@ class ModelRetailcrmHistory extends Model $updatedOrders = array(); $newOrders = array(); - foreach ($orders['orders'] as $order) { + foreach ($orders as $order) { if (isset($order['deleted'])) continue; diff --git a/admin/model/retailcrm/order.php b/admin/model/retailcrm/order.php index 2dc90b9..b0c169c 100644 --- a/admin/model/retailcrm/order.php +++ b/admin/model/retailcrm/order.php @@ -1,176 +1,113 @@ load->model('catalog/product'); - public function sendToCrm($order_data, $order_id) - { $this->load->model('setting/setting'); - $settings = $this->model_setting_setting->getSetting('retailcrm'); + $this->settings = $this->model_setting_setting->getSetting('retailcrm'); - if(!empty($settings['retailcrm_url']) && !empty($settings['retailcrm_apikey'])) { - require_once DIR_SYSTEM . 'library/retailcrm/bootstrap.php'; + $ordersToCrm = array(); - $this->retailcrm = new RetailcrmProxy( - $settings['retailcrm_url'], - $settings['retailcrm_apikey'], - DIR_SYSTEM . 'logs/retailcrm.log' - ); + foreach($orders as $order) { + $ordersToCrm[] = $this->process($order); + } - $order = array(); + $chunkedOrders = array_chunk($ordersToCrm, 50); - $customers = $this->retailcrm->customersList( - array( - 'name' => $order_data['telephone'], - 'email' => $order_data['email'] - ), - 1, - 100 - ); + foreach($chunkedOrders as $ordersPart) { + $this->retailcrmApi->ordersUpload($ordersPart); + } + } - foreach($customers['customers'] as $customer) { - $order['customer']['id'] = $customer['id']; + 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['email'] = $order_data['email']; + $order['phone'] = $order_data['telephone']; + $order['customerComment'] = $order_data['comment']; + + $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']; } + } - unset($customers); + $order['createdAt'] = $order_data['date_added']; + $order['paymentType'] = $this->settings['retailcrm_payment'][$payment_code]; - $order['externalId'] = $order_id; - $order['firstName'] = $order_data['firstname']; - $order['lastName'] = $order_data['lastname']; - $order['email'] = $order_data['email']; - $order['phone'] = $order_data['telephone']; - $order['customerComment'] = $order_data['comment']; + $country = (isset($order_data['shipping_country'])) ? $order_data['shipping_country'] : '' ; - $deliveryCost = 0; - $altTotals = isset($order_data['order_total']) ? $order_data['order_total'] : ""; - $orderTotals = isset($order_data['totals']) ? $order_data['totals'] : $altTotals ; + $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'] + )) + ) + ); - if (!empty($orderTotals)) { - foreach ($orderTotals as $totals) { - if ($totals['code'] == 'shipping') { - $deliveryCost = $totals['value']; + $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']; + } + } + } } } - } - $order['createdAt'] = date('Y-m-d H:i:s'); + ksort($options); - $payment_code = $order_data['payment_code']; - $order['paymentType'] = $settings['retailcrm_payment'][$payment_code]; - - $delivery_code = $order_data['shipping_code']; - $order['delivery'] = array( - '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']; - - foreach ($orderProducts as $product) { - $order['items'][] = array( - 'productId' => $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) - { - $this->load->model('setting/setting'); - $settings = $this->model_setting_setting->getSetting('retailcrm'); - - if(!empty($settings['retailcrm_url']) && !empty($settings['retailcrm_apikey'])) { - require_once DIR_SYSTEM . 'library/retailcrm/bootstrap.php'; - - $this->retailcrm = new RetailcrmProxy( - $settings['retailcrm_url'], - $settings['retailcrm_apikey'], - DIR_SYSTEM . '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['email'] = $order_data['email']; - $order['phone'] = $order_data['telephone']; - $order['customerComment'] = $order_data['comment']; - - $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']; + $offerId = array(); + foreach($options as $optionKey => $optionValue) { + $offerId[] = $optionKey.'-'.$optionValue; } + $offerId = implode('_', $offerId); } - $order['createdAt'] = date('Y-m-d H:i:s'); - $order['paymentType'] = $settings['retailcrm_payment'][$payment_code]; - - $country = (isset($order_data['shipping_country'])) ? $order_data['shipping_country'] : '' ; - - $order['delivery'] = array( - 'code' => !empty($settings['retailcrm_delivery'][$delivery_code]) - ? $settings['retailcrm_delivery'][$delivery_code] - : null, - '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'] - )) - ) + $order['items'][] = array( + 'productId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id'], + 'productName' => $product['name'], + 'initialPrice' => $product['price'], + 'quantity' => $product['quantity'], ); - - $orderProducts = isset($order_data['products']) ? $order_data['products'] : $order_data['order_product']; - - foreach ($orderProducts as $product) { - $order['items'][] = array( - 'productId' => $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); } + + return $order; } } diff --git a/catalog/controller/module/retailcrm.php b/catalog/controller/module/retailcrm.php index ba9cd45..471f15f 100644 --- a/catalog/controller/module/retailcrm.php +++ b/catalog/controller/module/retailcrm.php @@ -94,4 +94,24 @@ class ControllerModuleRetailcrm extends Controller $this->model_retailcrm_order->changeInCrm($data, $data['order_id']); } } + + /** + * Create customer on event + * + * @param int $customerId customer identificator + * + * @return void + */ + public function customer_create($parameter1, $parameter2) { + if($parameter2 != null) + $customerId = $parameter2; + else + $customerId = $parameter1; + + $this->load->model('account/customer'); + $customer = $this->model_account_customer->getCustomer($customerId); + + $this->load->model('retailcrm/customer'); + $this->model_retailcrm_customer->sendToCrm($customer); + } } diff --git a/catalog/model/retailcrm/customer.php b/catalog/model/retailcrm/customer.php new file mode 100644 index 0000000..093a109 --- /dev/null +++ b/catalog/model/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 . '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/retailcrm/order.php b/catalog/model/retailcrm/order.php index 0f6309e..4f684e2 100644 --- a/catalog/model/retailcrm/order.php +++ b/catalog/model/retailcrm/order.php @@ -122,7 +122,9 @@ class ModelRetailcrmOrder extends Model { } $order['items'][] = array( - 'productId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id'], + 'offer' => array( + 'externalId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id'] + ), 'productName' => $product['name'], 'initialPrice' => $product['price'], 'quantity' => $product['quantity'], @@ -233,7 +235,9 @@ class ModelRetailcrmOrder extends Model { } $order['items'][] = array( - 'productId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id'], + 'offer' => array( + 'externalId' => !empty($offerId) ? $product['product_id'].'#'.$offerId : $product['product_id'] + ), 'productName' => $product['name'], 'initialPrice' => $product['price'], 'quantity' => $product['quantity'], diff --git a/system/cron/export.php b/system/cron/export.php new file mode 100644 index 0000000..8da82f4 --- /dev/null +++ b/system/cron/export.php @@ -0,0 +1,3 @@ + + * @license https://opensource.org/licenses/MIT MIT License + * @link http://www.retailcrm.ru/docs/Developers/ApiVersion4 + */ class CurlException extends RuntimeException { } diff --git a/system/library/retailcrm/InvalidJsonException.php b/system/library/retailcrm/InvalidJsonException.php index 66a1105..1e631c2 100644 --- a/system/library/retailcrm/InvalidJsonException.php +++ b/system/library/retailcrm/InvalidJsonException.php @@ -1,5 +1,15 @@ + * @license https://opensource.org/licenses/MIT MIT License + * @link http://www.retailcrm.ru/docs/Developers/ApiVersion4 + */ class InvalidJsonException extends DomainException { } diff --git a/system/library/retailcrm/RetailcrmApiClient.php b/system/library/retailcrm/RetailcrmApiClient.php index 656c270..4363e65 100644 --- a/system/library/retailcrm/RetailcrmApiClient.php +++ b/system/library/retailcrm/RetailcrmApiClient.php @@ -1,10 +1,19 @@ + * @license https://opensource.org/licenses/MIT MIT License + * @link http://www.retailcrm.ru/docs/Developers/ApiVersion4 */ class RetailcrmApiClient { - const VERSION = 'v3'; + + const VERSION = 'v4'; protected $client; @@ -16,14 +25,17 @@ class RetailcrmApiClient /** * Client creating * - * @param string $url - * @param string $apiKey - * @param string $site + * @param string $url api url + * @param string $apiKey api key + * @param string $site site code + * + * @throws \InvalidArgumentException + * * @return mixed */ public function __construct($url, $apiKey, $site = null) { - if ('/' != substr($url, strlen($url) - 1, 1)) { + if ('/' !== $url[strlen($url) - 1]) { $url .= '/'; } @@ -34,139 +46,276 @@ class RetailcrmApiClient } /** - * Create a order + * Returns users list * - * @param array $order - * @param string $site (default: null) - * @return RetailcrmApiResponse - */ - public function ordersCreate(array $order, $site = null) - { - if (!sizeof($order)) { - throw new InvalidArgumentException('Parameter `order` must contains a data'); - } - - return $this->client->makeRequest("/orders/create", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array( - 'order' => json_encode($order) - ))); - } - - /** - * Edit a order + * @param array $filter + * @param null $page + * @param null $limit * - * @param array $order - * @param string $by - * @param string $site (default: null) - * @return RetailcrmApiResponse + * @throws \RetailCrm\Exception\InvalidJsonException + * @throws \RetailCrm\Exception\CurlException + * @throws \InvalidArgumentException + * + * @return ApiResponse */ - public function ordersEdit(array $order, $by = 'externalId', $site = null) + public function usersList(array $filter = array(), $page = null, $limit = null) { - if (!sizeof($order)) { - throw new InvalidArgumentException('Parameter `order` must contains a data'); + $parameters = array(); + + if (count($filter)) { + $parameters['filter'] = $filter; } - - $this->checkIdParameter($by); - - if (!isset($order[$by])) { - throw new InvalidArgumentException(sprintf('Order array must contain the "%s" parameter.', $by)); + if (null !== $page) { + $parameters['page'] = (int) $page; + } + if (null !== $limit) { + $parameters['limit'] = (int) $limit; } return $this->client->makeRequest( - "/orders/" . $order[$by] . "/edit", + '/users', + RetailcrmHttpClient::METHOD_GET, + $parameters + ); + } + + /** + * Returns user data + * + * @param integer $id user ID + * + * @throws \RetailCrm\Exception\InvalidJsonException + * @throws \RetailCrm\Exception\CurlException + * @throws \InvalidArgumentException + * + * @return ApiResponse + */ + public function usersGet($id) + { + return $this->client->makeRequest("/users/$id", RetailcrmHttpClient::METHOD_GET); + } + + /** + * Returns filtered orders list + * + * @param array $filter (default: array()) + * @param int $page (default: null) + * @param int $limit (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function ordersList(array $filter = array(), $page = null, $limit = null) + { + $parameters = array(); + + if (count($filter)) { + $parameters['filter'] = $filter; + } + if (null !== $page) { + $parameters['page'] = (int) $page; + } + if (null !== $limit) { + $parameters['limit'] = (int) $limit; + } + + return $this->client->makeRequest( + '/orders', + RetailcrmHttpClient::METHOD_GET, + $parameters + ); + } + + /** + * Create a order + * + * @param array $order order data + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function ordersCreate(array $order, $site = null) + { + if (!count($order)) { + throw new \InvalidArgumentException( + 'Parameter `order` must contains a data' + ); + } + + return $this->client->makeRequest( + '/orders/create', RetailcrmHttpClient::METHOD_POST, - $this->fillSite($site, array( - 'order' => json_encode($order), - 'by' => $by, - )) + $this->fillSite($site, array('order' => json_encode($order))) + ); + } + + /** + * Save order IDs' (id and externalId) association in the CRM + * + * @param array $ids order identificators + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function ordersFixExternalIds(array $ids) + { + if (! count($ids)) { + throw new \InvalidArgumentException( + 'Method parameter must contains at least one IDs pair' + ); + } + + return $this->client->makeRequest( + '/orders/fix-external-ids', + RetailcrmHttpClient::METHOD_POST, + array('orders' => json_encode($ids) + ) + ); + } + + /** + * Returns statuses of the orders + * + * @param array $ids (default: array()) + * @param array $externalIds (default: array()) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function ordersStatuses(array $ids = array(), array $externalIds = array()) + { + $parameters = array(); + + if (count($ids)) { + $parameters['ids'] = $ids; + } + if (count($externalIds)) { + $parameters['externalIds'] = $externalIds; + } + + return $this->client->makeRequest( + '/orders/statuses', + RetailcrmHttpClient::METHOD_GET, + $parameters ); } /** * Upload array of the orders * - * @param array $orders - * @param string $site (default: null) - * @return RetailcrmApiResponse + * @param array $orders array of orders + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function ordersUpload(array $orders, $site = null) { - if (!sizeof($orders)) { - throw new InvalidArgumentException('Parameter `orders` must contains array of the orders'); + if (!count($orders)) { + throw new \InvalidArgumentException( + 'Parameter `orders` must contains array of the orders' + ); } - return $this->client->makeRequest("/orders/upload", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array( - 'orders' => json_encode($orders), - ))); + return $this->client->makeRequest( + '/orders/upload', + RetailcrmHttpClient::METHOD_POST, + $this->fillSite($site, array('orders' => json_encode($orders))) + ); } /** * Get order by id or externalId * - * @param string $id - * @param string $by (default: 'externalId') - * @param string $site (default: null) - * @return RetailcrmApiResponse + * @param string $id order identificator + * @param string $by (default: 'externalId') + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function ordersGet($id, $by = 'externalId', $site = null) { $this->checkIdParameter($by); - return $this->client->makeRequest("/orders/$id", RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, array( - 'by' => $by - ))); + return $this->client->makeRequest( + "/orders/$id", + RetailcrmHttpClient::METHOD_GET, + $this->fillSite($site, array('by' => $by)) + ); } /** - * Returns a orders history + * Edit a order * - * @param DateTime $startDate (default: null) - * @param DateTime $endDate (default: null) - * @param int $limit (default: 100) - * @param int $offset (default: 0) - * @param bool $skipMyChanges (default: true) - * @return RetailcrmApiResponse + * @param array $order order data + * @param string $by (default: 'externalId') + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ - public function ordersHistory( - DateTime $startDate = null, - DateTime $endDate = null, - $limit = 100, - $offset = 0, - $skipMyChanges = true - ) { - $parameters = array(); - - if ($startDate) { - $parameters['startDate'] = $startDate->format('Y-m-d H:i:s'); - } - if ($endDate) { - $parameters['endDate'] = $endDate->format('Y-m-d H:i:s'); - } - if ($limit) { - $parameters['limit'] = (int) $limit; - } - if ($offset) { - $parameters['offset'] = (int) $offset; - } - if ($skipMyChanges) { - $parameters['skipMyChanges'] = (bool) $skipMyChanges; + public function ordersEdit(array $order, $by = 'externalId', $site = null) + { + if (!count($order)) { + throw new \InvalidArgumentException( + 'Parameter `order` must contains a data' + ); } - return $this->client->makeRequest('/orders/history', RetailcrmHttpClient::METHOD_GET, $parameters); + $this->checkIdParameter($by); + + if (!array_key_exists($by, $order)) { + throw new \InvalidArgumentException( + sprintf('Order array must contain the "%s" parameter.', $by) + ); + } + + return $this->client->makeRequest( + sprintf('/orders/%s/edit', $order[$by]), + RetailcrmHttpClient::METHOD_POST, + $this->fillSite( + $site, + array('order' => json_encode($order), 'by' => $by) + ) + ); } /** - * Returns filtered orders list + * Get orders history + * @param array $filter + * @param null $page + * @param null $limit * - * @param array $filter (default: array()) - * @param int $page (default: null) - * @param int $limit (default: null) - * @return RetailcrmApiResponse + * @return ApiResponse */ - public function ordersList(array $filter = array(), $page = null, $limit = null) + public function ordersHistory(array $filter = array(), $page = null, $limit = null) { $parameters = array(); - if (sizeof($filter)) { + if (count($filter)) { $parameters['filter'] = $filter; } if (null !== $page) { @@ -176,60 +325,31 @@ class RetailcrmApiClient $parameters['limit'] = (int) $limit; } - return $this->client->makeRequest('/orders', RetailcrmHttpClient::METHOD_GET, $parameters); + return $this->client->makeRequest( + '/orders/history', + RetailcrmHttpClient::METHOD_GET, + $parameters + ); } /** - * Returns statuses of the orders + * Returns filtered customers list * - * @param array $ids (default: array()) - * @param array $externalIds (default: array()) - * @return RetailcrmApiResponse + * @param array $filter (default: array()) + * @param int $page (default: null) + * @param int $limit (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ - public function ordersStatuses(array $ids = array(), array $externalIds = array()) + public function customersList(array $filter = array(), $page = null, $limit = null) { $parameters = array(); - if (sizeof($ids)) { - $parameters['ids'] = $ids; - } - if (sizeof($externalIds)) { - $parameters['externalIds'] = $externalIds; - } - - return $this->client->makeRequest('/orders/statuses', RetailcrmHttpClient::METHOD_GET, $parameters); - } - - /** - * Save order IDs' (id and externalId) association in the CRM - * - * @param array $ids - * @return RetailcrmApiResponse - */ - public function ordersFixExternalIds(array $ids) - { - if (!sizeof($ids)) { - throw new InvalidArgumentException('Method parameter must contains at least one IDs pair'); - } - - return $this->client->makeRequest("/orders/fix-external-ids", RetailcrmHttpClient::METHOD_POST, array( - 'orders' => json_encode($ids), - )); - } - - /** - * Get orders assembly history - * - * @param array $filter (default: array()) - * @param int $page (default: null) - * @param int $limit (default: null) - * @return RetailcrmApiResponse - */ - public function ordersPacksHistory(array $filter = array(), $page = null, $limit = null) - { - $parameters = array(); - - if (sizeof($filter)) { + if (count($filter)) { $parameters['filter'] = $filter; } if (null !== $page) { @@ -239,108 +359,169 @@ class RetailcrmApiClient $parameters['limit'] = (int) $limit; } - return $this->client->makeRequest('/orders/packs/history', RetailcrmHttpClient::METHOD_GET, $parameters); + return $this->client->makeRequest( + '/customers', + RetailcrmHttpClient::METHOD_GET, + $parameters + ); } /** * Create a customer * - * @param array $customer - * @param string $site (default: null) - * @return RetailcrmApiResponse + * @param array $customer customer data + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function customersCreate(array $customer, $site = null) { - if (!sizeof($customer)) { - throw new InvalidArgumentException('Parameter `customer` must contains a data'); - } - - return $this->client->makeRequest("/customers/create", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array( - 'customer' => json_encode($customer) - ))); - } - - /** - * Edit a customer - * - * @param array $customer - * @param string $by (default: 'externalId') - * @param string $site (default: null) - * @return RetailcrmApiResponse - */ - public function customersEdit(array $customer, $by = 'externalId', $site = null) - { - if (!sizeof($customer)) { - throw new InvalidArgumentException('Parameter `customer` must contains a data'); - } - - $this->checkIdParameter($by); - - if (!isset($customer[$by])) { - throw new InvalidArgumentException(sprintf('Customer array must contain the "%s" parameter.', $by)); + if (! count($customer)) { + throw new \InvalidArgumentException( + 'Parameter `customer` must contains a data' + ); } return $this->client->makeRequest( - "/customers/" . $customer[$by] . "/edit", + '/customers/create', RetailcrmHttpClient::METHOD_POST, - $this->fillSite( - $site, - array( - 'customer' => json_encode($customer), - 'by' => $by - ) - ) + $this->fillSite($site, array('customer' => json_encode($customer))) + ); + } + + /** + * Save customer IDs' (id and externalId) association in the CRM + * + * @param array $ids ids mapping + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function customersFixExternalIds(array $ids) + { + if (! count($ids)) { + throw new \InvalidArgumentException( + 'Method parameter must contains at least one IDs pair' + ); + } + + return $this->client->makeRequest( + '/customers/fix-external-ids', + RetailcrmHttpClient::METHOD_POST, + array('customers' => json_encode($ids)) ); } /** * Upload array of the customers * - * @param array $customers - * @param string $site (default: null) - * @return RetailcrmApiResponse + * @param array $customers array of customers + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function customersUpload(array $customers, $site = null) { - if (!sizeof($customers)) { - throw new InvalidArgumentException('Parameter `customers` must contains array of the customers'); + if (! count($customers)) { + throw new \InvalidArgumentException( + 'Parameter `customers` must contains array of the customers' + ); } - return $this->client->makeRequest("/customers/upload", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array( - 'customers' => json_encode($customers), - ))); + return $this->client->makeRequest( + '/customers/upload', + RetailcrmHttpClient::METHOD_POST, + $this->fillSite($site, array('customers' => json_encode($customers))) + ); } /** * Get customer by id or externalId * - * @param string $id - * @param string $by (default: 'externalId') - * @param string $site (default: null) - * @return RetailcrmApiResponse + * @param string $id customer identificator + * @param string $by (default: 'externalId') + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function customersGet($id, $by = 'externalId', $site = null) { $this->checkIdParameter($by); - return $this->client->makeRequest("/customers/$id", RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, array( - 'by' => $by - ))); + return $this->client->makeRequest( + "/customers/$id", + RetailcrmHttpClient::METHOD_GET, + $this->fillSite($site, array('by' => $by)) + ); } /** - * Returns filtered customers list + * Edit a customer * - * @param array $filter (default: array()) - * @param int $page (default: null) - * @param int $limit (default: null) - * @return RetailcrmApiResponse + * @param array $customer customer data + * @param string $by (default: 'externalId') + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ - public function customersList(array $filter = array(), $page = null, $limit = null) + public function customersEdit(array $customer, $by = 'externalId', $site = null) + { + if (!count($customer)) { + throw new \InvalidArgumentException( + 'Parameter `customer` must contains a data' + ); + } + + $this->checkIdParameter($by); + + if (!array_key_exists($by, $customer)) { + throw new \InvalidArgumentException( + sprintf('Customer array must contain the "%s" parameter.', $by) + ); + } + + return $this->client->makeRequest( + sprintf('/customers/%s/edit', $customer[$by]), + RetailcrmHttpClient::METHOD_POST, + $this->fillSite( + $site, + array('customer' => json_encode($customer), 'by' => $by) + ) + ); + } + + /** + * Get customers history + * @param array $filter + * @param null $page + * @param null $limit + * + * @return ApiResponse + */ + public function customersHistory(array $filter = array(), $page = null, $limit = null) { $parameters = array(); - if (sizeof($filter)) { + if (count($filter)) { $parameters['filter'] = $filter; } if (null !== $page) { @@ -350,40 +531,199 @@ class RetailcrmApiClient $parameters['limit'] = (int) $limit; } - return $this->client->makeRequest('/customers', RetailcrmHttpClient::METHOD_GET, $parameters); + return $this->client->makeRequest( + '/customers/history', + RetailcrmHttpClient::METHOD_GET, + $parameters + ); } /** - * Save customer IDs' (id and externalId) association in the CRM + * Get orders assembly list * - * @param array $ids - * @return RetailcrmApiResponse + * @param array $filter (default: array()) + * @param int $page (default: null) + * @param int $limit (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ - public function customersFixExternalIds(array $ids) + public function ordersPacksList(array $filter = array(), $page = null, $limit = null) { - if (!sizeof($ids)) { - throw new InvalidArgumentException('Method parameter must contains at least one IDs pair'); + $parameters = array(); + + if (count($filter)) { + $parameters['filter'] = $filter; + } + if (null !== $page) { + $parameters['page'] = (int) $page; + } + if (null !== $limit) { + $parameters['limit'] = (int) $limit; } - return $this->client->makeRequest("/customers/fix-external-ids", RetailcrmHttpClient::METHOD_POST, array( - 'customers' => json_encode($ids), - )); + return $this->client->makeRequest( + '/orders/packs', + RetailcrmHttpClient::METHOD_GET, + $parameters + ); + } + + /** + * Create orders assembly + * + * @param array $pack pack data + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function ordersPacksCreate(array $pack, $site = null) + { + if (!count($pack)) { + throw new \InvalidArgumentException( + 'Parameter `pack` must contains a data' + ); + } + + return $this->client->makeRequest( + '/orders/packs/create', + RetailcrmHttpClient::METHOD_POST, + $this->fillSite($site, array('pack' => json_encode($pack))) + ); + } + + /** + * Get orders assembly history + * + * @param array $filter (default: array()) + * @param int $page (default: null) + * @param int $limit (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function ordersPacksHistory(array $filter = array(), $page = null, $limit = null) + { + $parameters = array(); + + if (count($filter)) { + $parameters['filter'] = $filter; + } + if (null !== $page) { + $parameters['page'] = (int) $page; + } + if (null !== $limit) { + $parameters['limit'] = (int) $limit; + } + + return $this->client->makeRequest( + '/orders/packs/history', + RetailcrmHttpClient::METHOD_GET, + $parameters + ); + } + + /** + * Get orders assembly by id + * + * @param string $id pack identificator + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function ordersPacksGet($id) + { + if (empty($id)) { + throw new \InvalidArgumentException('Parameter `id` must be set'); + } + + return $this->client->makeRequest( + "/orders/packs/$id", + RetailcrmHttpClient::METHOD_GET + ); + } + + /** + * Delete orders assembly by id + * + * @param string $id pack identificator + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function ordersPacksDelete($id) + { + if (empty($id)) { + throw new \InvalidArgumentException('Parameter `id` must be set'); + } + + return $this->client->makeRequest( + sprintf('/orders/packs/%s/delete', $id), + RetailcrmHttpClient::METHOD_POST + ); + } + + /** + * Edit orders assembly + * + * @param array $pack pack data + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function ordersPacksEdit(array $pack, $site = null) + { + if (!count($pack) || empty($pack['id'])) { + throw new \InvalidArgumentException( + 'Parameter `pack` must contains a data & pack `id` must be set' + ); + } + + return $this->client->makeRequest( + sprintf('/orders/packs/%s/edit', $pack['id']), + RetailcrmHttpClient::METHOD_POST, + $this->fillSite($site, array('pack' => json_encode($pack))) + ); } /** * Get purchace prices & stock balance * - * @param array $filter (default: array()) - * @param int $page (default: null) - * @param int $limit (default: null) - * @param string $site (default: null) - * @return RetailcrmApiResponse + * @param array $filter (default: array()) + * @param int $page (default: null) + * @param int $limit (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ - public function storeInventories(array $filter = array(), $page = null, $limit = null, $site = null) + public function storeInventories(array $filter = array(), $page = null, $limit = null) { $parameters = array(); - if (sizeof($filter)) { + if (count($filter)) { $parameters['filter'] = $filter; } if (null !== $page) { @@ -393,157 +733,278 @@ class RetailcrmApiClient $parameters['limit'] = (int) $limit; } - return $this->client->makeRequest('/store/inventories', RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, $parameters)); + return $this->client->makeRequest( + '/store/inventories', + RetailcrmHttpClient::METHOD_GET, + $parameters + ); + } + + /** + * Get store settings + * + * @param string $code get settings code + * + * @return ApiResponse + * @throws \RetailCrm\Exception\InvalidJsonException + * @throws \RetailCrm\Exception\CurlException + * @throws \InvalidArgumentException + * + * @return ApiResponse + */ + public function storeSettingsGet($code) + { + if (empty($code)) { + throw new \InvalidArgumentException('Parameter `code` must be set'); + } + + return $this->client->makeRequest( + "/store/setting/$code", + RetailcrmHttpClient::METHOD_GET + ); + } + + /** + * Edit store configuration + * + * @param array $configuration + * + * @throws \RetailCrm\Exception\InvalidJsonException + * @throws \RetailCrm\Exception\CurlException + * @throws \InvalidArgumentException + * + * @return ApiResponse + */ + public function storeSettingsEdit(array $configuration) + { + if (!count($configuration) || empty($configuration['code'])) { + throw new \InvalidArgumentException( + 'Parameter `configuration` must contains a data & configuration `code` must be set' + ); + } + + return $this->client->makeRequest( + sprintf('/store/setting/%s/edit', $configuration['code']), + RetailcrmHttpClient::METHOD_POST, + $configuration + ); } /** * Upload store inventories * - * @param array $offers - * @param string $site (default: null) - * @return RetailcrmApiResponse + * @param array $offers offers data + * @param string $site (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function storeInventoriesUpload(array $offers, $site = null) { - if (!sizeof($offers)) { - throw new InvalidArgumentException('Parameter `offers` must contains array of the customers'); + if (!count($offers)) { + throw new \InvalidArgumentException( + 'Parameter `offers` must contains array of the offers' + ); } return $this->client->makeRequest( - "/store/inventories/upload", + '/store/inventories/upload', RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array('offers' => json_encode($offers))) ); } + /** + * Get products + * + * @param array $filter (default: array()) + * @param int $page (default: null) + * @param int $limit (default: null) + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function storeProducts(array $filter = array(), $page = null, $limit = null) + { + $parameters = array(); + + if (count($filter)) { + $parameters['filter'] = $filter; + } + if (null !== $page) { + $parameters['page'] = (int) $page; + } + if (null !== $limit) { + $parameters['limit'] = (int) $limit; + } + + return $this->client->makeRequest( + '/store/products', + RetailcrmHttpClient::METHOD_GET, + $parameters + ); + } + + /** + * Get delivery settings + * + * @param string $code + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function deliverySettingsGet($code) + { + if (empty($code)) { + throw new \InvalidArgumentException('Parameter `code` must be set'); + } + + return $this->client->makeRequest( + "/delivery/generic/setting/$code", + RetailcrmHttpClient::METHOD_GET + ); + } + + /** + * Edit delivery configuration + * + * @param array $configuration + * + * @throws \RetailCrm\Exception\InvalidJsonException + * @throws \RetailCrm\Exception\CurlException + * @throws \InvalidArgumentException + * + * @return ApiResponse + */ + public function deliverySettingsEdit(array $configuration) + { + if (!count($configuration) || empty($configuration['code'])) { + throw new \InvalidArgumentException( + 'Parameter `configuration` must contains a data & configuration `code` must be set' + ); + } + + return $this->client->makeRequest( + sprintf('/delivery/generic/setting/%s/edit', $configuration['code']), + RetailcrmHttpClient::METHOD_POST, + array('configuration' => json_encode($configuration)) + ); + } + + /** + * Delivery tracking update + * + * @param string $code + * @param array $statusUpdate + * + * @throws \RetailCrm\Exception\InvalidJsonException + * @throws \RetailCrm\Exception\CurlException + * @throws \InvalidArgumentException + * + * @return ApiResponse + */ + public function deliveryTracking($code, array $statusUpdate) + { + if (empty($code)) { + throw new \InvalidArgumentException('Parameter `code` must be set'); + } + + if (!count($statusUpdate)) { + throw new \InvalidArgumentException( + 'Parameter `statusUpdate` must contains a data' + ); + } + + return $this->client->makeRequest( + sprintf('/delivery/generic/%s/tracking', $code), + RetailcrmHttpClient::METHOD_POST, + $statusUpdate + ); + } + + /** + * Returns available county list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function countriesList() + { + return $this->client->makeRequest( + '/reference/countries', + RetailcrmHttpClient::METHOD_GET + ); + } + /** * Returns deliveryServices list * - * @return RetailcrmApiResponse + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function deliveryServicesList() { - return $this->client->makeRequest('/reference/delivery-services', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns deliveryTypes list - * - * @return RetailcrmApiResponse - */ - public function deliveryTypesList() - { - return $this->client->makeRequest('/reference/delivery-types', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns orderMethods list - * - * @return RetailcrmApiResponse - */ - public function orderMethodsList() - { - return $this->client->makeRequest('/reference/order-methods', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns orderTypes list - * - * @return RetailcrmApiResponse - */ - public function orderTypesList() - { - return $this->client->makeRequest('/reference/order-types', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns paymentStatuses list - * - * @return RetailcrmApiResponse - */ - public function paymentStatusesList() - { - return $this->client->makeRequest('/reference/payment-statuses', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns paymentTypes list - * - * @return RetailcrmApiResponse - */ - public function paymentTypesList() - { - return $this->client->makeRequest('/reference/payment-types', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns productStatuses list - * - * @return RetailcrmApiResponse - */ - public function productStatusesList() - { - return $this->client->makeRequest('/reference/product-statuses', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns statusGroups list - * - * @return RetailcrmApiResponse - */ - public function statusGroupsList() - { - return $this->client->makeRequest('/reference/status-groups', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns statuses list - * - * @return RetailcrmApiResponse - */ - public function statusesList() - { - return $this->client->makeRequest('/reference/statuses', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns sites list - * - * @return RetailcrmApiResponse - */ - public function sitesList() - { - return $this->client->makeRequest('/reference/sites', RetailcrmHttpClient::METHOD_GET); - } - - /** - * Returns stores list - * - * @return RetailcrmApiResponse - */ - public function storesList() - { - return $this->client->makeRequest('/reference/stores', RetailcrmHttpClient::METHOD_GET); + return $this->client->makeRequest( + '/reference/delivery-services', + RetailcrmHttpClient::METHOD_GET + ); } /** * Edit deliveryService * * @param array $data delivery service data - * @return RetailcrmApiResponse + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function deliveryServicesEdit(array $data) { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); } return $this->client->makeRequest( - '/reference/delivery-services/' . $data['code'] . '/edit', + sprintf('/reference/delivery-services/%s/edit', $data['code']), RetailcrmHttpClient::METHOD_POST, - array( - 'deliveryService' => json_encode($data) - ) + array('deliveryService' => json_encode($data)) + ); + } + + /** + * Returns deliveryTypes list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function deliveryTypesList() + { + return $this->client->makeRequest( + '/reference/delivery-types', + RetailcrmHttpClient::METHOD_GET ); } @@ -551,20 +1012,42 @@ class RetailcrmApiClient * Edit deliveryType * * @param array $data delivery type data - * @return RetailcrmApiResponse + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function deliveryTypesEdit(array $data) { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); } return $this->client->makeRequest( - '/reference/delivery-types/' . $data['code'] . '/edit', + sprintf('/reference/delivery-types/%s/edit', $data['code']), RetailcrmHttpClient::METHOD_POST, - array( - 'deliveryType' => json_encode($data) - ) + array('deliveryType' => json_encode($data)) + ); + } + + /** + * Returns orderMethods list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function orderMethodsList() + { + return $this->client->makeRequest( + '/reference/order-methods', + RetailcrmHttpClient::METHOD_GET ); } @@ -572,20 +1055,42 @@ class RetailcrmApiClient * Edit orderMethod * * @param array $data order method data - * @return RetailcrmApiResponse + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function orderMethodsEdit(array $data) { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); } return $this->client->makeRequest( - '/reference/order-methods/' . $data['code'] . '/edit', + sprintf('/reference/order-methods/%s/edit', $data['code']), RetailcrmHttpClient::METHOD_POST, - array( - 'orderMethod' => json_encode($data) - ) + array('orderMethod' => json_encode($data)) + ); + } + + /** + * Returns orderTypes list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function orderTypesList() + { + return $this->client->makeRequest( + '/reference/order-types', + RetailcrmHttpClient::METHOD_GET ); } @@ -593,20 +1098,42 @@ class RetailcrmApiClient * Edit orderType * * @param array $data order type data - * @return RetailcrmApiResponse + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function orderTypesEdit(array $data) { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); } return $this->client->makeRequest( - '/reference/order-types/' . $data['code'] . '/edit', + sprintf('/reference/order-types/%s/edit', $data['code']), RetailcrmHttpClient::METHOD_POST, - array( - 'orderType' => json_encode($data) - ) + array('orderType' => json_encode($data)) + ); + } + + /** + * Returns paymentStatuses list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function paymentStatusesList() + { + return $this->client->makeRequest( + '/reference/payment-statuses', + RetailcrmHttpClient::METHOD_GET ); } @@ -614,20 +1141,42 @@ class RetailcrmApiClient * Edit paymentStatus * * @param array $data payment status data - * @return RetailcrmApiResponse + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function paymentStatusesEdit(array $data) { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); } return $this->client->makeRequest( - '/reference/payment-statuses/' . $data['code'] . '/edit', + sprintf('/reference/payment-statuses/%s/edit', $data['code']), RetailcrmHttpClient::METHOD_POST, - array( - 'paymentStatus' => json_encode($data) - ) + array('paymentStatus' => json_encode($data)) + ); + } + + /** + * Returns paymentTypes list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function paymentTypesList() + { + return $this->client->makeRequest( + '/reference/payment-types', + RetailcrmHttpClient::METHOD_GET ); } @@ -635,20 +1184,42 @@ class RetailcrmApiClient * Edit paymentType * * @param array $data payment type data - * @return RetailcrmApiResponse + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function paymentTypesEdit(array $data) { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); } return $this->client->makeRequest( - '/reference/payment-types/' . $data['code'] . '/edit', + sprintf('/reference/payment-types/%s/edit', $data['code']), RetailcrmHttpClient::METHOD_POST, - array( - 'paymentType' => json_encode($data) - ) + array('paymentType' => json_encode($data)) + ); + } + + /** + * Returns productStatuses list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function productStatusesList() + { + return $this->client->makeRequest( + '/reference/product-statuses', + RetailcrmHttpClient::METHOD_GET ); } @@ -656,41 +1227,42 @@ class RetailcrmApiClient * Edit productStatus * * @param array $data product status data - * @return RetailcrmApiResponse + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function productStatusesEdit(array $data) { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); } return $this->client->makeRequest( - '/reference/product-statuses/' . $data['code'] . '/edit', + sprintf('/reference/product-statuses/%s/edit', $data['code']), RetailcrmHttpClient::METHOD_POST, - array( - 'productStatus' => json_encode($data) - ) + array('productStatus' => json_encode($data)) ); } /** - * Edit order status + * Returns sites list * - * @param array $data status data - * @return RetailcrmApiResponse + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ - public function statusesEdit(array $data) + public function sitesList() { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); - } - return $this->client->makeRequest( - '/reference/statuses/' . $data['code'] . '/edit', - RetailcrmHttpClient::METHOD_POST, - array( - 'status' => json_encode($data) - ) + '/reference/sites', + RetailcrmHttpClient::METHOD_GET ); } @@ -698,20 +1270,102 @@ class RetailcrmApiClient * Edit site * * @param array $data site data - * @return RetailcrmApiResponse + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function sitesEdit(array $data) { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); } return $this->client->makeRequest( - '/reference/sites/' . $data['code'] . '/edit', + sprintf('/reference/sites/%s/edit', $data['code']), RetailcrmHttpClient::METHOD_POST, - array( - 'site' => json_encode($data) - ) + array('site' => json_encode($data)) + ); + } + + /** + * Returns statusGroups list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function statusGroupsList() + { + return $this->client->makeRequest( + '/reference/status-groups', + RetailcrmHttpClient::METHOD_GET + ); + } + + /** + * Returns statuses list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function statusesList() + { + return $this->client->makeRequest( + '/reference/statuses', + RetailcrmHttpClient::METHOD_GET + ); + } + + /** + * Edit order status + * + * @param array $data status data + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function statusesEdit(array $data) + { + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); + } + + return $this->client->makeRequest( + sprintf('/reference/statuses/%s/edit', $data['code']), + RetailcrmHttpClient::METHOD_POST, + array('status' => json_encode($data)) + ); + } + + /** + * Returns stores list + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function storesList() + { + return $this->client->makeRequest( + '/reference/stores', + RetailcrmHttpClient::METHOD_GET ); } @@ -719,35 +1373,282 @@ class RetailcrmApiClient * Edit store * * @param array $data site data - * @return RetailcrmApiResponse + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function storesEdit(array $data) { - if (!isset($data['code'])) { - throw new InvalidArgumentException('Data must contain "code" parameter.'); + if (!array_key_exists('code', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "code" parameter.' + ); } - if (!isset($data['name'])) { - throw new InvalidArgumentException('Data must contain "name" parameter.'); + if (!array_key_exists('name', $data)) { + throw new \InvalidArgumentException( + 'Data must contain "name" parameter.' + ); } return $this->client->makeRequest( - '/reference/stores/' . $data['code'] . '/edit', + sprintf('/reference/stores/%s/edit', $data['code']), RetailcrmHttpClient::METHOD_POST, - array( - 'store' => json_encode($data) - ) + array('store' => json_encode($data)) + ); + } + + /** + * Get telephony settings + * + * @param string $code + * + * @throws \RetailCrm\Exception\InvalidJsonException + * @throws \RetailCrm\Exception\CurlException + * @throws \InvalidArgumentException + * + * @return ApiResponse + */ + public function telephonySettingsGet($code) + { + if (empty($code)) { + throw new \InvalidArgumentException('Parameter `code` must be set'); + } + + return $this->client->makeRequest( + "/telephony/setting/$code", + RetailcrmHttpClient::METHOD_GET + ); + } + + /** + * Edit telephony settings + * + * @param string $code symbolic code + * @param string $clientId client id + * @param boolean $active telephony activity + * @param mixed $name service name + * @param mixed $makeCallUrl service init url + * @param mixed $image service logo url(svg file) + * + * @param array $additionalCodes + * @param array $externalPhones + * @param bool $allowEdit + * @param bool $inputEventSupported + * @param bool $outputEventSupported + * @param bool $hangupEventSupported + * @param bool $changeUserStatusUrl + * + * @return ApiResponse + */ + public function telephonySettingsEdit( + $code, + $clientId, + $active = false, + $name = false, + $makeCallUrl = false, + $image = false, + $additionalCodes = array(), + $externalPhones = array(), + $allowEdit = false, + $inputEventSupported = false, + $outputEventSupported = false, + $hangupEventSupported = false, + $changeUserStatusUrl = false + ) + { + if (!isset($code)) { + throw new \InvalidArgumentException('Code must be set'); + } + + $parameters['code'] = $code; + + if (!isset($clientId)) { + throw new \InvalidArgumentException('client id must be set'); + } + + $parameters['clientId'] = $clientId; + + if (!isset($active)) { + $parameters['active'] = false; + } else { + $parameters['active'] = $active; + } + + if (!isset($name)) { + throw new \InvalidArgumentException('name must be set'); + } + + if (isset($name)) { + $parameters['name'] = $name; + } + + if (isset($makeCallUrl)) { + $parameters['makeCallUrl'] = $makeCallUrl; + } + + if (isset($image)) { + $parameters['image'] = $image; + } + + if (isset($additionalCodes)) { + $parameters['additionalCodes'] = $additionalCodes; + } + + if (isset($externalPhones)) { + $parameters['externalPhones'] = $externalPhones; + } + + if (isset($allowEdit)) { + $parameters['allowEdit'] = $allowEdit; + } + + if (isset($inputEventSupported)) { + $parameters['inputEventSupported'] = $inputEventSupported; + } + + if (isset($outputEventSupported)) { + $parameters['outputEventSupported'] = $outputEventSupported; + } + + if (isset($hangupEventSupported)) { + $parameters['hangupEventSupported'] = $hangupEventSupported; + } + + if (isset($changeUserStatusUrl)) { + $parameters['changeUserStatusUrl'] = $changeUserStatusUrl; + } + + return $this->client->makeRequest( + "/telephony/setting/$code/edit", + RetailcrmHttpClient::METHOD_POST, + array('configuration' => json_encode($parameters)) + ); + } + + /** + * Call event + * + * @param string $phone phone number + * @param string $type call type + * @param array $codes + * @param string $hangupStatus + * @param string $externalPhone + * @param array $webAnalyticsData + * + * @return ApiResponse + * @internal param string $code additional phone code + * @internal param string $status call status + * + */ + public function telephonyCallEvent( + $phone, + $type, + $codes, + $hangupStatus, + $externalPhone = null, + $webAnalyticsData = array() + ) + { + if (!isset($phone)) { + throw new \InvalidArgumentException('Phone number must be set'); + } + + if (!isset($type)) { + throw new \InvalidArgumentException('Type must be set (in|out|hangup)'); + } + + if (empty($codes)) { + throw new \InvalidArgumentException('Codes array must be set'); + } + + $parameters['phone'] = $phone; + $parameters['type'] = $type; + $parameters['codes'] = $codes; + $parameters['hangupStatus'] = $hangupStatus; + $parameters['callExternalId'] = $externalPhone; + $parameters['webAnalyticsData'] = $webAnalyticsData; + + + return $this->client->makeRequest( + '/telephony/call/event', + RetailcrmHttpClient::METHOD_POST, + array('event' => json_encode($parameters)) + ); + } + + /** + * Upload calls + * + * @param array $calls calls data + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function telephonyCallsUpload(array $calls) + { + if (!count($calls)) { + throw new \InvalidArgumentException( + 'Parameter `calls` must contains array of the calls' + ); + } + + return $this->client->makeRequest( + '/telephony/calls/upload', + RetailcrmHttpClient::METHOD_POST, + array('calls' => json_encode($calls)) + ); + } + + /** + * Get call manager + * + * @param string $phone phone number + * @param bool $details detailed information + * + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse + */ + public function telephonyCallManager($phone, $details) + { + if (!isset($phone)) { + throw new \InvalidArgumentException('Phone number must be set'); + } + + $parameters['phone'] = $phone; + $parameters['details'] = isset($details) ? $details : 0; + + return $this->client->makeRequest( + '/telephony/manager', + RetailcrmHttpClient::METHOD_GET, + $parameters ); } /** * Update CRM basic statistic * - * @return RetailcrmApiResponse + * @throws \InvalidArgumentException + * @throws \RetailCrm\Exception\CurlException + * @throws \RetailCrm\Exception\InvalidJsonException + * + * @return ApiResponse */ public function statisticUpdate() { - return $this->client->makeRequest('/statistic/update', RetailcrmHttpClient::METHOD_GET); + return $this->client->makeRequest( + '/statistic/update', + RetailcrmHttpClient::METHOD_GET + ); } /** @@ -763,7 +1664,8 @@ class RetailcrmApiClient /** * Set site * - * @param string $site + * @param string $site site code + * * @return void */ public function setSite($site) @@ -774,18 +1676,27 @@ class RetailcrmApiClient /** * Check ID parameter * - * @param string $by + * @param string $by identify by + * + * @throws \InvalidArgumentException + * * @return bool */ protected function checkIdParameter($by) { - $allowedForBy = array('externalId', 'id'); - if (!in_array($by, $allowedForBy)) { - throw new InvalidArgumentException(sprintf( - 'Value "%s" for parameter "by" is not valid. Allowed values are %s.', - $by, - implode(', ', $allowedForBy) - )); + $allowedForBy = array( + 'externalId', + 'id' + ); + + if (!in_array($by, $allowedForBy, false)) { + throw new \InvalidArgumentException( + sprintf( + 'Value "%s" for "by" param is not valid. Allowed values are %s.', + $by, + implode(', ', $allowedForBy) + ) + ); } return true; @@ -794,8 +1705,9 @@ class RetailcrmApiClient /** * Fill params by site value * - * @param string $site - * @param array $params + * @param string $site site code + * @param array $params input parameters + * * @return array */ protected function fillSite($site, array $params) diff --git a/system/library/retailcrm/RetailcrmApiResponse.php b/system/library/retailcrm/RetailcrmApiResponse.php index bba91db..b63599f 100644 --- a/system/library/retailcrm/RetailcrmApiResponse.php +++ b/system/library/retailcrm/RetailcrmApiResponse.php @@ -1,6 +1,14 @@ + * @license https://opensource.org/licenses/MIT MIT License + * @link http://www.retailcrm.ru/docs/Developers/ApiVersion4 */ class RetailcrmApiResponse implements ArrayAccess { @@ -10,6 +18,14 @@ class RetailcrmApiResponse implements ArrayAccess // response assoc array protected $response; + /** + * ApiResponse constructor. + * + * @param int $statusCode HTTP status code + * @param mixed $responseBody HTTP body + * + * @throws InvalidJsonException + */ public function __construct($statusCode, $responseBody = null) { $this->statusCode = (int) $statusCode; @@ -51,7 +67,11 @@ class RetailcrmApiResponse implements ArrayAccess /** * Allow to access for the property throw class method * - * @param string $name + * @param string $name method name + * @param mixed $arguments method parameters + * + * @throws \InvalidArgumentException + * * @return mixed */ public function __call($name, $arguments) @@ -60,7 +80,7 @@ class RetailcrmApiResponse implements ArrayAccess $propertyName = strtolower(substr($name, 3, 1)) . substr($name, 4); if (!isset($this->response[$propertyName])) { - throw new InvalidArgumentException("Method \"$name\" not found"); + throw new \InvalidArgumentException("Method \"$name\" not found"); } return $this->response[$propertyName]; @@ -69,37 +89,53 @@ class RetailcrmApiResponse implements ArrayAccess /** * Allow to access for the property throw object property * - * @param string $name + * @param string $name property name + * + * @throws \InvalidArgumentException + * * @return mixed */ public function __get($name) { if (!isset($this->response[$name])) { - throw new InvalidArgumentException("Property \"$name\" not found"); + throw new \InvalidArgumentException("Property \"$name\" not found"); } return $this->response[$name]; } /** - * @param mixed $offset - * @param mixed $value + * Offset set + * + * @param mixed $offset offset + * @param mixed $value value + * + * @throws \BadMethodCallException + * @return void */ public function offsetSet($offset, $value) { - throw new BadMethodCallException('This activity not allowed'); + throw new \BadMethodCallException('This activity not allowed'); } /** - * @param mixed $offset + * Offset unset + * + * @param mixed $offset offset + * + * @throws \BadMethodCallException + * @return void */ public function offsetUnset($offset) { - throw new BadMethodCallException('This call not allowed'); + throw new \BadMethodCallException('This call not allowed'); } /** - * @param mixed $offset + * Check offset + * + * @param mixed $offset offset + * * @return bool */ public function offsetExists($offset) @@ -108,13 +144,18 @@ class RetailcrmApiResponse implements ArrayAccess } /** - * @param mixed $offset + * Get offset + * + * @param mixed $offset offset + * + * @throws \InvalidArgumentException + * * @return mixed */ public function offsetGet($offset) { if (!isset($this->response[$offset])) { - throw new InvalidArgumentException("Property \"$offset\" not found"); + throw new \InvalidArgumentException("Property \"$offset\" not found"); } return $this->response[$offset]; diff --git a/system/library/retailcrm/RetailcrmHistoryHelper.php b/system/library/retailcrm/RetailcrmHistoryHelper.php new file mode 100644 index 0000000..bc5a718 --- /dev/null +++ b/system/library/retailcrm/RetailcrmHistoryHelper.php @@ -0,0 +1,108 @@ +fields->field as $object) { + $fields[(string)$object["group"]][(string)$object["id"]] = (string)$object; + } + } + $orders = array(); + foreach ($orderHistory as $change) { + $change['order'] = self::removeEmpty($change['order']); + if($change['order']['items']) { + $items = array(); + foreach($change['order']['items'] as $item) { + if(isset($change['created'])) { + $item['create'] = 1; + } + $items[$item['id']] = $item; + } + $change['order']['items'] = $items; + } + + if($change['order']['contragent']['contragentType']) { + $change['order']['contragentType'] = $change['order']['contragent']['contragentType']; + unset($change['order']['contragent']); + } + + if($orders[$change['order']['id']]) { + $orders[$change['order']['id']] = array_merge($orders[$change['order']['id']], $change['order']); + } else { + $orders[$change['order']['id']] = $change['order']; + } + + if($change['item']) { + if($orders[$change['order']['id']]['items'][$change['item']['id']]) { + $orders[$change['order']['id']]['items'][$change['item']['id']] = array_merge($orders[$change['order']['id']]['items'][$change['item']['id']], $change['item']); + } else { + $orders[$change['order']['id']]['items'][$change['item']['id']] = $change['item']; + } + + if(empty($change['oldValue']) && $change['field'] == 'order_product') { + $orders[$change['order']['id']]['items'][$change['item']['id']]['create'] = true; + } + if(empty($change['newValue']) && $change['field'] == 'order_product') { + $orders[$change['order']['id']]['items'][$change['item']['id']]['delete'] = true; + } + if(!$orders[$change['order']['id']]['items'][$change['item']['id']]['create'] && $fields['item'][$change['field']]) { + $orders[$change['order']['id']]['items'][$change['item']['id']][$fields['item'][$change['field']]] = $change['newValue']; + } + } else { + if($fields['delivery'][$change['field']] == 'service') { + $orders[$change['order']['id']]['delivery']['service']['code'] = self::newValue($change['newValue']); + } elseif($fields['delivery'][$change['field']]) { + $orders[$change['order']['id']]['delivery'][$fields['delivery'][$change['field']]] = self::newValue($change['newValue']); + } elseif($fields['orderAddress'][$change['field']]) { + $orders[$change['order']['id']]['delivery']['address'][$fields['orderAddress'][$change['field']]] = $change['newValue']; + } elseif($fields['integrationDelivery'][$change['field']]) { + $orders[$change['order']['id']]['delivery']['service'][$fields['integrationDelivery'][$change['field']]] = self::newValue($change['newValue']); + } elseif($fields['customerContragent'][$change['field']]) { + $orders[$change['order']['id']][$fields['customerContragent'][$change['field']]] = self::newValue($change['newValue']); + } elseif(strripos($change['field'], 'custom_') !== false) { + $orders[$change['order']['id']]['customFields'][str_replace('custom_', '', $change['field'])] = self::newValue($change['newValue']); + } elseif($fields['order'][$change['field']]) { + $orders[$change['order']['id']][$fields['order'][$change['field']]] = self::newValue($change['newValue']); + } + + if(isset($change['created'])) { + $orders[$change['order']['id']]['create'] = 1; + } + + if(isset($change['deleted'])) { + $orders[$change['order']['id']]['deleted'] = 1; + } + } + } + + return $orders; + } + + public static function newValue($value) + { + if(isset($value['code'])) { + return $value['code']; + } else { + return $value; + } + } + + public static function removeEmpty($inputArray) + { + $outputArray = array(); + if (!empty($inputArray)) { + foreach ($inputArray as $key => $element) { + if(!empty($element) || $element === 0 || $element === '0'){ + if (is_array($element)) { + $element = self::removeEmpty($element); + } + $outputArray[$key] = $element; + } + } + } + + return $outputArray; + } +} diff --git a/system/library/retailcrm/RetailcrmHttpClient.php b/system/library/retailcrm/RetailcrmHttpClient.php index 6f74d16..6ec0e5c 100644 --- a/system/library/retailcrm/RetailcrmHttpClient.php +++ b/system/library/retailcrm/RetailcrmHttpClient.php @@ -1,6 +1,14 @@ + * @license https://opensource.org/licenses/MIT MIT License + * @link http://www.retailcrm.ru/docs/Developers/ApiVersion4 */ class RetailcrmHttpClient { @@ -9,95 +17,88 @@ class RetailcrmHttpClient protected $url; protected $defaultParameters; - protected $retry; + /** + * Client constructor. + * + * @param string $url api url + * @param array $defaultParameters array of parameters + * + * @throws \InvalidArgumentException + */ public function __construct($url, array $defaultParameters = array()) { if (false === stripos($url, 'https://')) { - throw new InvalidArgumentException('API schema requires HTTPS protocol'); + throw new \InvalidArgumentException( + 'API schema requires HTTPS protocol' + ); } $this->url = $url; $this->defaultParameters = $defaultParameters; - $this->retry = 0; } /** * Make HTTP request * - * @param string $path - * @param string $method (default: 'GET') - * @param array $parameters (default: array()) - * @param int $timeout - * @param bool $verify - * @param bool $debug - * @return RetailcrmApiResponse + * @param string $path request url + * @param string $method (default: 'GET') + * @param array $parameters (default: array()) + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * + * @throws \InvalidArgumentException + * @throws CurlException + * @throws InvalidJsonException + * + * @return ApiResponse */ public function makeRequest( $path, $method, - array $parameters = array(), - $timeout = 30, - $verify = false, - $debug = false + array $parameters = array() ) { $allowedMethods = array(self::METHOD_GET, self::METHOD_POST); - if (!in_array($method, $allowedMethods)) { - throw new InvalidArgumentException(sprintf( - 'Method "%s" is not valid. Allowed methods are %s', - $method, - implode(', ', $allowedMethods) - )); + + if (!in_array($method, $allowedMethods, false)) { + throw new \InvalidArgumentException( + sprintf( + 'Method "%s" is not valid. Allowed methods are %s', + $method, + implode(', ', $allowedMethods) + ) + ); } $parameters = array_merge($this->defaultParameters, $parameters); $url = $this->url . $path; - if (self::METHOD_GET === $method && sizeof($parameters)) { + if (self::METHOD_GET === $method && count($parameters)) { $url .= '?' . http_build_query($parameters, '', '&'); } - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($ch, CURLOPT_FAILONERROR, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $verify); - - if (!$debug) { - curl_setopt($ch, CURLOPT_TIMEOUT, (int) $timeout); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, (int) $timeout); - } else { - curl_setopt($ch, CURLOPT_TIMEOUT_MS, (int) $timeout + ($this->retry * 2000)); - } + $curlHandler = curl_init(); + curl_setopt($curlHandler, CURLOPT_URL, $url); + curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curlHandler, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($curlHandler, CURLOPT_FAILONERROR, false); + curl_setopt($curlHandler, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curlHandler, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curlHandler, CURLOPT_TIMEOUT, 30); + curl_setopt($curlHandler, CURLOPT_CONNECTTIMEOUT, 30); if (self::METHOD_POST === $method) { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters); + curl_setopt($curlHandler, CURLOPT_POST, true); + curl_setopt($curlHandler, CURLOPT_POSTFIELDS, $parameters); } - $responseBody = curl_exec($ch); - $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - $errno = curl_errno($ch); - $error = curl_error($ch); + $responseBody = curl_exec($curlHandler); + $statusCode = curl_getinfo($curlHandler, CURLINFO_HTTP_CODE); + $errno = curl_errno($curlHandler); + $error = curl_error($curlHandler); - curl_close($ch); - - if ($errno && in_array($errno, array(6, 7, 28, 34, 35)) && $this->retry < 3) { - $errno = null; - $error = null; - $this->retry += 1; - $this->makeRequest( - $path, - $method, - $parameters, - $timeout, - $verify, - $debug - ); - } + curl_close($curlHandler); if ($errno) { throw new CurlException($error, $errno); @@ -105,9 +106,4 @@ class RetailcrmHttpClient return new RetailcrmApiResponse($statusCode, $responseBody); } - - public function getRetry() - { - return $this->retry; - } } diff --git a/system/library/retailcrm/objects.xml b/system/library/retailcrm/objects.xml new file mode 100644 index 0000000..4f4996e --- /dev/null +++ b/system/library/retailcrm/objects.xml @@ -0,0 +1,99 @@ + + + + id + firstName + lastName + patronymic + email + birthday + phones + manager + commentary + externalId + cumulativeDiscount + personalDiscount + discountCardNumber + + index + country + region + city + street + building + house + block + flat + floor + intercomCode + metro + notes + + contragentType + legalName + legalAddress + certificateNumber + certificateDate + bank + bankAddress + corrAccount + bankAccount + + id + createdAt + orderType + orderMethod + site + status + manager + firstName + lastName + patronymic + phone + additionalPhone + email + paymentType + paymentStatus + discount + discountPercent + prepaySum + customerComment + managerComment + shipmentStore + shipmentDate + shipped + + + id + initialPrice + discount + discountPercent + quantity + status + + code + service + date + time + cost + netCost + + country + index + region + city + street + building + house + block + flat + floor + intercomCode + metro + notes + + status + trackNumber + courier + + \ No newline at end of file