diff --git a/README.ru.md b/README.ru.md index 7d6e01e..a3f752a 100644 --- a/README.ru.md +++ b/README.ru.md @@ -34,3 +34,13 @@ Prestashop module ``` /usr/bin/php /path/to/your/site/modules/retailcrm/job/export.php ``` + +#### Рекомендации + +Для более полной выгрузки заказов из CRM в магазин рекомендуется заполнять следующие поля: + +1. Покупатель +..* Фамилия - если не указано, то в магазин выгрузится в виде прочерка(дефиса). +..* E-mail - если не указано, то в магазин выгрузится в виде md5(Имя)@retailcrm.ru +2. Доставка + diff --git a/retailcrm/job/export.php b/retailcrm/job/export.php index 24b5303..dbb23ea 100644 --- a/retailcrm/job/export.php +++ b/retailcrm/job/export.php @@ -1,4 +1,5 @@ ordersHistory(new DateTime($startFrom)); +$startDate = new DateTime($startFrom); +$history = $api->ordersHistory(array( + 'startDate' => $startDate->format('Y-m-d H:i:s') +)); -if ($history->isSuccessful() && count($history->orders) > 0) { +if ($history->isSuccessful() && count($history->history) > 0) { $statuses = array_flip(array_filter(json_decode(Configuration::get('RETAILCRM_API_STATUS'), true))); $deliveries = array_flip(array_filter(json_decode(Configuration::get('RETAILCRM_API_DELIVERY'), true))); $payments = array_flip(array_filter(json_decode(Configuration::get('RETAILCRM_API_PAYMENT'), true))); - foreach ($history->orders as $order) { + $orders = RetailcrmHistoryHelper::assemblyOrder($history->history); + + foreach ($orders as $order) { if (isset($order['deleted']) && $order['deleted'] == true) continue; if (!array_key_exists('externalId', $order)) { - $customer = new Customer(); - $customer->getByEmail($order['customer']['email']); + if(!empty($order['customer']['email'])) + $customer->getByEmail($order['customer']['email']); - if ( - !array_key_exists('externalId', $order['customer']) && - Validate::isEmail($order['customer']['email']) - ) { + if (!array_key_exists('externalId', $order['customer'])) { if (!$customer->id) { $customer->firstname = $order['customer']['firstName']; - $customer->lastname = $order['customer']['lastName']; - $customer->email = $order['customer']['email']; + $customer->lastname = !empty($order['customer']['lastName']) ? $order['customer']['lastName'] : '-'; + $customer->email = Validate::isEmail($order['customer']['email']) ? $order['customer']['email'] : md5($order['customer']['firstName']) . '@retailcrm.ru'; $customer->passwd = substr(str_shuffle(strtolower(sha1(rand() . time()))),0, 5); - if($customer->add()) { - $address = new Address(); - $address->id_customer = $customer->id; - $address->id_country = $default_country; - $address->lastname = $customer->lastname; - $address->firstname = $customer->firstname; - $address->alias = 'default'; - $address->postcode = $order['address']['index']; - $address->city = $order['address']['city']; - $address->address1 = $order['address']['text']; - $address->phone = $order['phone']; - $address->add(); - } + $customer->add(); } array_push( @@ -80,6 +70,18 @@ if ($history->isSuccessful() && count($history->orders) > 0) { ); } + $address = new Address(); + $address->id_customer = $customer->id; + $address->id_country = $default_country; + $address->lastname = $customer->lastname; + $address->firstname = $customer->firstname; + $address->alias = 'default'; + $address->postcode = $order['delivery']['address']['index']; + $address->city = !empty($order['delivery']['address']['city']) ? $order['delivery']['address']['city'] : '-'; + $address->address1 = !empty($order['delivery']['address']['text']) ? $order['delivery']['address']['text'] : '-'; + $address->phone = $order['phone']; + $address->add(); + $delivery = $order['delivery']['code']; if (array_key_exists($delivery, $deliveries) && $deliveries[$delivery] != '') { @@ -89,7 +91,11 @@ if ($history->isSuccessful() && count($history->orders) > 0) { $payment = $order['paymentType']; if (array_key_exists($payment, $payments) && $payments[$payment] != '') { - $paymentType = $payments[$payment]; + if(Module::getInstanceByName($payments[$payment])) { + $paymentType = Module::getModuleName($payments[$payment]); + } else { + $paymentType = $payments[$payment]; + } } $state = $order['status']; @@ -102,8 +108,8 @@ if ($history->isSuccessful() && count($history->orders) > 0) { $cart->id_currency = $default_currency; $cart->id_lang = $default_lang; $cart->id_customer = $customer->id; - $cart->id_address_delivery = (int) $address_id; - $cart->id_address_invoice = (int) $address_id; + $cart->id_address_delivery = (int) $address->id; + $cart->id_address_invoice = (int) $address->id; $cart->id_carrier = (int) $deliveries[$delivery]; $cart->add(); @@ -112,10 +118,13 @@ if ($history->isSuccessful() && count($history->orders) > 0) { if(!empty($order['items'])) { foreach ($order['items'] as $item) { + $productId = explode('#', $item['offer']['externalId']); + $product = array(); - $product['id_product'] = (int) $item['offer']['externalId']; + $product['id_product'] = (int) $productId[0]; + $product['id_product_attribute'] = !empty($productId[1]) ? $productId[1] : 0; $product['quantity'] = $item['quantity']; - $product['id_address_delivery'] = (int) $address_id; + $product['id_address_delivery'] = (int) $address->id; $products[] = $product; } } @@ -127,19 +136,20 @@ if ($history->isSuccessful() && count($history->orders) > 0) { * Create order */ $newOrder = new Order(); - $newOrder->id_address_delivery = (int) $address_id; - $newOrder->id_address_invoice = (int) $address_id; + $shops = Shop::getShops(); + $newOrder->id_shop = Shop::getCurrentShop(); + $newOrder->id_shop_group = (int)$shops[Shop::getCurrentShop()]['id_shop_group']; + + $newOrder->id_address_delivery = (int) $address->id; + $newOrder->id_address_invoice = (int) $address->id; $newOrder->id_cart = (int) $cart->id; $newOrder->id_currency = $default_currency; $newOrder->id_lang = $default_lang; $newOrder->id_customer = (int) $customer->id; if (isset($deliveryType)) $newOrder->id_carrier = (int) $deliveryType; - $newOrder->payment = $payments[$payment]; if (isset($paymentType)) { - $newOrder->module = (Module::getInstanceByName('advancedcheckout') === false) - ? $paymentType - : 'advancedcheckout' - ; + $newOrder->payment = $paymentType; + $newOrder->module = $payments[$payment]; } $newOrder->total_paid = $order['summ'] + $order['delivery']['cost']; $newOrder->total_paid_tax_incl = $order['summ'] + $order['delivery']['cost']; @@ -155,6 +165,7 @@ if ($history->isSuccessful() && count($history->orders) > 0) { if (!empty($order['delivery']['date'])) $newOrder->delivery_date = $order['delivery']['date']; $newOrder->date_add = $order['createdAt']; $newOrder->date_upd = $order['createdAt']; + $newOrder->invoice_date = $order['createdAt']; $newOrder->valid = 1; $newOrder->secure_key = md5(time()); @@ -165,6 +176,14 @@ if ($history->isSuccessful() && count($history->orders) > 0) { $newOrder->add(false, false); + $carrier = new OrderCarrierCore(); + $carrier->id_order = $newOrder->id; + $carrier->id_carrier = $deliveryType; + $carrier->shipping_cost_tax_excl = $order['delivery']['cost']; + $carrier->shipping_cost_tax_incl = $order['delivery']['cost']; + $carrier->date_add = $order['delivery']['date']; + $carrier->add(false, false); + /* * collect order ids for single fix request */ @@ -177,8 +196,31 @@ if ($history->isSuccessful() && count($history->orders) > 0) { foreach ($order['items'] as $item) { $product = new Product((int) $item['offer']['externalId'], false, $default_lang); - $qty = $item['quantity']; - $product_list[] = array('product' => $product, 'quantity' => $qty); + $product_id = $item['offer']['externalId']; + $product_attribute_id = 0; + if(strpos($item['offer']['externalId'], '#') !== false) { + $product_id = explode('#', $item['offer']['externalId']); + $product_attribute_id = $product_id[1]; + $product_id = $product_id[0]; + } + + if($product_attribute_id != 0) { + $productName = htmlspecialchars(strip_tags(Product::getProductName($product_id, $product_attribute_id))); + + $productPrice = Combination::getPrice($product_attribute_id); + $productPrice = $productPrice > 0 ? $productPrice : $product->price; + } else { + $productName = htmlspecialchars(strip_tags($product->name)); + $productPrice = $product->price; + } + + $product_list[] = array( + 'product' => $product, + 'product_attribute_id' => $product_attribute_id, + 'product_price' => $productPrice, + 'product_name' => $productName, + 'quantity' => $item['quantity'] + ); } $query = 'INSERT `'._DB_PREFIX_.'order_detail` @@ -198,201 +240,281 @@ if ($history->isSuccessful() && count($history->orders) > 0) { 0, '. Context::getContext()->shop->id.', '.(int) $product['product']->id.', - 0, - '.implode('', array('\'', $product['product']->name, '\'')).', + '.$product['product_attribute_id'].', + '.implode('', array('\'', $product['product_name'], '\'')).', '.(int) $product['quantity'].', '.(int) $product['quantity'].', - '.$product['product']->price.', + '.$product['product_price'].', '.implode('', array('\'', $product['product']->reference, '\'')).', - '.$product['product']->price.', - '.$product['product']->price.', - '.$product['product']->price.', - '.$product['product']->price.', - '.$product['product']->price.' + '.$product['product_price'].', + '.$product['product_price'].', + '.$product['product_price'].', + '.$product['product_price'].', + '.$product['product_price'].' ),'; } Db::getInstance()->execute(rtrim($query, ',')); - $api->customersFixExternalIds($customerFix); - $api->ordersFixExternalIds($orderFix); + if(!empty($customerFix)) + $api->customersFixExternalIds($customerFix); + if(!empty($orderFix)) + $api->ordersFixExternalIds($orderFix); } else { - /* - * take last order update only - */ - if (!empty($order['paymentType']) && - !empty($order['delivery']['code']) && - !empty($order['status']) - ) { - $orderToUpdate = new Order((int) $order['externalId']); + $orderToUpdate = new Order((int) $order['externalId']); - /* - * check status - */ + /* + * check status + */ + if(!empty($order['status'])) { $stype = $order['status']; + if ($statuses[$stype] != null) { if ($statuses[$stype] != $orderToUpdate->current_state) { Db::getInstance()->execute(' - UPDATE `'._DB_PREFIX_.'orders` - SET `current_state` = \''.$statuses[$stype].'\' - WHERE `id_order` = '.(int) $order['externalId'] + INSERT INTO `' . _DB_PREFIX_ . 'order_history` (`id_employee`, `id_order`, `id_order_state`, `date_add`) + VALUES ( + 0, + ' . $orderToUpdate->id . ', + ' . $statuses[$stype] . ', + "' . date('Y-m-d H:i:s') . '" + ) + '); + + Db::getInstance()->execute(' + UPDATE `' . _DB_PREFIX_ . 'orders` + SET `current_state` = \'' . $statuses[$stype] . '\' + WHERE `id_order` = ' . (int)$order['externalId'] ); } } + } - /* - * check delivery type - */ + /* + * check delivery type + */ + if(!empty($order['delivery']['code'])) { $dtype = $order['delivery']['code']; + $dcost = !empty($order['delivery']['cost']) ? $order['delivery']['cost'] : null; + if ($deliveries[$dtype] != null) { - if ($deliveries[$dtype] != $orderToUpdate->id_carrier) { + if ($deliveries[$dtype] != $orderToUpdate->id_carrier OR $dcost != null) { + + if($dtype != null) { + Db::getInstance()->execute(' + UPDATE `' . _DB_PREFIX_ . 'orders` + SET `id_carrier` = \'' . $deliveries[$dtype] . '\' + WHERE `id_order` = ' . (int)$order['externalId'] + ); + } + + $updateCarrierFields = array(); + if($dtype != null) { + $updateCarrierFields[] = '`id_carrier` = \'' . $deliveries[$dtype] . '\' '; + } + if($dcost != null) { + $updateCarrierFields[] = '`shipping_cost_tax_incl` = \'' . $dcost . '\' '; + $updateCarrierFields[] = '`shipping_cost_tax_excl` = \'' . $dcost . '\' '; + } + $updateCarrierFields = implode(', ', $updateCarrierFields); + Db::getInstance()->execute(' - UPDATE `'._DB_PREFIX_.'orders` - SET `id_carrier` = \''.$deliveries[$dtype].'\' - WHERE `id_order` = '.(int) $order['externalId'] - ); - Db::getInstance()->execute(' - UPDATE `'._DB_PREFIX_.'order_carrier` - SET `id_carrier` = \''.$deliveries[$dtype].'\' - WHERE `id_order` = \''.$orderToUpdate->id.'\'' + UPDATE `' . _DB_PREFIX_ . 'order_carrier` SET + '.$updateCarrierFields.' + WHERE `id_order` = \'' . $orderToUpdate->id . '\'' ); } } + } - /* - * check payment type - */ + /* + * check payment type + */ + if(!empty($order['paymentType'])) { $ptype = $order['paymentType']; + if ($payments[$ptype] != null) { if ($payments[$ptype] != $orderToUpdate->payment) { Db::getInstance()->execute(' - UPDATE `'._DB_PREFIX_.'orders` - SET `payment` = \''.$payments[$ptype].'\' - WHERE `id_order` = '.(int) $order['externalId'] + UPDATE `' . _DB_PREFIX_ . 'orders` + SET `payment` = \'' . $payments[$ptype] . '\' + WHERE `id_order` = ' . (int)$order['externalId'] ); Db::getInstance()->execute(' - UPDATE `'._DB_PREFIX_.'order_payment` - SET `payment_method` = \''.$payments[$ptype].'\' - WHERE `order_reference` = \''.$orderToUpdate->reference.'\'' + UPDATE `' . _DB_PREFIX_ . 'order_payment` + SET `payment_method` = \'' . $payments[$ptype] . '\' + WHERE `order_reference` = \'' . $orderToUpdate->reference . '\'' ); } } + } - /* - * Clean deleted items - */ + /* + * Clean deleted items + */ + foreach ($order['items'] as $key => $item) { + if (isset($item['deleted']) && $item['deleted'] == true) { + if(strpos($item['id'], '#') !== false) { + $itemId = explode('#', $item['id']); + $product_id = $itemId[0]; + $product_attribute_id = $itemId[1]; + } else { + $product_id = $item['id']; + $product_attribute_id = 0; + } + + Db::getInstance()->execute(' + DELETE FROM `'._DB_PREFIX_.'order_detail` + WHERE `id_order` = '. $orderToUpdate->id .' + AND `product_id` = '.$product_id. ' + AND `product_attribute_id` = '.$product_attribute_id + ); + + unset($order['items'][$key]); + } + } + + /* + * Check items quantity + */ + foreach ($orderToUpdate->getProductsDetail() as $orderItem) { foreach ($order['items'] as $key => $item) { - if (isset($item['deleted']) && $item['deleted'] == true) { - Db::getInstance()->execute(' - DELETE FROM `'._DB_PREFIX_.'order_detail` - WHERE `id_order` = '. $orderToUpdate->id .' - AND `product_id` = '.$item['id'] - ); + if(strpos($item['offer']['externalId'], '#') !== false) { + $itemId = explode('#', $item['offer']['externalId']); + $product_id = $itemId[0]; + $product_attribute_id = $itemId[1]; + } else { + $product_id = $item['offer']['externalId']; + $product_attribute_id = 0; + } + + if ($product_id == $orderItem['product_id'] && $product_attribute_id == $orderItem['product_attribute_id']) { + if (isset($item['quantity']) && $item['quantity'] != $orderItem['product_quantity']) { + Db::getInstance()->execute(' + UPDATE `'._DB_PREFIX_.'order_detail` + SET `product_quantity` = '.$item['quantity'].', + `product_quantity_in_stock` = '.$item['quantity'].' + WHERE `id_order_detail` = '.$orderItem['id_order_detail'] + ); + } unset($order['items'][$key]); } } + } - /* - * Check items quantity - */ - foreach ($orderToUpdate->getProductsDetail() as $orderItem) { - foreach ($order['items'] as $key => $item) { - if ($item['offer']['externalId'] == $orderItem['product_id']) { - if (isset($item['quantity']) && $item['quantity'] != $orderItem['product_quantity']) { - Db::getInstance()->execute(' - UPDATE `'._DB_PREFIX_.'order_detail` - SET `product_quantity` = '.$item['quantity'].', - `product_quantity_in_stock` = '.$item['quantity'].' - WHERE `id_order_detail` = '.$orderItem['id_order_detail'] - ); - } + /* + * Check new items + */ + if (!empty($order['items'])) { + $query = 'INSERT `'._DB_PREFIX_.'order_detail` + ( + `id_order`, `id_order_invoice`, `id_shop`, `product_id`, `product_attribute_id`, + `product_name`, `product_quantity`, `product_quantity_in_stock`, `product_price`, + `product_reference`, `total_price_tax_excl`, `total_price_tax_incl`, + `unit_price_tax_excl`, `unit_price_tax_incl`, `original_product_price` + ) - unset($order['items'][$key]); - } - } - } + VALUES'; - /* - * Check new items - */ - if (!empty($order['items'])) { - foreach ($order['items'] as $key => $newItem) { - $product = new Product((int) $newItem['offer']['externalId'], false, $default_lang); - $qty = $newItem['quantity']; - $product_list[] = array('product' =>$product, 'quantity' => $qty); + foreach ($order['items'] as $key => $newItem) { + $product_id = $newItem['offer']['externalId']; + $product_attribute_id = 0; + if(strpos($product_id, '#') !== false) { + $product_id = explode('#', $product_id); + + $product_attribute_id = $product_id[1]; + $product_id = $product_id[0]; } + $product = new Product((int) $product_id, false, $default_lang); - $query = 'INSERT `'._DB_PREFIX_.'order_detail` - ( - `id_order`, `id_order_invoice`, `id_shop`, `product_id`, `product_attribute_id`, - `product_name`, `product_quantity`, `product_quantity_in_stock`, `product_price`, - `product_reference`, `total_price_tax_excl`, `total_price_tax_incl`, - `unit_price_tax_excl`, `unit_price_tax_incl`, `original_product_price` - ) + if($product_attribute_id != 0) { + $productName = htmlspecialchars(strip_tags(Product::getProductName($product_id, $product_attribute_id))); - VALUES'; - - foreach ($product_list as $product) { - $query .= '(' - .(int) $orderToUpdate->id.', - 0, - '. Context::getContext()->shop->id.', - '.(int) $product['product']->id.', - 0, - '.implode('', array('\'', $product['product']->name, '\'')).', - '.(int) $product['quantity'].', - '.(int) $product['quantity'].', - '.$product['product']->price.', - '.implode('', array('\'', $product['product']->reference, '\'')).', - '.$product['product']->price.', - '.$product['product']->price.', - '.$product['product']->price.', - '.$product['product']->price.', - '.$product['product']->price.' - ),'; + $productPrice = Combination::getPrice($product_attribute_id); + $productPrice = $productPrice > 0 ? $productPrice : $product->price; + } else { + $productName = htmlspecialchars(strip_tags($product->name)); + $productPrice = $product->price; } - Db::getInstance()->execute(rtrim($query, ',')); + $query .= '(' + .(int) $orderToUpdate->id.', + 0, + '. Context::getContext()->shop->id.', + '.(int) $product_id.', + '.(int) $product_attribute_id.', + '.implode('', array('\'', $productName, '\'')).', + '.(int) $newItem['quantity'].', + '.(int) $newItem['quantity'].', + '.$productPrice.', + '.implode('', array('\'', $product->reference, '\'')).', + '.$productPrice * $newItem['quantity'].', + '.($productPrice + $productPrice / 100 * 18) * $newItem['quantity'].', + '.$productPrice.', + '.($productPrice + $productPrice / 100 * 18).', + '.$productPrice.' + ),'; + unset($order['items'][$key]); } - /* - * Fix prices & discounts - * Discounts only for whole order - */ - $orderDiscout = null; - $orderTotal = $order['summ']; + Db::getInstance()->execute(rtrim($query, ',')); + } - if (isset($order['discount']) && $order['discount'] > 0) { - if ($order['discount'] != $orderToUpdate->total_discounts) { - $orderDiscout = ($orderDiscout == null) ? $order['discount'] : $order['discount'] + $orderDiscout; - } + /* + * Fix prices & discounts + * Discounts only for whole order + */ + $orderDiscout = null; + $orderTotalProducts = 0; + foreach($orderToUpdate->getProductsDetail() as $orderItem) { + $orderTotalProducts += $orderItem['total_price_tax_incl']; + } + $orderTotalProducts = round($orderTotalProducts, 2); + + if (isset($order['discount']) && $order['discount'] > 0) { + if ($order['discount'] != $orderToUpdate->total_discounts) { + $orderDiscout = ($orderDiscout == null) ? $order['discount'] : $order['discount'] + $orderDiscout; } + } - if (isset($order['discountPercent']) && $order['discountPercent'] > 0) { - $percent = ($order['summ'] * $order['discountPercent'])/100; - if ($percent != $orderToUpdate->total_discounts) { - $orderDiscout = ($orderDiscout == null) ? $percent : $percent + $orderDiscout; - } + if (isset($order['discountPercent']) && $order['discountPercent'] > 0) { + $percent = ($order['summ'] * $order['discountPercent'])/100; + if ($percent != $orderToUpdate->total_discounts) { + $orderDiscout = ($orderDiscout == null) ? $percent : $percent + $orderDiscout; } + } - $totalDiscount = ($orderDiscout == null) ? $orderToUpdate->total_discounts : $orderDiscout; + $totalDiscount = ($orderDiscout == null) ? $orderToUpdate->total_discounts : $orderDiscout; - if ($totalDiscount != $orderToUpdate->total_discounts || $orderTotal != $orderToUpdate->total_paid) { - Db::getInstance()->execute(' - UPDATE `'._DB_PREFIX_.'orders` - SET `total_discounts` = '.$totalDiscount.', - `total_discounts_tax_incl` = '.$totalDiscount.', - `total_discounts_tax_excl` = '.$totalDiscount.', - `total_paid` = '.$orderTotal.', - `total_paid_tax_incl` = '.$orderTotal.', - `total_paid_tax_excl` = '.$orderTotal.' - WHERE `id_order` = '.(int) $order['externalId'] - ); - } + $deliveryCost = $orderToUpdate->total_shipping; + if(!empty($order['delivery']['cost'])) { + $deliveryCost = $order['delivery']['cost']; + } + + $totalPaid = $deliveryCost + $orderTotalProducts; + + if ($totalDiscount != $orderToUpdate->total_discounts || + $orderTotalProducts != $orderToUpdate->total_products_wt || + $deliveryCost != $orderToUpdate->total_shipping + ) { + Db::getInstance()->execute(' + UPDATE `'._DB_PREFIX_.'orders` + SET `total_discounts` = '.$totalDiscount.', + `total_discounts_tax_incl` = '.$totalDiscount.', + `total_discounts_tax_excl` = '.$totalDiscount.', + `total_shipping` = '.$deliveryCost.', + `total_shipping_tax_incl` = '.$deliveryCost.', + `total_shipping_tax_excl` = '.$deliveryCost.', + `total_paid` = '.$totalPaid.', + `total_paid_tax_incl` = '.$totalPaid.', + `total_paid_tax_excl` = '.$totalPaid.', + `total_products_wt` = '.$orderTotalProducts.' + WHERE `id_order` = '.(int) $order['externalId'] + ); } } } diff --git a/retailcrm/lib/CurlException.php b/retailcrm/lib/CurlException.php index 2ab00f5..8b8c2fe 100644 --- a/retailcrm/lib/CurlException.php +++ b/retailcrm/lib/CurlException.php @@ -1,5 +1,15 @@ + * @license https://opensource.org/licenses/MIT MIT License + * @link http://www.retailcrm.ru/docs/Developers/ApiVersion4 + */ +class CurlException extends \RuntimeException { } diff --git a/retailcrm/lib/InvalidJsonException.php b/retailcrm/lib/InvalidJsonException.php index 66a1105..8438051 100644 --- a/retailcrm/lib/InvalidJsonException.php +++ b/retailcrm/lib/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/retailcrm/lib/RetailcrmApiClient.php b/retailcrm/lib/RetailcrmApiClient.php index 656c270..f2ddbfb 100644 --- a/retailcrm/lib/RetailcrmApiClient.php +++ b/retailcrm/lib/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", Client::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/retailcrm/lib/RetailcrmApiResponse.php b/retailcrm/lib/RetailcrmApiResponse.php index bba91db..67a7517 100644 --- a/retailcrm/lib/RetailcrmApiResponse.php +++ b/retailcrm/lib/RetailcrmApiResponse.php @@ -1,8 +1,16 @@ + * @license https://opensource.org/licenses/MIT MIT License + * @link http://www.retailcrm.ru/docs/Developers/ApiVersion4 */ -class RetailcrmApiResponse implements ArrayAccess +class RetailcrmApiResponse implements \ArrayAccess { // HTTP response status code protected $statusCode; @@ -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/retailcrm/lib/RetailcrmCatalog.php b/retailcrm/lib/RetailcrmCatalog.php index a1808b1..939ec97 100644 --- a/retailcrm/lib/RetailcrmCatalog.php +++ b/retailcrm/lib/RetailcrmCatalog.php @@ -12,7 +12,6 @@ class RetailcrmCatalog public function getData() { - $id_lang = (int) Configuration::get('PS_LANG_DEFAULT'); $currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT')); $shop_url = (Configuration::get('PS_SSL_ENABLED') ? _PS_BASE_URL_SSL_ : _PS_BASE_URL_); @@ -35,6 +34,8 @@ class RetailcrmCatalog ); } + $link = new Link(); + $products = Product::getProducts($id_lang, 0, 0, 'name', 'asc'); foreach ($products AS $product) { @@ -53,78 +54,133 @@ class RetailcrmCatalog } } - $link = new Link(); - $cover = Image::getCover($product['id_product']); - - $picture = 'http://' . $link->getImageLink($product['link_rewrite'], $product['id_product'] . '-' . $cover['id_image'], 'large_default'); - if (!(substr($picture, 0, strlen($shop_url)) === $shop_url)) { - $picture = rtrim($shop_url, "/") . $picture; + $version = substr(_PS_VERSION_, 0, 3); + if ($version == "1.3") { + $available_for_order = $product['active'] && $product['quantity']; + } else { + $available_for_order = $product['active'] && $product['available_for_order']; } $crewrite = Category::getLinkRewrite($product['id_category_default'], $id_lang); $url = $link->getProductLink($product['id_product'], $product['link_rewrite'], $crewrite); - $version = substr(_PS_VERSION_, 0, 3); - - if ($version == "1.3") { - $available_for_order = $product['active'] && $product['quantity']; - $quantity = $product['quantity']; - } else { - $prod = new Product($product['id_product']); - $available_for_order = $product['active'] && $product['available_for_order'] && $prod->checkQty(1); - $quantity = (int) StockAvailable::getQuantityAvailableByProduct($prod->id); - } - - $item = array( - 'id' => $product['id_product'], - 'productId' => $product['id_product'], - 'productActivity' => ($available_for_order) ? 'Y' : 'N', - 'name' => htmlspecialchars(strip_tags($product['name'])), - 'productName' => htmlspecialchars(strip_tags($product['name'])), - 'categoryId' => array($category), - 'picture' => $picture, - 'url' => $url, - 'quantity' => $quantity > 0 ? $quantity : 0 - ); if (!empty($product['wholesale_price'])) { - $item['purchasePrice'] = round($product['wholesale_price'], 2); + $purchasePrice = round($product['wholesale_price'], 2); + } else { + $purchasePrice = null; } - $item['price'] = !empty($product['rate']) + $price = !empty($product['rate']) ? round($product['price'], 2) + (round($product['price'], 2) * $product['rate'] / 100) : round($product['price'], 2) - ; - + ; if (!empty($product['manufacturer_name'])) { - $item['vendor'] = $product['manufacturer_name']; + $vendor = $product['manufacturer_name']; + } else { + $vendor = null; } if (!empty($product['reference'])) { - $item['article'] = htmlspecialchars($product['reference']); + $article = htmlspecialchars($product['reference']); + } else { + $article = null; } $weight = round($product['weight'], 2); - - if (!empty($weight)) { - $item['weight'] = $weight; + if (empty($weight)) { + $weight = null; } $width = round($product['width'], 2); $height = round($product['height'], 2); $depth = round($product['depth'], 2); - if (!empty($width)) { - if (!empty($height)) { - if (!empty($depth)) { - $item['size'] = implode('x', array($width, $height, $depth)); - } else { - $item['size'] = implode('x', array($width, $height)); - } + if (!empty($width) && !empty($height)) { + if (!empty($depth)) { + $size = implode('x', array($width, $height, $depth)); + } else { + $size = implode('x', array($width, $height)); } + } else { + $size = null; + } + + $offers = Product::getProductAttributesIds($product['id_product']); + + if(!empty($offers)) { + foreach($offers as $offer) { + $pictures = array(); + $covers = Image::getImages($id_lang, $product['id_product'], $offer['id_product_attribute']); + foreach($covers as $cover) { + $picture = 'http://' . $link->getImageLink($product['link_rewrite'], $product['id_product'] . '-' . $cover['id_image'], 'large_default'); + $pictures[] = $picture; + } + + if ($version == "1.3") { + $quantity = $product['quantity']; + } else { + $quantity = (int) StockAvailable::getQuantityAvailableByProduct($product['id_product'], $offer['id_product_attribute']); + } + + $offerPrice = Combination::getPrice($offer['id_product_attribute']); + $offerPrice = $offerPrice > 0 ? $offerPrice : $price; + + $item = array( + 'id' => $product['id_product'] . '#' . $offer['id_product_attribute'], + 'productId' => $product['id_product'], + 'productActivity' => ($available_for_order) ? 'Y' : 'N', + 'name' => htmlspecialchars(strip_tags(Product::getProductName($product['id_product'], $offer['id_product_attribute']))), + 'productName' => htmlspecialchars(strip_tags($product['name'])), + 'categoryId' => array($category), + 'picture' => $pictures, + 'url' => $url, + 'quantity' => $quantity > 0 ? $quantity : 0, + 'purchasePrice' => $purchasePrice, + 'price' => round($offerPrice, 2), + 'vendor' => $vendor, + 'article' => $article, + 'weight' => $weight, + 'size' => $size + ); + + $items[] = $item; + } + } else { + $pictures = array(); + $covers = Image::getImages($id_lang, $product['id_product'], null); + foreach($covers as $cover) { + $picture = 'http://' . $link->getImageLink($product['link_rewrite'], $product['id_product'] . '-' . $cover['id_image'], 'large_default'); + $pictures[] = $picture; + } + + if ($version == "1.3") { + $quantity = $product['quantity']; + } else { + $quantity = (int) StockAvailable::getQuantityAvailableByProduct($product['id_product']); + } + + $item = array( + 'id' => $product['id_product'], + 'productId' => $product['id_product'], + 'productActivity' => ($available_for_order) ? 'Y' : 'N', + 'name' => htmlspecialchars(strip_tags($product['name'])), + 'productName' => htmlspecialchars(strip_tags($product['name'])), + 'categoryId' => array($category), + 'picture' => $pictures, + 'url' => $url, + 'quantity' => $quantity > 0 ? $quantity : 0, + 'purchasePrice' => round($purchasePrice, 2), + 'price' => $price, + 'vendor' => $vendor, + 'article' => $article, + 'weight' => $weight, + 'size' => $size + ); + + $items[] = $item; } - $items[] = $item; } return array($categories, $items); diff --git a/retailcrm/lib/RetailcrmHistoryHelper.php b/retailcrm/lib/RetailcrmHistoryHelper.php new file mode 100644 index 0000000..03a330d --- /dev/null +++ b/retailcrm/lib/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/retailcrm/lib/RetailcrmHttpClient.php b/retailcrm/lib/RetailcrmHttpClient.php index 6f74d16..6ec0e5c 100644 --- a/retailcrm/lib/RetailcrmHttpClient.php +++ b/retailcrm/lib/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/retailcrm/lib/RetailcrmIcml.php b/retailcrm/lib/RetailcrmIcml.php index 825d9c2..8c72447 100644 --- a/retailcrm/lib/RetailcrmIcml.php +++ b/retailcrm/lib/RetailcrmIcml.php @@ -113,12 +113,24 @@ class RetailcrmIcml $offerKeys = array_keys($offer); foreach ($offerKeys as $key) { + if($offer[$key] == null) continue; + if (in_array($key, $this->properties)) { - $e->appendChild( + if(is_array($offer[$key])) { + foreach($offer[$key] as $property) { + $e->appendChild( + $this->dd->createElement($key) + )->appendChild( + $this->dd->createTextNode(trim($property)) + ); + } + } else { + $e->appendChild( $this->dd->createElement($key) - )->appendChild( + )->appendChild( $this->dd->createTextNode(trim($offer[$key])) - ); + ); + } } if (in_array($key, array_keys($this->params))) { diff --git a/retailcrm/objects.xml b/retailcrm/objects.xml new file mode 100644 index 0000000..4f4996e --- /dev/null +++ b/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 diff --git a/retailcrm/retailcrm.php b/retailcrm/retailcrm.php index 580ba97..89a3980 100644 --- a/retailcrm/retailcrm.php +++ b/retailcrm/retailcrm.php @@ -20,8 +20,8 @@ class RetailCRM extends Module { $this->name = 'retailcrm'; $this->tab = 'export'; - $this->version = '2.0.1'; - $this->version = '2.0'; + $this->version = '2.1.1'; + $this->version = '2.1'; $this->author = 'Retail Driver LCC'; $this->displayName = $this->l('RetailCRM'); $this->description = $this->l('Integration module for RetailCRM'); @@ -38,7 +38,7 @@ class RetailCRM extends Module $this->bootstrap = true; } - if (!empty($this->apiUrl) && !empty($this->apiKey)) { + if ($this->validateCrmAddress($this->apiUrl) && !empty($this->apiKey)) { $this->api = new RetailcrmProxy($this->apiUrl, $this->apiKey, _PS_ROOT_DIR_ . '/retailcrm.log'); $this->reference = new RetailcrmReferences($this->api); } @@ -74,17 +74,6 @@ class RetailCRM extends Module $address = Configuration::get('RETAILCRM_ADDRESS'); $token = Configuration::get('RETAILCRM_API_TOKEN'); - if (!$address || $address == '') { - $output .= $this->displayError($this->l('Invalid or empty crm address')); - } elseif (!$token || $token == '') { - $output .= $this->displayError($this->l('Invalid or empty crm api token')); - } else { - $output .= $this->displayConfirmation( - $this->l('Timezone settings must be identical to both of your crm and shop') . - " $address/admin/settings#t-main" - ); - } - if (Tools::isSubmit('submit' . $this->name)) { $address = strval(Tools::getValue('RETAILCRM_ADDRESS')); $token = strval(Tools::getValue('RETAILCRM_API_TOKEN')); @@ -92,7 +81,7 @@ class RetailCRM extends Module $status = json_encode(Tools::getValue('RETAILCRM_API_STATUS')); $payment = json_encode(Tools::getValue('RETAILCRM_API_PAYMENT')); - if (!$address || empty($address) || !Validate::isGenericName($address)) { + if (!$this->validateCrmAddress($address) || !Validate::isGenericName($address)) { $output .= $this->displayError($this->l('Invalid crm address')); } elseif (!$token || empty($token) || !Validate::isGenericName($token)) { $output .= $this->displayError($this->l('Invalid crm api token')); @@ -103,9 +92,25 @@ class RetailCRM extends Module Configuration::updateValue('RETAILCRM_API_STATUS', $status); Configuration::updateValue('RETAILCRM_API_PAYMENT', $payment); $output .= $this->displayConfirmation($this->l('Settings updated')); + + $this->apiUrl = $address; + $this->apiKey = $token; + $this->api = new RetailcrmProxy($this->apiUrl, $this->apiKey, _PS_ROOT_DIR_ . '/retailcrm.log'); + $this->reference = new RetailcrmReferences($this->api); } } + if (!$this->validateCrmAddress($this->apiUrl)) { + $output .= $this->displayError($this->l('Invalid or empty crm address')); + } elseif (!$token || $token == '') { + $output .= $this->displayError($this->l('Invalid or empty crm api token')); + } else { + $output .= $this->displayConfirmation( + $this->l('Timezone settings must be identical to both of your crm and shop') . + " $address/admin/settings#t-main" + ); + } + $this->display(__FILE__, 'retailcrm.tpl'); return $output . $this->displayForm(); @@ -148,7 +153,7 @@ class RetailCRM extends Module ); - if (!empty($this->apiUrl) && !empty($this->apiKey)) { + if ($this->api) { /* * Delivery */ @@ -287,103 +292,116 @@ class RetailCRM extends Module if (isset($params['orderStatus'])) { - $customer = array( - 'externalId' => $params['customer']->id, - 'lastName' => $params['customer']->lastname, - 'firstName' => $params['customer']->firstname, - 'email' => $params['customer']->email, - 'createdAt' => $params['customer']->date_add - ); - - $order = array( - 'externalId' => $params['order']->id, - 'firstName' => $params['customer']->firstname, - 'lastName' => $params['customer']->lastname, - 'email' => $params['customer']->email, - 'discount' => $params['order']->total_discounts, - 'createdAt' => $params['order']->date_add, - 'delivery' => array('cost' => $params['order']->total_shipping) - ); - - $cart = new Cart($params['cart']->id); - $addressCollection = $cart->getAddressCollection(); - $address = array_shift($addressCollection); - - if ($address instanceof Address) { - $phone = is_null($address->phone) - ? is_null($address->phone_mobile) ? '' : $address->phone_mobile - : $address->phone - ; - - $postcode = $address->postcode; - $city = $address->city; - $addres_line = sprintf("%s %s", $address->address1, $address->address2); - } - - if (!empty($postcode)) { - $customer['address']['index'] = $postcode; - $order['delivery']['address']['index'] = $postcode; - } - - if (!empty($city)) { - $customer['address']['city'] = $city; - $order['delivery']['address']['city'] = $city; - } - - if (!empty($addres_line)) { - $customer['address']['text'] = $addres_line; - $order['delivery']['address']['text'] = $addres_line; - } - - if (!empty($phone)) { - $customer['phones'][] = array('number' => $phone); - $order['phone'] = $phone; - } - - foreach ($cart->getProducts() as $item) { - $order['items'][] = array( - 'initialPrice' => !empty($item['rate']) - ? $item['price'] + ($item['price'] * $item['rate'] / 100) - : $item['price'] - , - 'quantity' => $item['quantity'], - 'productId' => $item['id_product'], - 'productName' => $item['name'] + $customer = array( + 'externalId' => $params['customer']->id, + 'lastName' => $params['customer']->lastname, + 'firstName' => $params['customer']->firstname, + 'email' => $params['customer']->email, + 'createdAt' => $params['customer']->date_add ); - } - $deliveryCode = $params['order']->id_carrier; + $order = array( + 'externalId' => $params['order']->id, + 'firstName' => $params['customer']->firstname, + 'lastName' => $params['customer']->lastname, + 'email' => $params['customer']->email, + 'discount' => $params['order']->total_discounts, + 'createdAt' => $params['order']->date_add, + 'delivery' => array('cost' => $params['order']->total_shipping) + ); - if (array_key_exists($deliveryCode, $delivery) && !empty($delivery[$deliveryCode])) { - $order['delivery']['code'] = $delivery[$deliveryCode]; - } + $cart = new Cart($params['cart']->id); + $addressCollection = $cart->getAddressCollection(); + $address = array_shift($addressCollection); - if (Module::getInstanceByName('advancedcheckout') === false) { - $paymentCode = $params['order']->module; - } else { - $paymentCode = $params['order']->payment; - } + if ($address instanceof Address) { + $phone = is_null($address->phone) + ? is_null($address->phone_mobile) ? '' : $address->phone_mobile + : $address->phone; - if (array_key_exists($paymentCode, $payment) && !empty($payment[$paymentCode])) { - $order['paymentType'] = $payment[$paymentCode]; - } + $postcode = $address->postcode; + $city = $address->city; + $addres_line = sprintf("%s %s", $address->address1, $address->address2); + } - $statusCode = $params['orderStatus']->id; + if (!empty($postcode)) { + $customer['address']['index'] = $postcode; + $order['delivery']['address']['index'] = $postcode; + } - if (array_key_exists($statusCode, $status) && !empty($status[$statusCode])) { - $order['status'] = $status[$statusCode]; - } else { - $order['status'] = ['new']; - } + if (!empty($city)) { + $customer['address']['city'] = $city; + $order['delivery']['address']['city'] = $city; + } - $customerCheck = $this->api->customersGet($customer['externalId']); + if (!empty($addres_line)) { + $customer['address']['text'] = $addres_line; + $order['delivery']['address']['text'] = $addres_line; + } - if ($customerCheck === false) { - $this->api->customersCreate($customer); - } + if (!empty($phone)) { + $customer['phones'][] = array('number' => $phone); + $order['phone'] = $phone; + } + + foreach ($cart->getProducts() as $item) { + if(isset($item['id_product_attribute']) && $item['id_product_attribute'] > 0) { + $productId = $item['id_product'] . '#' . $item['id_product_attribute']; + } else { + $productId = $item['id_product']; + } + + $order['items'][] = array( + 'initialPrice' => !empty($item['rate']) + ? $item['price'] + ($item['price'] * $item['rate'] / 100) + : $item['price'] + , + 'quantity' => $item['quantity'], + 'productId' => $productId, + 'productName' => $item['name'] + ); + } + + $deliveryCode = $params['order']->id_carrier; + + if (array_key_exists($deliveryCode, $delivery) && !empty($delivery[$deliveryCode])) { + $order['delivery']['code'] = $delivery[$deliveryCode]; + } + + if (Module::getInstanceByName('advancedcheckout') === false) { + $paymentCode = $params['order']->module; + } else { + $paymentCode = $params['order']->payment; + } + + if (array_key_exists($paymentCode, $payment) && !empty($payment[$paymentCode])) { + $order['paymentType'] = $payment[$paymentCode]; + } + + $statusCode = $params['orderStatus']->id; + + if (array_key_exists($statusCode, $status) && !empty($status[$statusCode])) { + $order['status'] = $status[$statusCode]; + } else { + $order['status'] = array('new'); + } + + $customerCheck = $this->api->customersGet($customer['externalId']); + + if ($customerCheck === false) { + $this->api->customersCreate($customer); + } + + $order['customer']['externalId'] = $customer['externalId']; + $this->api->ordersCreate($order); - $order['customer']['externalId'] = $customer['externalId']; - $this->api->ordersCreate($order); } } + + private function validateCrmAddress($address) { + if(preg_match("/https:\/\/(.*).retailcrm.ru/", $address) === 1) + return true; + + return false; + } }