From c0ea6c2a06e3bf2bdf27a7229b268e635acc6425 Mon Sep 17 00:00:00 2001 From: Alex Lushpai Date: Mon, 11 Jan 2016 18:02:20 +0300 Subject: [PATCH] customer, orders & pre-alpha archive export --- retailcrm/bootstrap.php | 99 +++ retailcrm/job/export.php | 99 +++ retailcrm/job/icml.php | 20 +- retailcrm/job/sync.php | 198 ++---- retailcrm/lib/CurlException.php | 5 + retailcrm/lib/InvalidJsonException.php | 5 + retailcrm/lib/RetailcrmApiClient.php | 811 +++++++++++++++++++++++++ retailcrm/lib/RetailcrmApiResponse.php | 122 ++++ retailcrm/lib/RetailcrmCatalog.php | 133 ++++ retailcrm/lib/RetailcrmHttpClient.php | 113 ++++ retailcrm/lib/RetailcrmIcml.php | 137 +++++ retailcrm/lib/RetailcrmProxy.php | 44 ++ retailcrm/lib/RetailcrmReferences.php | 190 ++++++ retailcrm/lib/RetailcrmService.php | 42 ++ retailcrm/retailcrm.php | 550 +---------------- retailcrm/version.1.6.php | 433 +++++++++++++ 16 files changed, 2304 insertions(+), 697 deletions(-) create mode 100644 retailcrm/bootstrap.php create mode 100644 retailcrm/job/export.php create mode 100644 retailcrm/lib/CurlException.php create mode 100644 retailcrm/lib/InvalidJsonException.php create mode 100644 retailcrm/lib/RetailcrmApiClient.php create mode 100644 retailcrm/lib/RetailcrmApiResponse.php create mode 100644 retailcrm/lib/RetailcrmCatalog.php create mode 100644 retailcrm/lib/RetailcrmHttpClient.php create mode 100644 retailcrm/lib/RetailcrmIcml.php create mode 100644 retailcrm/lib/RetailcrmProxy.php create mode 100644 retailcrm/lib/RetailcrmReferences.php create mode 100644 retailcrm/lib/RetailcrmService.php create mode 100644 retailcrm/version.1.6.php diff --git a/retailcrm/bootstrap.php b/retailcrm/bootstrap.php new file mode 100644 index 0000000..7c0cc34 --- /dev/null +++ b/retailcrm/bootstrap.php @@ -0,0 +1,99 @@ + + * @author Alex Lushpai + */ +class RetailcrmAutoloader +{ + /** + * File extension as a string. Defaults to ".php". + */ + protected static $fileExt = '.php'; + + /** + * The top level directory where recursion will begin. + * + */ + protected static $pathTop; + + /** + * Autoload function for registration with spl_autoload_register + * + * Looks recursively through project directory and loads class files based on + * filename match. + * + * @param string $className + */ + public static function loader($className) + { + $directory = new RecursiveDirectoryIterator(self::$pathTop); + $fileIterator = new RecursiveIteratorIterator($directory); + $filename = $className . self::$fileExt; + + foreach ($fileIterator as $file) { + if (strtolower($file->getFilename()) === strtolower($filename) && $file->isReadable()) { + include_once $file->getPathname(); + } + } + + } + + /** + * Sets the $fileExt property + * + * @param string $fileExt The file extension used for class files. Default is "php". + */ + public static function setFileExt($fileExt) + { + self::$fileExt = $fileExt; + } + + /** + * Sets the $path property + * + * @param string $path The path representing the top level where recursion should + * begin. Defaults to the current directory. + */ + public static function setPath($path) + { + self::$pathTop = $path; + } + +} + +RetailcrmAutoloader::setPath(realpath(dirname(__FILE__))); +RetailcrmAutoloader::setFileExt('.php'); +spl_autoload_register('RetailcrmAutoloader::loader'); diff --git a/retailcrm/job/export.php b/retailcrm/job/export.php new file mode 100644 index 0000000..0426bf4 --- /dev/null +++ b/retailcrm/job/export.php @@ -0,0 +1,99 @@ +getOrdersWithInformations(2); + +$delivery = json_decode(Configuration::get('RETAILCRM_API_DELIVERY')); +$payment = json_decode(Configuration::get('RETAILCRM_API_PAYMENT')); +$status = json_decode(Configuration::get('RETAILCRM_API_STATUS')); + +foreach ($records as $record) { + + $object = new Order($record['id_order']); + + if (Module::getInstanceByName('advancedcheckout') === false) { + $paymentType = $record['module']; + } else { + $paymentType = $record['payment']; + } + + $cart = new Cart($object->getCartIdStatic($record['id_order'])); + $addressCollection = $cart->getAddressCollection(); + $address = array_shift($addressCollection); + + $order = array( + 'externalId' => $record['id_order'], + 'createdAt' => $record['date_add'], + 'status' => $record['current_state'] == 0 ? 'new' : $status->$record['current_state'], + 'firstName' => $record['firstname'], + 'lastName' => $record['lastname'], + 'email' => $record['email'], + 'phone' => $address->phone, + 'delivery' => array( + 'code' => $delivery->$record['id_carrier'], + 'cost' => $record['total_shipping_tax_incl'], + 'address' => array( + 'index' => $address->postcode, + 'city' => $address->city, + 'street' => sprintf("%s %s", $address->address1, $address->address2) + ) + ), + 'paymentType' => $payment->$paymentType + ); + + $products = $object->getProducts(); + + foreach($products as $product) { + $item = array( + 'productId' => $product['product_id'], + 'productName' => $product['product_name'], + 'quantity' => $product['product_quantity'], + 'initialPrice' => round($product['product_price'], 2), + 'purchasePrice' => round($product['purchase_supplier_price'], 2) + ); + + $order['items'][] = $item; + } + + if ($record['id_customer']) { + $order['customer']['externalId'] = $record['id_customer']; + + $customer = new Customer($record['id_customer']); + $customerCRM = array( + 'externalId' => $customer->id, + 'firstName' => $customer->firstname, + 'lastname' => $customer->lastname, + 'email' => $customer->email, + 'phones' => array(array('number' => $address->phone)), + 'createdAt' => $customer->date_add, + 'address' => array( + 'index' => $address->postcode, + 'city' => $address->city, + 'street' => sprintf("%s %s", $address->address1, $address->address2) + ) + ); + + $customers[$customer->id] = $customerCRM; + } + + $orders[] = $order; +} + +var_dump(count($customers)); +var_dump(count($orders)); diff --git a/retailcrm/job/icml.php b/retailcrm/job/icml.php index ec0ddec..9cf6da5 100644 --- a/retailcrm/job/icml.php +++ b/retailcrm/job/icml.php @@ -1,21 +1,11 @@ getData(); -$icml = new Icml( - Configuration::get('PS_SHOP_NAME'), - _PS_ROOT_DIR_ . '/retailcrm.xml' -); - +$icml = new RetailcrmIcml(Configuration::get('PS_SHOP_NAME'), _PS_ROOT_DIR_ . '/retailcrm.xml'); $icml->generate($data[0], $data[1]); diff --git a/retailcrm/job/sync.php b/retailcrm/job/sync.php index d567a50..07e50c5 100644 --- a/retailcrm/job/sync.php +++ b/retailcrm/job/sync.php @@ -1,13 +1,8 @@ ordersHistory(new DateTime($startFrom)); -} -catch (CurlException $e) { - error_log('orderHistory: connection error', 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); -} -catch (InvalidJsonException $e) { - error_log('orderHistory: ' . $e->getMessage(), 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); -} +$history = $api->ordersHistory(new DateTime($startFrom)); -/* - * store recieved data into shop database -*/ -if (count($history->orders) > 0) { +if ($history->isSuccess() && count($history->orders) > 0) { - /* - * Customer object. Will be used for further updates. - */ - - $statuses = array_filter( - json_decode( - Configuration::get('RETAILCRM_API_STATUS'), true - ) - ); - - $statuses = array_flip($statuses); - - $deliveries = array_filter( - json_decode( - Configuration::get('RETAILCRM_API_DELIVERY'), true - ) - ); - - $deliveries = array_flip($deliveries); - - $payments = array_filter( - json_decode( - Configuration::get('RETAILCRM_API_PAYMENT'), true - ) - ); - - $payments = array_flip($payments); + $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) { if (!array_key_exists('externalId', $order)) { - /* - * create customer if not exist - */ $customer = new Customer(); $customer->getByEmail($order['customer']['email']); - if (!array_key_exists('externalId', $order['customer'])) { - if (Validate::isEmail($order['customer']['email'])) { + if ( + !array_key_exists('externalId', $order['customer']) && + Validate::isEmail($order['customer']['email']) + ) { + if (!$customer->id) + { + $customer->firstname = $order['customer']['firstName']; + $customer->lastname = $order['customer']['lastName']; + $customer->email = $order['customer']['email']; + $customer->passwd = substr(str_shuffle(strtolower(sha1(rand() . time()))),0, 5); - if (!$customer->id) - { - $customer->firstname = $order['customer']['firstName']; - $customer->lastname = $order['customer']['lastName']; - $customer->email = $order['customer']['email']; - $customer->passwd = substr(str_shuffle(strtolower(sha1(rand() . time()))),0, 5); - - if($customer->add()) { - - /* - * create customer address for delivery data - */ - - $customer->getByEmail($order['customer']['email']); - $customer_id = $customer->id; - - $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 = $customer['address']['index']; - $address->city = $customer['address']['city']; - $address->address1 = $customer['address']['text']; - $address->phone = $customer['phones'][0]['number']; - - $address->add(); - - /* - * store address record id for handle order data - */ - $addr = $customer->getAddresses($default_lang); - $address_id = $addr[0]['id_address']; - } - } else { - $addresses = $customer->getAddresses($default_lang); - $address_id = $addresses[0]['id_address']; + if($customer->add()) { + $customer->getByEmail($order['customer']['email']); $customer_id = $customer->id; - } - /* - * collect customer ids for single fix request - */ - array_push( - $customerFix, - array( - 'id' => $order['customer']['id'], - 'externalId' => $customer_id - ) - ); + $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 = $customer['address']['index']; + $address->city = $customer['address']['city']; + $address->address1 = $customer['address']['text']; + $address->phone = $customer['phones'][0]['number']; + + $address->add(); + $addr = $customer->getAddresses($default_lang); + $address_id = $addr[0]['id_address']; + } + } else { + $addresses = $customer->getAddresses($default_lang); + $address_id = $addresses[0]['id_address']; + $customer_id = $customer->id; } + + array_push( + $customerFix, + array( + 'id' => $order['customer']['id'], + 'externalId' => $customer_id + ) + ); } else { $addresses = $customer->getAddresses($default_lang); $address_id = $addresses[0]['id_address']; @@ -185,7 +125,6 @@ if (count($history->orders) > 0) { /* * Create order */ - $newOrder = new Order(); $newOrder->id_address_delivery = (int) $address_id; $newOrder->id_address_invoice = (int) $address_id; @@ -270,34 +209,12 @@ if (count($history->orders) > 0) { Db::getInstance()->execute(rtrim($query, ',')); - try { - $this->api->customersFixExternalIds($customerFix); - } - catch (CurlException $e) { - error_log('customersFixExternalId: connection error', 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - continue; - } - catch (InvalidJsonException $e) { - error_log('customersFixExternalId: ' . $e->getMessage(), 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - continue; - } - - try { - $this->api->ordersFixExternalIds($orderFix); - } - catch (CurlException $e) { - error_log('ordersFixExternalId: connection error', 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - continue; - } - catch (InvalidJsonException $e) { - error_log('ordersFixExternalId: ' . $e->getMessage(), 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - continue; - } + $this->api->customersFixExternalIds($customerFix); + $this->api->ordersFixExternalIds($orderFix); } else { /* * take last order update only */ - if ($order['paymentType'] != null && $order['deliveryType'] != null && $order['status'] != null) { $orderToUpdate = new Order((int) $order['externalId']); @@ -355,11 +272,7 @@ if (count($history->orders) > 0) { } /* - * check items - */ - - /* - * Clean deleted + * Clean deleted items */ foreach ($order['items'] as $key => $item) { if (isset($item['deleted']) && $item['deleted'] == true) { @@ -374,9 +287,8 @@ if (count($history->orders) > 0) { } /* - * check quantity + * Check items quantity */ - foreach ($orderToUpdate->getProductsDetail() as $orderItem) { foreach ($order['items'] as $key => $item) { if ($item['offer']['externalId'] == $orderItem['product_id']) { @@ -395,7 +307,7 @@ if (count($history->orders) > 0) { } /* - * check new items + * Check new items */ if (!empty($order['items'])) { foreach ($order['items'] as $key => $newItem) { @@ -483,4 +395,4 @@ if (count($history->orders) > 0) { Configuration::updateValue('RETAILCRM_LAST_SYNC', $history->generatedAt); } else { return 'Nothing to sync'; -} \ No newline at end of file +} diff --git a/retailcrm/lib/CurlException.php b/retailcrm/lib/CurlException.php new file mode 100644 index 0000000..2ab00f5 --- /dev/null +++ b/retailcrm/lib/CurlException.php @@ -0,0 +1,5 @@ +client = new RetailcrmHttpClient($url, array('apiKey' => $apiKey)); + $this->siteCode = $site; + } + + /** + * Create a order + * + * @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 $order + * @param string $by + * @param string $site (default: null) + * @return RetailcrmApiResponse + */ + public function ordersEdit(array $order, $by = 'externalId', $site = null) + { + if (!sizeof($order)) { + throw new InvalidArgumentException('Parameter `order` must contains a data'); + } + + $this->checkIdParameter($by); + + if (!isset($order[$by])) { + throw new InvalidArgumentException(sprintf('Order array must contain the "%s" parameter.', $by)); + } + + return $this->client->makeRequest( + "/orders/" . $order[$by] . "/edit", + RetailcrmHttpClient::METHOD_POST, + $this->fillSite($site, array( + 'order' => json_encode($order), + 'by' => $by, + )) + ); + } + + /** + * Upload array of the orders + * + * @param array $orders + * @param string $site (default: null) + * @return RetailcrmApiResponse + */ + public function ordersUpload(array $orders, $site = null) + { + if (!sizeof($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), + ))); + } + + /** + * Get order by id or externalId + * + * @param string $id + * @param string $by (default: 'externalId') + * @param string $site (default: null) + * @return RetailcrmApiResponse + */ + 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 + ))); + } + + /** + * Returns a orders history + * + * @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 + */ + 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; + } + + return $this->client->makeRequest('/orders/history', RetailcrmHttpClient::METHOD_GET, $parameters); + } + + /** + * Returns filtered orders list + * + * @param array $filter (default: array()) + * @param int $page (default: null) + * @param int $limit (default: null) + * @return RetailcrmApiResponse + */ + public function ordersList(array $filter = array(), $page = null, $limit = null) + { + $parameters = array(); + + if (sizeof($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); + } + + /** + * Returns statuses of the orders + * + * @param array $ids (default: array()) + * @param array $externalIds (default: array()) + * @return RetailcrmApiResponse + */ + public function ordersStatuses(array $ids = array(), array $externalIds = array()) + { + $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)) { + $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); + } + + /** + * Create a customer + * + * @param array $customer + * @param string $site (default: null) + * @return RetailcrmApiResponse + */ + 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)); + } + + return $this->client->makeRequest( + "/customers/" . $customer[$by] . "/edit", + RetailcrmHttpClient::METHOD_POST, + $this->fillSite( + $site, + array( + 'customer' => json_encode($customer), + 'by' => $by + ) + ) + ); + } + + /** + * Upload array of the customers + * + * @param array $customers + * @param string $site (default: null) + * @return RetailcrmApiResponse + */ + public function customersUpload(array $customers, $site = null) + { + if (!sizeof($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), + ))); + } + + /** + * Get customer by id or externalId + * + * @param string $id + * @param string $by (default: 'externalId') + * @param string $site (default: null) + * @return RetailcrmApiResponse + */ + 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 + ))); + } + + /** + * Returns filtered customers list + * + * @param array $filter (default: array()) + * @param int $page (default: null) + * @param int $limit (default: null) + * @return RetailcrmApiResponse + */ + public function customersList(array $filter = array(), $page = null, $limit = null) + { + $parameters = array(); + + if (sizeof($filter)) { + $parameters['filter'] = $filter; + } + if (null !== $page) { + $parameters['page'] = (int) $page; + } + if (null !== $limit) { + $parameters['limit'] = (int) $limit; + } + + return $this->client->makeRequest('/customers', RetailcrmHttpClient::METHOD_GET, $parameters); + } + + /** + * Save customer IDs' (id and externalId) association in the CRM + * + * @param array $ids + * @return RetailcrmApiResponse + */ + public function customersFixExternalIds(array $ids) + { + if (!sizeof($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), + )); + } + + /** + * 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 + */ + public function storeInventories(array $filter = array(), $page = null, $limit = null, $site = null) + { + $parameters = array(); + + if (sizeof($filter)) { + $parameters['filter'] = $filter; + } + if (null !== $page) { + $parameters['page'] = (int) $page; + } + if (null !== $limit) { + $parameters['limit'] = (int) $limit; + } + + return $this->client->makeRequest('/store/inventories', RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, $parameters)); + } + + /** + * Upload store inventories + * + * @param array $offers + * @param string $site (default: null) + * @return RetailcrmApiResponse + */ + public function storeInventoriesUpload(array $offers, $site = null) + { + if (!sizeof($offers)) { + throw new InvalidArgumentException('Parameter `offers` must contains array of the customers'); + } + + return $this->client->makeRequest( + "/store/inventories/upload", + RetailcrmHttpClient::METHOD_POST, + $this->fillSite($site, array('offers' => json_encode($offers))) + ); + } + + /** + * Returns deliveryServices list + * + * @return RetailcrmApiResponse + */ + 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); + } + + /** + * Edit deliveryService + * + * @param array $data delivery service data + * @return RetailcrmApiResponse + */ + public function deliveryServicesEdit(array $data) + { + if (!isset($data['code'])) { + throw new InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->client->makeRequest( + '/reference/delivery-services/' . $data['code'] . '/edit', + RetailcrmHttpClient::METHOD_POST, + array( + 'deliveryService' => json_encode($data) + ) + ); + } + + /** + * Edit deliveryType + * + * @param array $data delivery type data + * @return RetailcrmApiResponse + */ + public function deliveryTypesEdit(array $data) + { + if (!isset($data['code'])) { + throw new InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->client->makeRequest( + '/reference/delivery-types/' . $data['code'] . '/edit', + RetailcrmHttpClient::METHOD_POST, + array( + 'deliveryType' => json_encode($data) + ) + ); + } + + /** + * Edit orderMethod + * + * @param array $data order method data + * @return RetailcrmApiResponse + */ + public function orderMethodsEdit(array $data) + { + if (!isset($data['code'])) { + throw new InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->client->makeRequest( + '/reference/order-methods/' . $data['code'] . '/edit', + RetailcrmHttpClient::METHOD_POST, + array( + 'orderMethod' => json_encode($data) + ) + ); + } + + /** + * Edit orderType + * + * @param array $data order type data + * @return RetailcrmApiResponse + */ + public function orderTypesEdit(array $data) + { + if (!isset($data['code'])) { + throw new InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->client->makeRequest( + '/reference/order-types/' . $data['code'] . '/edit', + RetailcrmHttpClient::METHOD_POST, + array( + 'orderType' => json_encode($data) + ) + ); + } + + /** + * Edit paymentStatus + * + * @param array $data payment status data + * @return RetailcrmApiResponse + */ + public function paymentStatusesEdit(array $data) + { + if (!isset($data['code'])) { + throw new InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->client->makeRequest( + '/reference/payment-statuses/' . $data['code'] . '/edit', + RetailcrmHttpClient::METHOD_POST, + array( + 'paymentStatus' => json_encode($data) + ) + ); + } + + /** + * Edit paymentType + * + * @param array $data payment type data + * @return RetailcrmApiResponse + */ + public function paymentTypesEdit(array $data) + { + if (!isset($data['code'])) { + throw new InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->client->makeRequest( + '/reference/payment-types/' . $data['code'] . '/edit', + RetailcrmHttpClient::METHOD_POST, + array( + 'paymentType' => json_encode($data) + ) + ); + } + + /** + * Edit productStatus + * + * @param array $data product status data + * @return RetailcrmApiResponse + */ + public function productStatusesEdit(array $data) + { + if (!isset($data['code'])) { + throw new InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->client->makeRequest( + '/reference/product-statuses/' . $data['code'] . '/edit', + RetailcrmHttpClient::METHOD_POST, + array( + 'productStatus' => json_encode($data) + ) + ); + } + + /** + * Edit order status + * + * @param array $data status data + * @return RetailcrmApiResponse + */ + public function statusesEdit(array $data) + { + 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) + ) + ); + } + + /** + * Edit site + * + * @param array $data site data + * @return RetailcrmApiResponse + */ + public function sitesEdit(array $data) + { + if (!isset($data['code'])) { + throw new InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->client->makeRequest( + '/reference/sites/' . $data['code'] . '/edit', + RetailcrmHttpClient::METHOD_POST, + array( + 'site' => json_encode($data) + ) + ); + } + + /** + * Edit store + * + * @param array $data site data + * @return RetailcrmApiResponse + */ + public function storesEdit(array $data) + { + if (!isset($data['code'])) { + throw new InvalidArgumentException('Data must contain "code" parameter.'); + } + + if (!isset($data['name'])) { + throw new InvalidArgumentException('Data must contain "name" parameter.'); + } + + return $this->client->makeRequest( + '/reference/stores/' . $data['code'] . '/edit', + RetailcrmHttpClient::METHOD_POST, + array( + 'store' => json_encode($data) + ) + ); + } + + /** + * Update CRM basic statistic + * + * @return RetailcrmApiResponse + */ + public function statisticUpdate() + { + return $this->client->makeRequest('/statistic/update', RetailcrmHttpClient::METHOD_GET); + } + + /** + * Return current site + * + * @return string + */ + public function getSite() + { + return $this->siteCode; + } + + /** + * Set site + * + * @param string $site + * @return void + */ + public function setSite($site) + { + $this->siteCode = $site; + } + + /** + * Check ID parameter + * + * @param string $by + * @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) + )); + } + + return true; + } + + /** + * Fill params by site value + * + * @param string $site + * @param array $params + * @return array + */ + protected function fillSite($site, array $params) + { + if ($site) { + $params['site'] = $site; + } elseif ($this->siteCode) { + $params['site'] = $this->siteCode; + } + + return $params; + } +} diff --git a/retailcrm/lib/RetailcrmApiResponse.php b/retailcrm/lib/RetailcrmApiResponse.php new file mode 100644 index 0000000..bba91db --- /dev/null +++ b/retailcrm/lib/RetailcrmApiResponse.php @@ -0,0 +1,122 @@ +statusCode = (int) $statusCode; + + if (!empty($responseBody)) { + $response = json_decode($responseBody, true); + + if (!$response && JSON_ERROR_NONE !== ($error = json_last_error())) { + throw new InvalidJsonException( + "Invalid JSON in the API response body. Error code #$error", + $error + ); + } + + $this->response = $response; + } + } + + /** + * Return HTTP response status code + * + * @return int + */ + public function getStatusCode() + { + return $this->statusCode; + } + + /** + * HTTP request was successful + * + * @return bool + */ + public function isSuccessful() + { + return $this->statusCode < 400; + } + + /** + * Allow to access for the property throw class method + * + * @param string $name + * @return mixed + */ + public function __call($name, $arguments) + { + // convert getSomeProperty to someProperty + $propertyName = strtolower(substr($name, 3, 1)) . substr($name, 4); + + if (!isset($this->response[$propertyName])) { + throw new InvalidArgumentException("Method \"$name\" not found"); + } + + return $this->response[$propertyName]; + } + + /** + * Allow to access for the property throw object property + * + * @param string $name + * @return mixed + */ + public function __get($name) + { + if (!isset($this->response[$name])) { + throw new InvalidArgumentException("Property \"$name\" not found"); + } + + return $this->response[$name]; + } + + /** + * @param mixed $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) + { + throw new BadMethodCallException('This activity not allowed'); + } + + /** + * @param mixed $offset + */ + public function offsetUnset($offset) + { + throw new BadMethodCallException('This call not allowed'); + } + + /** + * @param mixed $offset + * @return bool + */ + public function offsetExists($offset) + { + return isset($this->response[$offset]); + } + + /** + * @param mixed $offset + * @return mixed + */ + public function offsetGet($offset) + { + if (!isset($this->response[$offset])) { + throw new InvalidArgumentException("Property \"$offset\" not found"); + } + + return $this->response[$offset]; + } +} diff --git a/retailcrm/lib/RetailcrmCatalog.php b/retailcrm/lib/RetailcrmCatalog.php new file mode 100644 index 0000000..a1808b1 --- /dev/null +++ b/retailcrm/lib/RetailcrmCatalog.php @@ -0,0 +1,133 @@ +default_lang = (int) Configuration::get('PS_LANG_DEFAULT'); + $this->default_currency = (int) Configuration::get('PS_CURRENCY_DEFAULT'); + $this->default_country = (int) Configuration::get('PS_COUNTRY_DEFAULT'); + } + + 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_); + + $items = array(); + $categories = array(); + + if ($currency->iso_code == 'RUB') { + $currency->iso_code = 'RUR'; + } + + $currencies = Currency::getCurrencies(); + + $types = Category::getCategories($id_lang, true, false); + foreach ($types AS $category) { + $categories[] = array( + 'id' => $category['id_category'], + 'parentId' => $category['id_parent'], + 'name' => $category['name'] + ); + } + + $products = Product::getProducts($id_lang, 0, 0, 'name', 'asc'); + + foreach ($products AS $product) { + $category = $product['id_category_default']; + + if ($category == Configuration::get('PS_HOME_CATEGORY')) { + $temp_categories = Product::getProductCategories($product['id_product']); + + foreach ($temp_categories AS $category) { + if ($category != Configuration::get('PS_HOME_CATEGORY')) + break; + } + + if ($category == Configuration::get('PS_HOME_CATEGORY')) { + continue; + } + } + + $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; + } + + $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); + } + + $item['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']; + } + + if (!empty($product['reference'])) { + $item['article'] = htmlspecialchars($product['reference']); + } + + $weight = round($product['weight'], 2); + + if (!empty($weight)) { + $item['weight'] = $weight; + } + + $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)); + } + } + } + + $items[] = $item; + } + + return array($categories, $items); + } + +} diff --git a/retailcrm/lib/RetailcrmHttpClient.php b/retailcrm/lib/RetailcrmHttpClient.php new file mode 100644 index 0000000..6f74d16 --- /dev/null +++ b/retailcrm/lib/RetailcrmHttpClient.php @@ -0,0 +1,113 @@ +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 + */ + public function makeRequest( + $path, + $method, + array $parameters = array(), + $timeout = 30, + $verify = false, + $debug = false + ) { + $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) + )); + } + + $parameters = array_merge($this->defaultParameters, $parameters); + + $url = $this->url . $path; + + if (self::METHOD_GET === $method && sizeof($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)); + } + + if (self::METHOD_POST === $method) { + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters); + } + + $responseBody = curl_exec($ch); + $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $errno = curl_errno($ch); + $error = curl_error($ch); + + 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 + ); + } + + if ($errno) { + throw new CurlException($error, $errno); + } + + return new RetailcrmApiResponse($statusCode, $responseBody); + } + + public function getRetry() + { + return $this->retry; + } +} diff --git a/retailcrm/lib/RetailcrmIcml.php b/retailcrm/lib/RetailcrmIcml.php new file mode 100644 index 0000000..5b5f950 --- /dev/null +++ b/retailcrm/lib/RetailcrmIcml.php @@ -0,0 +1,137 @@ +shop = $shop; + $this->file = $file; + + $this->properties = array( + 'name', + 'productName', + 'price', + 'purchasePrice', + 'vendor', + 'picture', + 'url', + 'xmlId', + 'productActivity' + ); + + $this->params = array( + 'article' => 'Артикул', + 'color' => 'Цвет', + 'weight' => 'Вес', + 'size' => 'Размер', + 'tax' => 'Наценка' + ); + } + + public function generate($categories, $offers) + { + $string = ' + + + ' . $this->shop . ' + + + + + '; + + $xml = new SimpleXMLElement( + $string, LIBXML_NOENT | LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_PARSEHUGE + ); + + $this->dd = new DOMDocument(); + $this->dd->preserveWhiteSpace = false; + $this->dd->formatOutput = true; + $this->dd->loadXML($xml->asXML()); + + $this->eCategories = $this->dd + ->getElementsByTagName('categories')->item(0); + $this->eOffers = $this->dd + ->getElementsByTagName('offers')->item(0); + + $this->addCategories($categories); + $this->addOffers($offers); + + $this->dd->saveXML(); + $this->dd->save($this->file); + } + + private function addCategories($categories) + { + foreach ($categories as $category) { + $e = $this->eCategories->appendChild( + $this->dd->createElement( + 'category', $category['name'] + ) + ); + + $e->setAttribute('id', $category['id']); + + if ($category['parentId'] > 0) { + $e->setAttribute('parentId', $category['parentId']); + } + } + } + + private function addOffers($offers) + { + foreach ($offers as $offer) { + + $e = $this->eOffers->appendChild( + $this->dd->createElement('offer') + ); + + $e->setAttribute('id', $offer['id']); + $e->setAttribute('productId', $offer['productId']); + + if (!empty($offer['quantity'])) { + $e->setAttribute('quantity', (int) $offer['quantity']); + } else { + $e->setAttribute('quantity', 0); + } + + foreach ($offer['categoryId'] as $categoryId) { + $e->appendChild( + $this->dd->createElement('categoryId', $categoryId) + ); + } + + $offerKeys = array_keys($offer); + + foreach ($offerKeys as $key) { + if (in_array($key, $this->properties)) { + $e->appendChild( + $this->dd->createElement($key) + )->appendChild( + $this->dd->createTextNode($offer[$key]) + ); + } + + if (in_array($key, array_keys($this->params))) { + $param = $this->dd->createElement('param'); + $param->setAttribute('code', $key); + $param->setAttribute('name', $this->params[$key]); + $param->appendChild( + $this->dd->createTextNode($offer[$key]) + ); + $e->appendChild($param); + } + } + } + } + +} diff --git a/retailcrm/lib/RetailcrmProxy.php b/retailcrm/lib/RetailcrmProxy.php new file mode 100644 index 0000000..7cac9ec --- /dev/null +++ b/retailcrm/lib/RetailcrmProxy.php @@ -0,0 +1,44 @@ +api = new RetailcrmApiClient($url, $key); + $this->log = $log; + } + + public function __call($method, $arguments) + { + try { + $response = call_user_func_array(array($this->api, $method), $arguments); + + if (!$response->isSuccessful()) { + $response = false; + error_log("[$method] " . $response->getErrorMsg() . "\n", 3, $this->log); + } + + if (isset($response['errors'])) { + $error = implode("\n", $response['errors']); + error_log($error . "\n", 3, $this->log); + } + + return $response; + } catch (CurlException $e) { + error_log("[$method] " . $e->getMessage() . "\n", 3, $this->log); + return false; + } catch (InvalidJsonException $e) { + error_log("[$method] " . $e->getMessage() . "\n", 3, $this->log); + return false; + } + } + +} diff --git a/retailcrm/lib/RetailcrmReferences.php b/retailcrm/lib/RetailcrmReferences.php new file mode 100644 index 0000000..1b62c1c --- /dev/null +++ b/retailcrm/lib/RetailcrmReferences.php @@ -0,0 +1,190 @@ +api = $client; + $this->default_lang = (int) Configuration::get('PS_LANG_DEFAULT'); + $this->default_currency = (int) Configuration::get('PS_CURRENCY_DEFAULT'); + $this->default_country = (int) Configuration::get('PS_COUNTRY_DEFAULT'); + } + + public function getDeliveryTypes() + { + $deliveryTypes = array(); + + $carriers = Carrier::getCarriers($this->default_lang, true, false, false, null, PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE); + + if (!empty($carriers)) { + foreach ($carriers as $carrier) { + $deliveryTypes[] = array( + 'type' => 'select', + 'label' => $carrier['name'], + 'name' => 'RETAILCRM_API_DELIVERY[' . $carrier['id_carrier'] . ']', + 'required' => false, + 'options' => array( + 'query' => $this->getApiDeliveryTypes(), + 'id' => 'id_option', + 'name' => 'name' + ) + ); + } + } + + return $deliveryTypes; + } + + public function getStatuses() + { + $statusTypes = array(); + $states = array_merge( + OrderState::getOrderStates($this->default_lang, true), + OrderReturnState::getOrderReturnStates($this->default_lang, true) + ); + + if (!empty($states)) { + foreach ($states as $state) { + if ($state['name'] != ' ') { + $statusTypes[] = array( + 'type' => 'select', + 'label' => $state['name'], + 'name' => 'RETAILCRM_API_STATUS[' . $state['id_order_state'] . ']', + 'required' => false, + 'options' => array( + 'query' => $this->getApiStatuses(), + 'id' => 'id_option', + 'name' => 'name' + ) + ); + } + } + } + + return $statusTypes; + } + + public function getPaymentTypes() + { + $payments = $this->getSystemPaymentModules(); + $paymentTypes = array(); + + if (!empty($payments)) { + foreach ($payments as $payment) { + $paymentTypes[] = array( + 'type' => 'select', + 'label' => $payment['name'], + 'name' => 'RETAILCRM_API_PAYMENT[' . $payment['code'] . ']', + 'required' => false, + 'options' => array( + 'query' => $this->getApiPaymentTypes(), + 'id' => 'id_option', + 'name' => 'name' + ) + ); + } + } + + return $paymentTypes; + } + + protected function getSystemPaymentModules() + { + $shop_id = Context::getContext()->shop->id; + + /* Get all modules then select only payment ones */ + $modules = Module::getModulesOnDisk(true); + + foreach ($modules as $module) { + if ($module->tab == 'payments_gateways') { + if ($module->id) { + if (!get_class($module) == 'SimpleXMLElement') + $module->country = array(); + $countries = DB::getInstance()->executeS('SELECT id_country FROM ' . _DB_PREFIX_ . 'module_country WHERE id_module = ' . (int) $module->id . ' AND `id_shop`=' . (int) $shop_id); + foreach ($countries as $country) + $module->country[] = $country['id_country']; + if (!get_class($module) == 'SimpleXMLElement') + $module->currency = array(); + $currencies = DB::getInstance()->executeS('SELECT id_currency FROM ' . _DB_PREFIX_ . 'module_currency WHERE id_module = ' . (int) $module->id . ' AND `id_shop`=' . (int) $shop_id); + foreach ($currencies as $currency) + $module->currency[] = $currency['id_currency']; + if (!get_class($module) == 'SimpleXMLElement') + $module->group = array(); + $groups = DB::getInstance()->executeS('SELECT id_group FROM ' . _DB_PREFIX_ . 'module_group WHERE id_module = ' . (int) $module->id . ' AND `id_shop`=' . (int) $shop_id); + foreach ($groups as $group) + $module->group[] = $group['id_group']; + } else { + $module->country = null; + $module->currency = null; + $module->group = null; + } + + if ($module->active != 0) { + $this->payment_modules[] = array( + 'id' => $module->id, + 'code' => $module->name, + 'name' => $module->displayName + ); + } + } + } + + return $this->payment_modules; + } + + protected function getApiDeliveryTypes() + { + $crmDeliveryTypes = array(); + $request = $this->api->deliveryTypesList(); + + if ($request->isSuccessful()) { + $crmDeliveryTypes[] = array(); + foreach ($request->deliveryTypes as $dType) { + $crmDeliveryTypes[] = array( + 'id_option' => $dType['code'], + 'name' => $dType['name'], + ); + } + } + + return $crmDeliveryTypes; + } + + protected function getApiStatuses() + { + $crmStatusTypes = array(); + $request = $this->api->statusesList(); + + if ($request->isSuccessful()) { + $crmStatusTypes[] = array(); + foreach ($request->statuses as $sType) { + $crmStatusTypes[] = array( + 'id_option' => $sType['code'], + 'name' => $sType['name'] + ); + } + } + + return $crmStatusTypes; + } + + protected function getApiPaymentTypes() + { + $crmPaymentTypes = array(); + $request = $this->api->paymentTypesList(); + + if ($request->isSuccessful()) { + $crmPaymentTypes[] = array(); + foreach ($request->paymentTypes as $pType) { + $crmPaymentTypes[] = array( + 'id_option' => $pType['code'], + 'name' => $pType['name'] + ); + } + } + + return $crmPaymentTypes; + } + +} diff --git a/retailcrm/lib/RetailcrmService.php b/retailcrm/lib/RetailcrmService.php new file mode 100644 index 0000000..9a94694 --- /dev/null +++ b/retailcrm/lib/RetailcrmService.php @@ -0,0 +1,42 @@ +name = 'retailcrm'; - $this->tab = 'market_place'; - $this->version = '1.1'; - $this->author = 'Retail Driver LCC'; - - $this->displayName = $this->l('RetailCRM'); - $this->description = $this->l('Integration module for RetailCRM'); - $this->confirmUninstall = $this->l('Are you sure you want to uninstall?'); - - $this->apiUrl = Configuration::get('RETAILCRM_ADDRESS'); - $this->apiKey = Configuration::get('RETAILCRM_API_TOKEN'); - - if (!empty($this->apiUrl) && !empty($this->apiKey)) { - $this->api = new ApiClient( - $this->apiUrl, - $this->apiKey - ); - } - - $this->default_lang = (int) Configuration::get('PS_LANG_DEFAULT'); - $this->default_currency = (int) Configuration::get('PS_CURRENCY_DEFAULT'); - $this->default_country = (int) Configuration::get('PS_COUNTRY_DEFAULT'); - - $this->response = array(); - $this->customerFix = array(); - $this->orderFix = array(); - - $this->address_id = null; - $this->customer_id = null; - - $this->customer = null; - - $this->ref = new References($this->api); - - parent::__construct(); - } - - function install() - { - return ( - parent::install() && - $this->registerHook('newOrder') && - $this->registerHook('actionOrderStatusPostUpdate') && - $this->registerHook('actionPaymentConfirmation') && - $this->registerHook('actionCustomerAccountAdd') - ); - } - - function uninstall() - { - return parent::uninstall() && - Configuration::deleteByName('RETAILCRM_ADDRESS') && - Configuration::deleteByName('RETAILCRM_API_TOKEN') && - Configuration::deleteByName('RETAILCRM_API_STATUS') && - Configuration::deleteByName('RETAILCRM_API_DELIVERY') && - Configuration::deleteByName('RETAILCRM_LAST_SYNC') && - Configuration::deleteByName('RETAILCRM_API_ADDR') - ; - } - - public function getContent() - { - $output = null; - - $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')); - $delivery = json_encode(Tools::getValue('RETAILCRM_API_DELIVERY')); - $status = json_encode(Tools::getValue('RETAILCRM_API_STATUS')); - $payment = json_encode(Tools::getValue('RETAILCRM_API_PAYMENT')); - $order_address = json_encode(Tools::getValue('RETAILCRM_API_ADDR')); - - if (!$address || empty($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') ); - } else { - Configuration::updateValue('RETAILCRM_ADDRESS', $address); - Configuration::updateValue('RETAILCRM_API_TOKEN', $token); - Configuration::updateValue('RETAILCRM_API_DELIVERY', $delivery); - Configuration::updateValue('RETAILCRM_API_STATUS', $status); - Configuration::updateValue('RETAILCRM_API_PAYMENT', $payment); - Configuration::updateValue('RETAILCRM_API_ADDR', $order_address); - $output .= $this->displayConfirmation($this->l('Settings updated')); - } - } - - $this->display(__FILE__, 'retailcrm.tpl'); - - return $output.$this->displayForm(); - } - - public function displayForm() - { - - $this->displayConfirmation($this->l('Settings updated')); - - $default_lang = $this->default_lang; - $intaroCrm = $this->api; - - /* - * Network connection form - */ - $fields_form[0]['form'] = array( - 'legend' => array( - 'title' => $this->l('Network connection'), - ), - 'input' => array( - array( - 'type' => 'text', - 'label' => $this->l('CRM address'), - 'name' => 'RETAILCRM_ADDRESS', - 'size' => 20, - 'required' => true - ), - array( - 'type' => 'text', - 'label' => $this->l('CRM token'), - 'name' => 'RETAILCRM_API_TOKEN', - 'size' => 20, - 'required' => true - ) - ), - 'submit' => array( - 'title' => $this->l('Save'), - 'class' => 'button' - ) - ); - - - if (!empty($this->apiUrl) && !empty($this->apiKey)) { - /* - * Delivery - */ - $fields_form[1]['form'] = array( - 'legend' => array( - 'title' => $this->l('Delivery'), - ), - 'input' => $this->ref->getDeliveryTypes(), - ); - - /* - * Order status - */ - $fields_form[2]['form'] = array( - 'legend' => array( - 'title' => $this->l('Order statuses'), - ), - 'input' => $this->ref->getStatuses(), - ); - - /* - * Payment - */ - $fields_form[3]['form'] = array( - 'legend' => array( - 'title' => $this->l('Payment types'), - ), - 'input' => $this->ref->getPaymentTypes(), - ); - } - - /* - * Address fields - */ - $fields_form[4]['form'] = array( - 'legend' => array( - 'title' => $this->l('Address'), - ), - 'input' => $this->getAddressFields() - ); - - - /* - * Diplay forms - */ - - $helper = new HelperForm(); - - $helper->module = $this; - $helper->name_controller = $this->name; - $helper->token = Tools::getAdminTokenLite('AdminModules'); - $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name; - - $helper->default_form_language = $default_lang; - $helper->allow_employee_form_lang = $default_lang; - - $helper->title = $this->displayName; - $helper->show_toolbar = true; - $helper->toolbar_scroll = true; - $helper->submit_action = 'submit'.$this->name; - $helper->toolbar_btn = array( - 'save' => - array( - 'desc' => $this->l('Save'), - 'href' => AdminController::$currentIndex.'&configure='.$this->name.'&save'.$this->name. - '&token='.Tools::getAdminTokenLite('AdminModules'), - ), - 'back' => array( - 'href' => AdminController::$currentIndex.'&token='.Tools::getAdminTokenLite('AdminModules'), - 'desc' => $this->l('Back to list') - ) - ); - - $helper->fields_value['RETAILCRM_ADDRESS'] = Configuration::get('RETAILCRM_ADDRESS'); - $helper->fields_value['RETAILCRM_API_TOKEN'] = Configuration::get('RETAILCRM_API_TOKEN'); - - $deliverySettings = Configuration::get('RETAILCRM_API_DELIVERY'); - if (isset($deliverySettings) && $deliverySettings != '') - { - $deliveryTypes = json_decode($deliverySettings); - foreach ($deliveryTypes as $idx => $delivery) { - $name = 'RETAILCRM_API_DELIVERY[' . $idx . ']'; - $helper->fields_value[$name] = $delivery; - } - } - - $statusSettings = Configuration::get('RETAILCRM_API_STATUS'); - if (isset($statusSettings) && $statusSettings != '') - { - $statusTypes = json_decode($statusSettings); - foreach ($statusTypes as $idx => $status) { - $name = 'RETAILCRM_API_STATUS[' . $idx . ']'; - $helper->fields_value[$name] = $status; - } - } - - $paymentSettings = Configuration::get('RETAILCRM_API_PAYMENT'); - if (isset($paymentSettings) && $paymentSettings != '') - { - $paymentTypes = json_decode($paymentSettings); - foreach ($paymentTypes as $idx => $payment) { - $name = 'RETAILCRM_API_PAYMENT[' . $idx . ']'; - $helper->fields_value[$name] = $payment; - } - } - - $addressSettings = Configuration::get('RETAILCRM_API_ADDR'); - if (isset($addressSettings) && $addressSettings != '') - { - $addressTypes = json_decode($addressSettings); - foreach ($addressTypes as $idx => $address) { - $name = 'RETAILCRM_API_ADDR[' . $idx . ']'; - $helper->fields_value[$name] = $address; - } - } - - return $helper->generateForm($fields_form); - } - - public function getAddressFields() - { - $addressFields = array(); - $address = explode(' ', str_replace("\n", ' ', AddressFormat::getAddressCountryFormat($this->context->country->id))); - - if (!empty($address)) { - foreach ($address as $idx => $a) { - if (!in_array($a, array('vat_number', 'phone_mobile', 'company'))) { - if (!strpos($a, ':')) { - $a = preg_replace('/_/', ' ', $a); - $a = preg_replace('/[\,\.]/', '', $a); - $addressFields[] = array( - 'type' => 'select', - 'label' => $this->l((string) ucfirst($a)), - 'name' => 'RETAILCRM_API_ADDR[' . $idx . ']', - 'required' => false, - 'options' => array( - 'query' => array( - array( - 'name' => '', - 'id_option' => '' - ), - array( - 'name' => $this->l('FIRST_NAME'), - 'id_option' => 'first_name' - ), - array( - 'name' => $this->l('LAST_NAME'), - 'id_option' => 'last_name' - ), - array( - 'name' => $this->l('PHONE'), - 'id_option' => 'phone' - ), - array( - 'name' => $this->l('EMAIL'), - 'id_option' => 'email' - ), - array( - 'name' => $this->l('ADDRESS'), - 'id_option' => 'address' - ), - array( - 'name' => $this->l('COUNTRY'), - 'id_option' => 'country' - ), - array( - 'name' => $this->l('REGION'), - 'id_option' => 'region' - ), - array( - 'name' => $this->l('CITY'), - 'id_option' => 'city' - ), - array( - 'name' => $this->l('ZIP'), - 'id_option' => 'index' - ), - array( - 'name' => $this->l('STREET'), - 'id_option' => 'street' - ), - array( - 'name' => $this->l('BUILDING'), - 'id_option' => 'building' - ), - array( - 'name' => $this->l('FLAT'), - 'id_option' => 'flat' - ), - array( - 'name' => $this->l('INTERCOMCODE'), - 'id_option' => 'intercomcode' - ), - array( - 'name' => $this->l('FLOOR'), - 'id_option' => 'floor' - ), - array( - 'name' => $this->l('BLOCK'), - 'id_option' => 'block' - ), - array( - 'name' => $this->l('HOUSE'), - 'ID' => 'house' - ) - ), - 'id' => 'id_option', - 'name' => 'name' - ) - ); - } - } - } - } - - return $addressFields; - } - - public function hookActionCustomerAccountAdd($params) - { - try { - $this->api->customersCreate( - array( - 'externalId' => $params['newCustomer']->id, - 'firstName' => $params['newCustomer']->firstname, - 'lastName' => $params['newCustomer']->lastname, - 'email' => $params['newCustomer']->email, - 'createdAt' => $params['newCustomer']->date_add - ) - ); - } - catch (CurlException $e) { - error_log('customerCreate: connection error', 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - } - catch (InvalidJsonException $e) { - error_log('customerCreate: ' . $e->getMessage(), 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - } - } - - public function hookNewOrder($params) - { - return $this->hookActionOrderStatusPostUpdate($params); - } - - public function hookActionPaymentConfirmation($params) - { - $this->api->ordersEdit( - array( - 'externalId' => $params['id_order'], - 'paymentStatus' => 'paid', - 'createdAt' => $params['cart']->date_upd - ) - ); - - return $this->hookActionOrderStatusPostUpdate($params); - } - - public function hookActionOrderStatusPostUpdate($params) - { - $address_id = Address::getFirstCustomerAddressId($params['cart']->id_customer); - $sql = 'SELECT * FROM '._DB_PREFIX_.'address WHERE id_address='.(int) $address_id; - $address = Db::getInstance()->ExecuteS($sql); - $address = $address[0]; - $delivery = json_decode(Configuration::get('RETAILCRM_API_DELIVERY')); - $payment = json_decode(Configuration::get('RETAILCRM_API_PAYMENT')); - $inCart = $params['cart']->getProducts(); - - if (isset($params['orderStatus'])) { - try { - $this->api->customersCreate( - array( - 'externalId' => $params['cart']->id_customer, - 'lastName' => $params['customer']->lastname, - 'firstName' => $params['customer']->firstname, - 'email' => $params['customer']->email, - 'phones' => array( - array( - 'number' => $address['phone'], - 'type' => 'mobile' - ), - array( - 'number' => $address['phone_mobile'], - 'type' => 'mobile' - ) - ), - 'createdAt' => $params['customer']->date_add - ) - ); - } - catch (CurlException $e) { - error_log("customerCreate: connection error", 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - } - catch (InvalidJsonException $e) { - error_log('customerCreate: ' . $e->getMessage(), 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - } - - try { - $items = array(); - foreach ($inCart as $item) { - $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'], - 'createdAt' => $item['date_add'] - ); - } - - $dTypeKey = $params['cart']->id_carrier; - - if (Module::getInstanceByName('advancedcheckout') === false) { - $pTypeKey = $params['order']->module; - } else { - $pTypeKey = $params['order']->payment; - } - - $this->api->ordersCreate( - array( - 'externalId' => $params['order']->id, - 'orderType' => 'eshop-individual', - 'orderMethod' => 'shopping-cart', - 'status' => 'new', - 'customerId' => $params['cart']->id_customer, - 'firstName' => $params['customer']->firstname, - 'lastName' => $params['customer']->lastname, - 'phone' => $address['phone'], - 'email' => $params['customer']->email, - 'paymentType' => $payment->$pTypeKey, - 'delivery' => array( - 'code' => $delivery->$dTypeKey, - 'cost' => $params['order']->total_shipping, - 'address' => array( - 'city' => $address['city'], - 'index' => $address['postcode'], - 'text' => $address['address1'], - ) - ), - 'discount' => $params['order']->total_discounts, - 'items' => $items, - 'createdAt' => $params['order']->date_add - ) - ); - } - catch (CurlException $e) { - error_log('orderCreate: connection error', 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - } - catch (InvalidJsonException $e) { - error_log('orderCreate: ' . $e->getMessage(), 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - } - - } - - if (!empty($params['newOrderStatus'])) { - $statuses = OrderState::getOrderStates($this->default_lang); - $aStatuses = json_decode(Configuration::get('RETAILCRM_API_STATUS')); - foreach ($statuses as $status) { - if ($status['name'] == $params['newOrderStatus']->name) { - $currStatus = $status['id_order_state']; - try { - $this->api->ordersEdit( - array( - 'externalId' => $params['id_order'], - 'status' => $aStatuses->$currStatus - ) - ); - } - catch (CurlException $e) { - error_log('orderStatusUpdate: connection error', 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - } - catch (InvalidJsonException $e) { - error_log('orderStatusUpdate: ' . $e->getMessage(), 3, _PS_ROOT_DIR_ . "log/retailcrm.log"); - } - } - } - } + $allowed = array('1.4', '1.5', '1.6'); + $version = substr(_PS_VERSION_, 0, 3); + if (!in_array($version, $allowed)) { + exit; + } else { + require_once (dirname(__FILE__) . '/bootstrap.php'); + require(dirname(__FILE__) . '/version.' . $version . '.php'); } } + diff --git a/retailcrm/version.1.6.php b/retailcrm/version.1.6.php new file mode 100644 index 0000000..188ac27 --- /dev/null +++ b/retailcrm/version.1.6.php @@ -0,0 +1,433 @@ +name = 'retailcrm'; + $this->tab = 'market_place'; + $this->version = '1.1'; + $this->author = 'Retail Driver LCC'; + $this->displayName = $this->l('RetailCRM'); + $this->description = $this->l('Integration module for RetailCRM'); + $this->confirmUninstall = $this->l('Are you sure you want to uninstall?'); + + $this->apiUrl = Configuration::get('RETAILCRM_ADDRESS'); + $this->apiKey = Configuration::get('RETAILCRM_API_TOKEN'); + + if (!empty($this->apiUrl) && !empty($this->apiKey)) { + $this->api = new RetailcrmProxy($this->apiUrl, $this->apiKey, _PS_ROOT_DIR_ . '/retailcrm.log'); + $this->reference = new RetailcrmReferences($this->api); + } + $this->default_lang = (int)Configuration::get('PS_LANG_DEFAULT'); + $this->default_currency = (int)Configuration::get('PS_CURRENCY_DEFAULT'); + $this->default_country = (int)Configuration::get('PS_COUNTRY_DEFAULT'); + $this->response = array(); + $this->customerFix = array(); + $this->orderFix = array(); + $this->address_id = null; + $this->customer_id = null; + $this->customer = null; + parent::__construct(); + } + + function install() + { + return ( + parent::install() && + $this->registerHook('newOrder') && + $this->registerHook('actionOrderStatusPostUpdate') && + $this->registerHook('actionPaymentConfirmation') && + $this->registerHook('actionCustomerAccountAdd') + ); + } + + function uninstall() + { + return parent::uninstall() && + Configuration::deleteByName('RETAILCRM_ADDRESS') && + Configuration::deleteByName('RETAILCRM_API_TOKEN') && + Configuration::deleteByName('RETAILCRM_API_STATUS') && + Configuration::deleteByName('RETAILCRM_API_DELIVERY') && + Configuration::deleteByName('RETAILCRM_LAST_SYNC') && + Configuration::deleteByName('RETAILCRM_API_ADDR'); + } + + public function getContent() + { + $output = null; + + $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')); + $delivery = json_encode(Tools::getValue('RETAILCRM_API_DELIVERY')); + $status = json_encode(Tools::getValue('RETAILCRM_API_STATUS')); + $payment = json_encode(Tools::getValue('RETAILCRM_API_PAYMENT')); + $order_address = json_encode(Tools::getValue('RETAILCRM_API_ADDR')); + + if (!$address || empty($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')); + } else { + Configuration::updateValue('RETAILCRM_ADDRESS', $address); + Configuration::updateValue('RETAILCRM_API_TOKEN', $token); + Configuration::updateValue('RETAILCRM_API_DELIVERY', $delivery); + Configuration::updateValue('RETAILCRM_API_STATUS', $status); + Configuration::updateValue('RETAILCRM_API_PAYMENT', $payment); + Configuration::updateValue('RETAILCRM_API_ADDR', $order_address); + $output .= $this->displayConfirmation($this->l('Settings updated')); + } + } + + $this->display(__FILE__, 'retailcrm.tpl'); + + return $output . $this->displayForm(); + } + + public function displayForm() + { + + $this->displayConfirmation($this->l('Settings updated')); + + $default_lang = $this->default_lang; + $intaroCrm = $this->api; + + /* + * Network connection form + */ + $fields_form[0]['form'] = array( + 'legend' => array( + 'title' => $this->l('Network connection'), + ), + 'input' => array( + array( + 'type' => 'text', + 'label' => $this->l('CRM address'), + 'name' => 'RETAILCRM_ADDRESS', + 'size' => 20, + 'required' => true + ), + array( + 'type' => 'text', + 'label' => $this->l('CRM token'), + 'name' => 'RETAILCRM_API_TOKEN', + 'size' => 20, + 'required' => true + ) + ), + 'submit' => array( + 'title' => $this->l('Save'), + 'class' => 'button' + ) + ); + + + if (!empty($this->apiUrl) && !empty($this->apiKey)) { + /* + * Delivery + */ + $fields_form[1]['form'] = array( + 'legend' => array( + 'title' => $this->l('Delivery'), + ), + 'input' => $this->reference->getDeliveryTypes(), + ); + + /* + * Order status + */ + $fields_form[2]['form'] = array( + 'legend' => array( + 'title' => $this->l('Order statuses'), + ), + 'input' => $this->reference->getStatuses(), + ); + + /* + * Payment + */ + $fields_form[3]['form'] = array( + 'legend' => array( + 'title' => $this->l('Payment types'), + ), + 'input' => $this->reference->getPaymentTypes(), + ); + } + + /* + * Address fields + */ + $fields_form[4]['form'] = array( + 'legend' => array( + 'title' => $this->l('Address'), + ), + 'input' => $this->getAddressFields() + ); + + + /* + * Diplay forms + */ + + $helper = new HelperForm(); + + $helper->module = $this; + $helper->name_controller = $this->name; + $helper->token = Tools::getAdminTokenLite('AdminModules'); + $helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name; + + $helper->default_form_language = $default_lang; + $helper->allow_employee_form_lang = $default_lang; + + $helper->title = $this->displayName; + $helper->show_toolbar = true; + $helper->toolbar_scroll = true; + $helper->submit_action = 'submit' . $this->name; + $helper->toolbar_btn = array( + 'save' => + array( + 'desc' => $this->l('Save'), + 'href' => sprintf( + "%s&configure=%s&save%s&token=%s", + AdminController::$currentIndex, + $this->name, + $this->name, + Tools::getAdminTokenLite('AdminModules') + ) + ), + 'back' => array( + 'href' => AdminController::$currentIndex . '&token=' . Tools::getAdminTokenLite('AdminModules'), + 'desc' => $this->l('Back to list') + ) + ); + + $helper->fields_value['RETAILCRM_ADDRESS'] = Configuration::get('RETAILCRM_ADDRESS'); + $helper->fields_value['RETAILCRM_API_TOKEN'] = Configuration::get('RETAILCRM_API_TOKEN'); + + $deliverySettings = Configuration::get('RETAILCRM_API_DELIVERY'); + if (isset($deliverySettings) && $deliverySettings != '') { + $deliveryTypes = json_decode($deliverySettings); + foreach ($deliveryTypes as $idx => $delivery) { + $name = 'RETAILCRM_API_DELIVERY[' . $idx . ']'; + $helper->fields_value[$name] = $delivery; + } + } + + $statusSettings = Configuration::get('RETAILCRM_API_STATUS'); + if (isset($statusSettings) && $statusSettings != '') { + $statusTypes = json_decode($statusSettings); + foreach ($statusTypes as $idx => $status) { + $name = 'RETAILCRM_API_STATUS[' . $idx . ']'; + $helper->fields_value[$name] = $status; + } + } + + $paymentSettings = Configuration::get('RETAILCRM_API_PAYMENT'); + if (isset($paymentSettings) && $paymentSettings != '') { + $paymentTypes = json_decode($paymentSettings); + foreach ($paymentTypes as $idx => $payment) { + $name = 'RETAILCRM_API_PAYMENT[' . $idx . ']'; + $helper->fields_value[$name] = $payment; + } + } + + $addressSettings = Configuration::get('RETAILCRM_API_ADDR'); + if (isset($addressSettings) && $addressSettings != '') { + $addressTypes = json_decode($addressSettings); + foreach ($addressTypes as $idx => $address) { + $name = 'RETAILCRM_API_ADDR[' . $idx . ']'; + $helper->fields_value[$name] = $address; + } + } + + return $helper->generateForm($fields_form); + } + + public function getAddressFields() + { + $addressFields = array(); + $address = explode(' ', str_replace("\n", ' ', AddressFormat::getAddressCountryFormat($this->context->country->id))); + + if (!empty($address)) { + foreach ($address as $idx => $a) { + if (!in_array($a, array('vat_number', 'phone_mobile', 'company'))) { + if (!strpos($a, ':')) { + $a = preg_replace('/_/', ' ', $a); + $a = preg_replace('/[\,\.]/', '', $a); + $addressFields[] = array( + 'type' => 'select', + 'label' => $this->l((string)ucfirst($a)), + 'name' => 'RETAILCRM_API_ADDR[' . $idx . ']', + 'required' => false, + 'options' => array( + 'query' => array( + array('name' => '', 'id_option' => ''), + array('name' => $this->l('FIRST_NAME'), 'id_option' => 'first_name'), + array('name' => $this->l('LAST_NAME'), 'id_option' => 'last_name'), + array('name' => $this->l('PHONE'), 'id_option' => 'phone'), + array('name' => $this->l('EMAIL'), 'id_option' => 'email'), + array('name' => $this->l('ADDRESS'), 'id_option' => 'address'), + array('name' => $this->l('COUNTRY'), 'id_option' => 'country'), + array('name' => $this->l('REGION'), 'id_option' => 'region'), + array('name' => $this->l('CITY'), 'id_option' => 'city'), + array('name' => $this->l('ZIP'), 'id_option' => 'index'), + array('name' => $this->l('STREET'), 'id_option' => 'street'), + array('name' => $this->l('BUILDING'), 'id_option' => 'building'), + array('name' => $this->l('FLAT'), 'id_option' => 'flat'), + array('name' => $this->l('INTERCOMCODE'), 'id_option' => 'intercomcode'), + array('name' => $this->l('FLOOR'), 'id_option' => 'floor'), + array('name' => $this->l('BLOCK'), 'id_option' => 'block'), + array('name' => $this->l('HOUSE'), 'ID' => 'house') + ), + 'id' => 'id_option', + 'name' => 'name' + ) + ); + } + } + } + } + + return $addressFields; + } + + public function hookActionCustomerAccountAdd($params) + { + $this->api->customersCreate( + array( + 'externalId' => $params['newCustomer']->id, + 'firstName' => $params['newCustomer']->firstname, + 'lastName' => $params['newCustomer']->lastname, + 'email' => $params['newCustomer']->email, + 'createdAt' => $params['newCustomer']->date_add + ) + ); + } + + public function hookNewOrder($params) + { + return $this->hookActionOrderStatusPostUpdate($params); + } + + public function hookActionPaymentConfirmation($params) + { + $this->api->ordersEdit( + array( + 'externalId' => $params['id_order'], + 'paymentStatus' => 'paid', + 'createdAt' => $params['cart']->date_upd + ) + ); + + return $this->hookActionOrderStatusPostUpdate($params); + } + + public function hookActionOrderStatusPostUpdate($params) + { + $address_id = Address::getFirstCustomerAddressId($params['cart']->id_customer); + $sql = 'SELECT * FROM ' . _DB_PREFIX_ . 'address WHERE id_address=' . (int)$address_id; + $dbaddress = Db::getInstance()->ExecuteS($sql); + $address = $dbaddress[0]; + $delivery = json_decode(Configuration::get('RETAILCRM_API_DELIVERY')); + $payment = json_decode(Configuration::get('RETAILCRM_API_PAYMENT')); + $inCart = $params['cart']->getProducts(); + + if (isset($params['orderStatus'])) { + $this->api->customersEdit( + array( + 'externalId' => $params['cart']->id_customer, + 'lastName' => $params['customer']->lastname, + 'firstName' => $params['customer']->firstname, + 'email' => $params['customer']->email, + 'phones' => array( + array( + 'number' => $address['phone'], + ), + array( + 'number' => $address['phone_mobile'], + ) + ), + 'createdAt' => $params['customer']->date_add + ) + ); + + $items = array(); + foreach ($inCart as $item) { + $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'], + 'createdAt' => $item['date_add'] + ); + } + + $dTypeKey = $params['cart']->id_carrier; + + if (Module::getInstanceByName('advancedcheckout') === false) { + $pTypeKey = $params['order']->module; + } else { + $pTypeKey = $params['order']->payment; + } + + $this->api->ordersCreate( + array( + 'externalId' => $params['order']->id, + 'orderType' => 'eshop-individual', + 'orderMethod' => 'shopping-cart', + 'status' => 'new', + 'customerId' => $params['cart']->id_customer, + 'firstName' => $params['customer']->firstname, + 'lastName' => $params['customer']->lastname, + 'phone' => $address['phone'], + 'email' => $params['customer']->email, + 'paymentType' => $payment->$pTypeKey, + 'delivery' => array( + 'code' => $delivery->$dTypeKey, + 'cost' => $params['order']->total_shipping, + 'address' => array( + 'city' => $address['city'], + 'index' => $address['postcode'], + 'text' => $address['address1'], + ) + ), + 'discount' => $params['order']->total_discounts, + 'items' => $items, + 'createdAt' => $params['order']->date_add + ) + ); + } + + if (!empty($params['newOrderStatus'])) { + $statuses = OrderState::getOrderStates($this->default_lang); + $aStatuses = json_decode(Configuration::get('RETAILCRM_API_STATUS')); + foreach ($statuses as $status) { + if ($status['name'] == $params['newOrderStatus']->name) { + $currStatus = $status['id_order_state']; + $this->api->ordersEdit( + array( + 'externalId' => $params['id_order'], + 'status' => $aStatuses->$currStatus + ) + ); + } + } + } + } +}