diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c36965..44b0c89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2019-01-17 v3.4.0 +* Добавлена настройка Daemon Collector +* Изменена логика передачи данных по заказам и клиентам. Данные доставки передаются в заказ, данные оплаты в карточку клиента. + ## 2018-12-14 v3.3.8 * Добавлена выгрузка картинок для категорий товаров в ICML diff --git a/VERSION b/VERSION index 7cb75ca..fbcbf73 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3.8 \ No newline at end of file +3.4.0 \ No newline at end of file diff --git a/src/include/class-wc-retailcrm-customers.php b/src/include/class-wc-retailcrm-customers.php index 5ad1ef4..90f6d12 100644 --- a/src/include/class-wc-retailcrm-customers.php +++ b/src/include/class-wc-retailcrm-customers.php @@ -68,26 +68,67 @@ if (!class_exists('WC_Retailcrm_Customers')) : } /** - * Create customer in CRM + * @param array $orders * - * @param int $customer_id - * - * @return WC_Customer $customer + * @throws Exception */ - public function createCustomer($customer_id) + public function customersFromOrdersUpload($orders) { - if (!$this->retailcrm) { - return; + $data_customers = array(); + + foreach ($orders as $order_data) { + $order = wc_get_order($order_data->ID); + + if ($order->get_user()) { + continue; + } + + $customer = $this->buildCustomerFromOrderData($order); + $this->processCustomer($customer); + $data_customers[] = $this->customer; } - $customer = $this->wcCustomerGet($customer_id); + if ($data_customers) { + $data = \array_chunk($data_customers, 50); + + foreach ($data as $array_customers) { + $this->retailcrm->customersUpload($array_customers); + time_nanosleep(0, 250000000); + } + } + } + + /** + * Create customer in CRM + * + * @param int | WC_Customer $customer + * + * @return mixed + */ + public function createCustomer($customer) + { + if (!$this->retailcrm) { + return null; + } + + if (is_int($customer)) { + $customer = $this->wcCustomerGet($customer); + } + + if (!$customer instanceof WC_Customer) { + return null; + } if ($customer->get_role() == self::CUSTOMER_ROLE) { $this->processCustomer($customer); - $this->retailcrm->customersCreate($this->customer); + $response = $this->retailcrm->customersCreate($this->customer); + + if ($response->isSuccessful() && isset($response['id'])) { + return $response['id']; + } } - return $customer; + return null; } /** @@ -126,7 +167,7 @@ if (!class_exists('WC_Retailcrm_Customers')) : $firstName = $customer->get_first_name(); $data_customer = array( 'createdAt' => $createdAt->date('Y-m-d H:i:s'), - 'externalId' => $customer->get_id(), + 'externalId' => $customer->get_id() > 0 ? $customer->get_id() : uniqid(), 'firstName' => $firstName ? $firstName : $customer->get_username(), 'lastName' => $customer->get_last_name(), 'email' => $customer->get_email(), @@ -148,6 +189,58 @@ if (!class_exists('WC_Retailcrm_Customers')) : $this->customer = apply_filters('retailcrm_process_customer', $data_customer, $customer); } + /** + * @param array $filter + * + * @return bool|array + */ + public function searchCustomer($filter) + { + if (isset($filter['id'])) { + $search = $this->retailcrm->customersGet($filter['id']); + } elseif (isset($filter['email'])) { + $search = $this->retailcrm->customersList(array('email' => $filter['email'])); + } + + if ($search->isSuccessful()) { + if (isset($search['customers'])) { + if (empty($search['customers'])) { + return false; + } + + $customer = reset($search['customers']); + } else { + $customer = $search['customer']; + } + + return $customer; + } + + return false; + } + + /** + * @param WC_Order $order + * + * @return WC_Customer + * @throws Exception + */ + public function buildCustomerFromOrderData($order) + { + $new_customer = new WC_Customer; + + foreach ($order->get_address('billing') as $prop => $value) { + $new_customer->{'set_billing_' . $prop}($value); + } + + $new_customer->set_first_name($order->get_billing_first_name()); + $new_customer->set_last_name($order->get_billing_last_name()); + $new_customer->set_email($order->get_billing_email()); + $new_customer->set_date_created($order->get_date_created()); + + return $new_customer; + } + /** * @param int $customer_id * diff --git a/src/include/class-wc-retailcrm-history.php b/src/include/class-wc-retailcrm-history.php index 164fe13..852704e 100644 --- a/src/include/class-wc-retailcrm-history.php +++ b/src/include/class-wc-retailcrm-history.php @@ -93,6 +93,14 @@ if ( ! class_exists( 'WC_Retailcrm_History' ) ) : continue; } + if (isset($record['customer']['externalId'])) { + $customer = new WC_Customer($record['customer']['externalId']); + + if ($customer->get_id() == 0) { + continue; + } + } + WC_Retailcrm_Plugin::$history_run = true; if ($record['field'] == 'first_name' && isset($record['customer']['externalId'])) { @@ -102,7 +110,7 @@ if ( ! class_exists( 'WC_Retailcrm_History' ) ) : } elseif ($record['field'] == 'last_name' && isset($record['customer']['externalId'])) { - if ($record['newValue']){ + if ($record['newValue']) { update_user_meta($record['customer']['externalId'], 'last_name', $record['newValue']); } } diff --git a/src/include/class-wc-retailcrm-orders.php b/src/include/class-wc-retailcrm-orders.php index 5b65e0c..5a08a24 100644 --- a/src/include/class-wc-retailcrm-orders.php +++ b/src/include/class-wc-retailcrm-orders.php @@ -65,12 +65,17 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : $orders_data[] = $this->order; } - if ($withCustomers === true && !empty($customers)) { - if (!class_exists('WC_Retailcrm_Customers')) { - include_once(WC_Retailcrm_Base::checkCustomFile('customers')); - } + if (!class_exists('WC_Retailcrm_Customers')) { + include_once(WC_Retailcrm_Base::checkCustomFile('customers')); + } - $retailcrmCustomer = new WC_Retailcrm_Customers($this->retailcrm); + $retailcrmCustomer = new WC_Retailcrm_Customers($this->retailcrm); + + if (!$include) { + $retailcrmCustomer->customersFromOrdersUpload($orders); + } + + if ($withCustomers === true && !empty($customers)) { $retailcrmCustomer->customersUpload($customers); } @@ -101,21 +106,35 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : $this->processOrder($order); $customer = $order->get_user(); + if (!class_exists('WC_Retailcrm_Customers')) { + include_once(WC_Retailcrm_Base::checkCustomFile('customers')); + } + + $retailcrm_customers = new WC_Retailcrm_Customers($this->retailcrm); + if ($customer != false) { - $search = $this->retailcrm->customersGet($customer->get('ID')); + $search = $retailcrm_customers->searchCustomer(array('id' => $customer->get('ID'))); - if (!$search->isSuccessful()) { - $customer_data = array( - 'externalId' => $customer->get('ID'), - 'firstName' => $this->order['firstName'], - 'lastName' => $this->order['lastName'], - 'email' => $this->order['email'] - ); - - $this->retailcrm->customersCreate($customer_data); + if (!$search) { + $retailcrm_customers->createCustomer($customer); } else { - $this->order['customer']['externalId'] = $search['customer']['externalId']; + $this->order['customer']['externalId'] = $search['externalId']; } + } else { + $search = $retailcrm_customers->searchCustomer(array('email' => $order->get_billing_email())); + + if (!$search) { + $new_customer = $retailcrm_customers->buildCustomerFromOrderData($order); + $id = $retailcrm_customers->createCustomer($new_customer); + + if ($id !== null) { + $this->order['customer']['id'] = $id; + } + } else { + $this->order['customer']['externalId'] = $search['externalId']; + } + + unset($new_customer); } $this->retailcrm->ordersCreate($this->order); @@ -294,36 +313,28 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : $user_data_billing = $order->get_address('billing'); if (!empty($user_data_billing)) { - if (!empty($user_data_billing['phone'])) $order_data['phone'] = $user_data_billing['phone']; - if (!empty($user_data_billing['email'])) $order_data['email'] = $user_data_billing['email']; - if (!empty($user_data_billing['first_name'])) $order_data['firstName'] = $user_data_billing['first_name']; - if (!empty($user_data_billing['last_name'])) $order_data['lastName'] = $user_data_billing['last_name']; - if (!empty($user_data_billing['postcode'])) $order_data['delivery']['address']['index'] = $user_data_billing['postcode']; - if (!empty($user_data_billing['city'])) $order_data['delivery']['address']['city'] = $user_data_billing['city']; - if (!empty($user_data_billing['state'])) $order_data['delivery']['address']['region'] = $user_data_billing['state']; - if (!empty($user_data_billing['country'])) $order_data['countryIso'] = $user_data_billing['country']; + $order_data['phone'] = $user_data_billing['phone']; + $order_data['email'] = $user_data_billing['email']; } - $user_data = $order->get_address('shipping'); + $user_data_shipping = $order->get_address('shipping'); - if (!empty($user_data)) { - if (!empty($user_data['phone'])) $order_data['phone'] = $user_data['phone']; - if (!empty($user_data['email'])) $order_data['email'] = $user_data['email']; - if (!empty($user_data['first_name'])) $order_data['firstName'] = $user_data['first_name']; - if (!empty($user_data['last_name'])) $order_data['lastName'] = $user_data['last_name']; - if (!empty($user_data['postcode'])) $order_data['delivery']['address']['index'] = $user_data['postcode']; - if (!empty($user_data['city'])) $order_data['delivery']['address']['city'] = $user_data['city']; - if (!empty($user_data['state'])) $order_data['delivery']['address']['region'] = $user_data['state']; - if (!empty($user_data['country'])) $order_data['delivery']['address']['countryIso'] = $user_data['country']; + if (!empty($user_data_shipping)) { + $order_data['firstName'] = $user_data_shipping['first_name']; + $order_data['lastName'] = $user_data_shipping['last_name']; + $order_data['delivery']['address']['index'] = $user_data_shipping['postcode']; + $order_data['delivery']['address']['city'] = $user_data_shipping['city']; + $order_data['delivery']['address']['region'] = $user_data_shipping['state']; + $order_data['countryIso'] = $user_data_shipping['country']; } $order_data['delivery']['address']['text'] = sprintf( "%s %s %s %s %s", - !empty($user_data_billing['postcode']) ? $user_data_billing['postcode'] : $user_data['postcode'], - !empty($user_data_billing['state']) ? $user_data_billing['state'] : $user_data['state'], - !empty($user_data_billing['city']) ? $user_data_billing['city'] : $user_data['city'], - !empty($user_data_billing['address_1']) ? $user_data_billing['address_1'] : $user_data['address_1'], - !empty($user_data_billing['address_2']) ? $user_data_billing['address_2'] : $user_data['address_2'] + $user_data_shipping['postcode'], + $user_data_shipping['state'], + $user_data_shipping['city'], + $user_data_shipping['address_1'], + $user_data_shipping['address_2'] ); $order_items = array(); @@ -414,8 +425,7 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : $payment['paidAt'] = trim($pay_date->date('Y-m-d H:i:s')); } - if ($update === false){ - + if ($update === false) { if (isset($this->retailcrm_settings[$order->get_payment_method()])) { $payment['type'] = $this->retailcrm_settings[$order->get_payment_method()]; } diff --git a/src/readme.txt b/src/readme.txt index 98a2ed3..f09edc0 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -45,6 +45,10 @@ API-ключ должен быть для отдельного магазина 2. В появившихся списках справочников настройте соответствие способов доставки и оплаты, а так же статусов заказов. Отметьте галочку "Выгружать остатки", если хотите выгружать остатки из Retailcrm в магазин (подробнее смотрите в описании). == Changelog == += 3.4.0 = +* Добавлена настройка Daemon Collector +* Изменена логика передачи данных по заказам и клиентам. Данные доставки передаются в заказ, данные оплаты в карточку клиента. + = 3.3.8 = * Добавлена выгрузка картинок для категорий товаров в ICML @@ -159,6 +163,9 @@ API-ключ должен быть для отдельного магазина * Исправелены ошибки. == Upgrade Notice == += 3.4.0 = +Внедрен Daemon Collector + = 3.3.5 = После обновления плагина необходимо пересохранить настройки для того, чтобы активировать модуль в маркетплейсе retailCRM diff --git a/src/retailcrm.php b/src/retailcrm.php index 65437d8..644c91a 100644 --- a/src/retailcrm.php +++ b/src/retailcrm.php @@ -1,6 +1,6 @@ getMock(); + $this->responseMock->expects($this->any()) + ->method('isSuccessful') + ->willReturn(true); + + $this->apiMock->expects($this->any()) + ->method('customersCreate') + ->willReturn($this->responseMock); + $this->customer = new WC_Customer(); $this->customer->set_email(uniqid(md5(date('Y-m-d H:i:s'))) . '@mail.com'); $this->customer->set_password('password'); - $this->customer->set_role(WC_Retailcrm_Customers::CUSTOMER_ROLE); $this->customer->set_billing_phone('89000000000'); $this->customer->save(); } @@ -73,7 +80,7 @@ class WC_Retailcrm_Customers_Test extends WC_Retailcrm_Test_Case_Helper public function test_create_customer($retailcrm) { $retailcrm_customer = new WC_Retailcrm_Customers($retailcrm); - $customer = $retailcrm_customer->createCustomer($this->customer->get_id()); + $id = $retailcrm_customer->createCustomer($this->customer->get_id()); $customer_send = $retailcrm_customer->getCustomer(); if ($retailcrm) { @@ -84,9 +91,8 @@ class WC_Retailcrm_Customers_Test extends WC_Retailcrm_Test_Case_Helper $this->assertNotEmpty($customer_send['externalId']); $this->assertNotEmpty($customer_send['firstName']); $this->assertNotEmpty($customer_send['email']); - $this->assertInstanceOf('WC_Customer', $customer); } else { - $this->assertEquals(null, $customer); + $this->assertEquals(null, $id); $this->assertEquals(array(), $customer_send); } } diff --git a/tests/phpunit/test-wc-retailcrm-orders.php b/tests/phpunit/test-wc-retailcrm-orders.php index 5907045..0e8fe8a 100644 --- a/tests/phpunit/test-wc-retailcrm-orders.php +++ b/tests/phpunit/test-wc-retailcrm-orders.php @@ -18,7 +18,8 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper 'customersGet', 'customersCreate', 'ordersPaymentCreate', - 'ordersPaymentDelete' + 'ordersPaymentDelete', + 'customersList' )) ->getMock(); @@ -50,6 +51,36 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper */ public function test_order_create($retailcrm, $apiVersion) { + if ($retailcrm) { + $responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper') + ->disableOriginalConstructor() + ->setMethods(array( + 'isSuccessful' + )) + ->getMock(); + + $responseMockCustomers = $this->getMockBuilder('\WC_Retailcrm_Response_Helper') + ->disableOriginalConstructor() + ->setMethods(array( + 'isSuccessful' + )) + ->getMock(); + $responseMockCustomers->setResponse( + array('success' => true, + 'customers' => array( + array('externalId' => 1) + ) + ) + ); + + $retailcrm->expects($this->any()) + ->method('customersCreate') + ->willReturn($responseMock); + $retailcrm->expects($this->any()) + ->method('customersList') + ->willReturn($responseMockCustomers); + } + $this->createTestOrder(); $this->options = $this->setOptions($apiVersion); $retailcrm_orders = new WC_Retailcrm_Orders($retailcrm); @@ -252,7 +283,16 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper private function createTestOrder() { + /** @var WC_Order order */ $this->order = WC_Helper_Order::create_order(0); + + foreach ($this->order->get_address('billing') as $prop => $value) { + if (method_exists($this->order, 'set_shipping_' . $prop)) { + $this->order->{'set_shipping_' . $prop}($value); + } + } + + $this->order->save(); } private function getResponseData($externalId)