1
0
mirror of synced 2025-01-30 23:01:43 +03:00

Corporate clients support

* corporate customers support
* skip new payments without type
* extract customer data from order for guests
* extract customer phone and email from order for guests
* set item discount to zero if no discount applies
* create order from back-office
* sync phone via history
* fixed customer squashing
* fixed createdAt crash
* fixed customer id assigning & possible crash after errors in order creation
This commit is contained in:
Pavel 2020-07-10 13:14:03 +03:00 committed by GitHub
parent 53f6327da0
commit 804cbfac37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 7142 additions and 985 deletions

View File

@ -22,7 +22,7 @@ RUN apt-get install -y subversion
RUN apt-get install -y wget RUN apt-get install -y wget
RUN wget -O /usr/bin/phpunit https://phar.phpunit.de/phpunit-7.phar && chmod +x /usr/bin/phpunit RUN wget -O /usr/bin/phpunit https://phar.phpunit.de/phpunit-7.phar && chmod +x /usr/bin/phpunit
RUN curl --insecure https://getcomposer.org/composer.phar -o /usr/bin/composer && chmod +x /usr/bin/composer RUN curl --insecure https://getcomposer.org/download/1.9.3/composer.phar -o /usr/bin/composer && chmod +x /usr/bin/composer
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y nodejs RUN apt-get install -y nodejs

View File

@ -1,6 +1,12 @@
# MySQL host and credentials
DB_NAME=wc_retailcrm_test DB_NAME=wc_retailcrm_test
DB_USER=wc_retailcrm DB_USER=wc_retailcrm
DB_PASS=wc_retailcrm DB_PASS=wc_retailcrm
DB_HOST=mysql DB_HOST=mysql
# WordPress and WooCommerce versions
WP_VERSION=4.4 WP_VERSION=4.4
WC_VERSION=3.0.0 WC_VERSION=3.0.0
# Enable this in order to pipe all module log messages (including debug ones) to STDOUT.
MODULE_LOGS_TO_STDOUT=0

View File

@ -1,3 +1,7 @@
## 2020-06-18 4.0.0
* Поддержка корпоративных клиентов
* Поддержка изменения покупателя в заказе
## 2020-06-18 3.6.4 ## 2020-06-18 3.6.4
* Передача названия региона / штата / провинции вместо кода * Передача названия региона / штата / провинции вместо кода

View File

@ -1 +1 @@
3.6.4 4.0.0

View File

@ -9,7 +9,9 @@
} }
], ],
"minimum-stability": "dev", "minimum-stability": "dev",
"require": {}, "require": {
"ext-simplexml": "*"
},
"require-dev": { "require-dev": {
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",

View File

@ -222,3 +222,9 @@ msgstr "Transferencia de un número de pedido"
msgid "Transferring the payment amount" msgid "Transferring the payment amount"
msgstr "Transferencia de un monto de pago" msgstr "Transferencia de un monto de pago"
msgid "Corporate customers support"
msgstr "Soporte a clientes corporativos"
msgid "Enabled"
msgstr "Habilitado"

View File

@ -231,3 +231,9 @@ msgstr "Передача номера заказа"
msgid "Transferring the payment amount" msgid "Transferring the payment amount"
msgstr "Передача суммы оплаты" msgstr "Передача суммы оплаты"
msgid "Corporate customers support"
msgstr "Поддержка корпоративных клиентов"
msgid "Enabled"
msgstr "Включено"

View File

@ -15,6 +15,20 @@
<field id="personal_discount" group="customer">personalDiscount</field> <field id="personal_discount" group="customer">personalDiscount</field>
<field id="discount_card_number" group="customer">discountCardNumber</field> <field id="discount_card_number" group="customer">discountCardNumber</field>
<field id="id" group="customerCorporate">id</field>
<field id="external_id" group="customerCorporate">externalId</field>
<field id="nick_name" group="customerCorporate">nickName</field>
<field id="vip" group="customerCorporate">vip</field>
<field id="bad" group="customerCorporate">bad</field>
<field id="custom_fields" group="customerCorporate">customFields</field>
<field id="personal_discount" group="customerCorporate">personalDiscount</field>
<field id="discount_card_number" group="customerCorporate">discountCardNumber</field>
<field id="manager" group="customerCorporate">manager</field>
<field id="address" group="customerCorporate">address</field>
<field id="main_contact" group="customerCorporate">mainCustomerContact</field>
<field id="company.contragent.i_n_n" group="customerCorporate">companyInn</field>
<field id="main_company" group="customerCorporate">company</field>
<field id="address.index" group="customerAddress">index</field> <field id="address.index" group="customerAddress">index</field>
<field id="address.country" group="customerAddress">country</field> <field id="address.country" group="customerAddress">country</field>
<field id="address.region" group="customerAddress">region</field> <field id="address.region" group="customerAddress">region</field>
@ -45,6 +59,7 @@
<field id="order_method" group="order">orderMethod</field> <field id="order_method" group="order">orderMethod</field>
<field id="site" group="order">site</field> <field id="site" group="order">site</field>
<field id="status" group="order">status</field> <field id="status" group="order">status</field>
<field id="customer" group="order">customer</field>
<field id="manager" group="order">manager</field> <field id="manager" group="order">manager</field>
<field id="first_name" group="order">firstName</field> <field id="first_name" group="order">firstName</field>
<field id="last_name" group="order">lastName</field> <field id="last_name" group="order">lastName</field>
@ -62,6 +77,8 @@
<field id="shipment_store" group="order">shipmentStore</field> <field id="shipment_store" group="order">shipmentStore</field>
<field id="shipment_date" group="order">shipmentDate</field> <field id="shipment_date" group="order">shipmentDate</field>
<field id="shipped" group="order">shipped</field> <field id="shipped" group="order">shipped</field>
<field id="contact" group="order">contact</field>
<field id="company" group="order">company</field>
<!--<field id="order_product" group="order">item</field>--> <!--<field id="order_product" group="order">item</field>-->
<field id="payment" group="order">payment</field> <field id="payment" group="order">payment</field>
<field id="payments.amount" group="order">amount</field> <field id="payments.amount" group="order">amount</field>

View File

@ -0,0 +1,86 @@
<?php
/**
* Class WC_Retailcrm_Abstract_Builder.
*/
abstract class WC_Retailcrm_Abstract_Builder implements WC_Retailcrm_Builder_Interface
{
/** @var array|mixed $data */
protected $data;
/**
* @param array|mixed $data
*
* @return \WC_Retailcrm_Abstract_Builder
*/
public function setData($data)
{
$this->data = $data;
return $this;
}
/**
* @return array|mixed
*/
public function getData()
{
return $this->data;
}
/**
* @return $this|\WC_Retailcrm_Builder_Interface
*/
public function reset()
{
$this->data = array();
return $this;
}
/**
* Returns key if it's present in data array (or object which implements ArrayAccess).
* Returns default value if key is not present in data, or data is not accessible as array.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
protected function dataValue($key, $default = '')
{
return self::arrayValue($this->data, $key, $default);
}
/**
* Returns key from array if it's present in array
*
* @param array|\ArrayObject $data
* @param mixed $key
* @param string $default
*
* @return mixed|string
*/
protected static function arrayValue($data, $key, $default = '')
{
if (!is_array($data) && !($data instanceof ArrayAccess)) {
return $default;
}
if (array_key_exists($key, $data) && !empty($data[$key])) {
return $data[$key];
}
return $default;
}
/**
* @return \WC_Retailcrm_Builder_Interface
*/
abstract public function build();
/**
* Returns builder result. Should return null if WC_Retailcrm_Abstract_Builder::isBuilt() == false.
*
* @return mixed|null
*/
abstract public function getResult();
}

View File

@ -11,6 +11,19 @@
abstract class WC_Retailcrm_Abstracts_Address extends WC_Retailcrm_Abstracts_Data abstract class WC_Retailcrm_Abstracts_Address extends WC_Retailcrm_Abstracts_Data
{ {
const ADDRESS_TYPE_BILLING = 'billing';
const ADDRESS_TYPE_SHIPPING = 'shipping';
/** @var string $address_type */
protected $address_type = 'shipping';
/** @var bool $fallback_to_billing */
protected $fallback_to_billing = false;
/** @var bool $fallback_to_shipping */
protected $fallback_to_shipping = false;
/** @var array $data */
protected $data = array( protected $data = array(
'index' => '', 'index' => '',
'city' => '', 'city' => '',
@ -18,6 +31,9 @@ abstract class WC_Retailcrm_Abstracts_Address extends WC_Retailcrm_Abstracts_Dat
'text' => '', 'text' => '',
); );
/**
* Resets inner state
*/
public function reset_data() public function reset_data()
{ {
$this->data = array( $this->data = array(
@ -26,6 +42,86 @@ abstract class WC_Retailcrm_Abstracts_Address extends WC_Retailcrm_Abstracts_Dat
'region' => '', 'region' => '',
'text' => '', 'text' => '',
); );
return $this;
}
/**
* @param bool $fallback_to_billing
*
* @return self
*/
public function setFallbackToBilling($fallback_to_billing)
{
$this->fallback_to_billing = $fallback_to_billing;
return $this;
}
/**
* @param bool $fallback_to_shipping
*
* @return WC_Retailcrm_Abstracts_Address
*/
public function setFallbackToShipping($fallback_to_shipping)
{
$this->fallback_to_shipping = $fallback_to_shipping;
return $this;
}
/**
* Sets woocommerce address type to work with
*
* @param string $addressType
*
* @return self
*/
public function setWCAddressType($addressType = WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_SHIPPING)
{
$this->address_type = $addressType;
return $this;
}
/**
* Returns address from order. Respects fallback_to_billing parameter.
*
* @param \WC_Order $order
*
* @return array
*/
protected function getOrderAddress($order)
{
$orderAddress = $order->get_address($this->address_type);
if (empty($orderAddress) && $this->address_type === self::ADDRESS_TYPE_BILLING && $this->fallback_to_shipping) {
$orderAddress = $order->get_address(self::ADDRESS_TYPE_SHIPPING);
}
if (empty($orderAddress) && $this->address_type === self::ADDRESS_TYPE_SHIPPING && $this->fallback_to_billing) {
$orderAddress = $order->get_address(self::ADDRESS_TYPE_BILLING);
}
return $orderAddress;
}
/**
* Glue two addresses
*
* @param string $address1
* @param string $address2
*
* @return string
*/
protected function joinAddresses($address1 = '', $address2 = '')
{
if (empty($address1) && empty($address2)) {
return '';
}
if (empty($address2) && !empty($address1)) {
return $address1;
}
return $address1 . ', ' . $address2;
} }
/** /**

View File

@ -58,6 +58,14 @@ abstract class WC_Retailcrm_Abstracts_Data
*/ */
public function get_data() public function get_data()
{ {
return apply_filters('retailcrm_before_send_' . $this->filter_name, $this->data); return apply_filters('retailcrm_before_send_' . $this->filter_name, WC_Retailcrm_Plugin::clearArray($this->data));
}
/**
* @return array
*/
protected function get_data_without_filters()
{
return $this->data;
} }
} }

View File

@ -122,11 +122,6 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
) )
); );
$api_version_list = array(
'v4' => 'v4',
'v5' => 'v5'
);
$this->form_fields[] = array( $this->form_fields[] = array(
'title' => __( 'API settings', 'retailcrm' ), 'title' => __( 'API settings', 'retailcrm' ),
'type' => 'title', 'type' => 'title',
@ -134,23 +129,22 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
'id' => 'api_options' 'id' => 'api_options'
); );
$this->form_fields['api_version'] = array(
'title' => __( 'API version', 'retailcrm' ),
'description' => __( 'Select API version', 'retailcrm' ),
'css' => 'min-width:50px;',
'class' => 'select',
'type' => 'select',
'options' => $api_version_list,
'desc_tip' => true,
);
$this->form_fields['send_payment_amount'] = array( $this->form_fields['send_payment_amount'] = array(
'title' => __( 'Transferring the payment amount', 'retailcrm' ), 'title' => __( 'Transferring the payment amount', 'retailcrm' ),
'label' => ' ', 'label' => ' ',
'description' => '', 'description' => '',
'class' => 'checkbox', 'class' => 'checkbox',
'type' => 'checkbox', 'type' => 'checkbox',
'desc_tip' => true, 'desc_tip' => true
);
$this->form_fields['corporate_enabled'] = array(
'title' => __('Corporate customers support', 'retailcrm'),
'label' => __('Enabled'),
'description' => '',
'class' => 'checkbox',
'type' => 'checkbox',
'desc_tip' => true
); );
$this->form_fields[] = array( $this->form_fields[] = array(
@ -563,40 +557,6 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
return ob_get_clean(); return ob_get_clean();
} }
/**
* Validate API version
*
* @param string $key
* @param string $value
*
* @return string
*/
public function validate_api_version_field($key, $value)
{
$post = $this->get_post_data();
$versionMap = array(
'v4' => '4.0',
'v5' => '5.0'
);
$api = new WC_Retailcrm_Proxy(
$post[$this->plugin_id . $this->id . '_api_url'],
$post[$this->plugin_id . $this->id . '_api_key']
);
$response = $api->apiVersions();
if (!empty($response) && $response->isSuccessful()) {
if (!in_array($versionMap[$value], $response['versions'])) {
WC_Admin_Settings::add_error( esc_html__( 'The selected API version is unavailable', 'retailcrm' ) );
$value = '';
}
}
return $value;
}
/** /**
* Validate API url * Validate API url
* *
@ -610,7 +570,8 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
$post = $this->get_post_data(); $post = $this->get_post_data();
$api = new WC_Retailcrm_Proxy( $api = new WC_Retailcrm_Proxy(
$value, $value,
$post[$this->plugin_id . $this->id . '_api_key'] $post[$this->plugin_id . $this->id . '_api_key'],
$this->get_option('corporate_enabled', 'no') === 'yes'
); );
$response = $api->apiVersions(); $response = $api->apiVersions();
@ -636,7 +597,8 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
$post = $this->get_post_data(); $post = $this->get_post_data();
$api = new WC_Retailcrm_Proxy( $api = new WC_Retailcrm_Proxy(
$post[$this->plugin_id . $this->id . '_api_url'], $post[$this->plugin_id . $this->id . '_api_url'],
$value $value,
$this->get_option('corporate_enabled', 'no') === 'yes'
); );
$response = $api->apiVersions(); $response = $api->apiVersions();
@ -645,7 +607,7 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
$value = ''; $value = '';
} }
if (!$response->isSuccessful()) { if (empty($response) || !$response->isSuccessful()) {
WC_Admin_Settings::add_error( esc_html__( 'Enter the correct API key', 'retailcrm' ) ); WC_Admin_Settings::add_error( esc_html__( 'Enter the correct API key', 'retailcrm' ) );
$value = ''; $value = '';
} }

File diff suppressed because it is too large Load Diff

View File

@ -15,64 +15,127 @@ if ( ! class_exists( 'WC_Retailcrm_Proxy' ) ) :
class WC_Retailcrm_Proxy class WC_Retailcrm_Proxy
{ {
protected $retailcrm; protected $retailcrm;
protected $logger; protected $corporateEnabled;
public function __construct($api_url, $api_key, $api_vers = null) public function __construct($api_url, $api_key, $corporateEnabled = false)
{ {
$this->logger = new WC_Logger(); $this->corporateEnabled = $corporateEnabled;
if ( ! class_exists( 'WC_Retailcrm_Client_V4' ) ) {
include_once( __DIR__ . '/class-wc-retailcrm-client-v4.php' );
}
if ( ! class_exists( 'WC_Retailcrm_Client_V5' ) ) { if ( ! class_exists( 'WC_Retailcrm_Client_V5' ) ) {
include_once( __DIR__ . '/class-wc-retailcrm-client-v5.php' ); include_once( __DIR__ . '/class-wc-retailcrm-client-v5.php' );
} }
switch ($api_vers) { $this->retailcrm = new WC_Retailcrm_Client_V5($api_url, $api_key, 'v5');
case 'v4':
$this->retailcrm = new WC_Retailcrm_Client_V4($api_url, $api_key, $api_vers);
break;
case 'v5':
$this->retailcrm = new WC_Retailcrm_Client_V5($api_url, $api_key, $api_vers);
break;
case null:
$this->retailcrm = new WC_Retailcrm_Client_V4($api_url, $api_key, $api_vers);
break;
} }
/**
* getCorporateEnabled
*
* @return bool
*/
public function getCorporateEnabled()
{
return $this->corporateEnabled;
}
private static function reduceErrors($errors)
{
$result = '';
foreach ($errors as $key => $error) {
$result .= " [$key] => $error";
}
return $result;
}
/**
* Response will be omitted in debug logs for those methods
*
* @return string[]
*/
private function methodsWithoutDebugResponse()
{
$methodsList = array('statusesList', 'paymentTypesList', 'deliveryTypesList', 'orderMethodsList');
foreach ($methodsList as $key => $method) {
$method = get_class($this->retailcrm) . '::' . $method;
$methodsList[$key] = $method;
}
return $methodsList;
} }
public function __call($method, $arguments) public function __call($method, $arguments)
{ {
$result = '';
$response = null;
$called = sprintf('%s::%s', get_class($this->retailcrm), $method);
try { try {
WC_Retailcrm_Logger::debug(
$called,
array(empty($arguments) ? '[no params]' : print_r($arguments, true))
);
/** @var \WC_Retailcrm_Response $response */
$response = call_user_func_array(array($this->retailcrm, $method), $arguments); $response = call_user_func_array(array($this->retailcrm, $method), $arguments);
if (!empty($response) && $response->isSuccessful()) { if (is_string($response)) {
WC_Retailcrm_Logger::debug($called, array($response));
return $response;
}
if (empty($response)) {
WC_Retailcrm_Logger::add(sprintf("[%s] null (no response whatsoever)", $called));
return null;
}
if ($response->isSuccessful()) {
// Don't print long lists in debug logs (errors while calling this will be easy to detect anyway)
// Also don't call useless array_map at all while debug mode is off.
if (retailcrm_is_debug()) {
if (in_array(
$called,
$this->methodsWithoutDebugResponse()
)) {
WC_Retailcrm_Logger::debug($called, array('[request was successful, but response is omitted]'));
} else {
WC_Retailcrm_Logger::debug($called, array($response->getRawResponse()));
}
}
$result = ' Ok'; $result = ' Ok';
} else { } else {
$result = sprintf( $result = sprintf(
$method ." : Error: [HTTP-code %s] %s", $called ." : Error: [HTTP-code %s] %s",
$response->getStatusCode(), $response->getStatusCode(),
$response->getErrorMsg() $response->getErrorString()
); );
if (isset($response['errors'])) { if (isset($response['errors'])) {
foreach ($response['errors'] as $error) { $result .= self::reduceErrors($response['errors']);
$result .= " $error";
}
}
} }
$this->logger->add('retailcrm', sprintf("[%s] %s", $method, $result)); WC_Retailcrm_Logger::debug($called, array($response->getErrorString()));
WC_Retailcrm_Logger::debug($called, array($response->getRawResponse()));
}
WC_Retailcrm_Logger::add(sprintf("[%s] %s", $called, $result));
} catch (WC_Retailcrm_Exception_Curl $exception) { } catch (WC_Retailcrm_Exception_Curl $exception) {
$this->logger->add('retailcrm', sprintf("[%s] %s - %s", $method, $exception->getMessage(), $result)); WC_Retailcrm_Logger::debug(get_class($this->retailcrm).'::'.$called, array($exception->getMessage()));
WC_Retailcrm_Logger::debug('', array($exception->getTraceAsString()));
WC_Retailcrm_Logger::add(sprintf("[%s] %s - %s", $called, $exception->getMessage(), $result));
} catch (WC_Retailcrm_Exception_Json $exception) { } catch (WC_Retailcrm_Exception_Json $exception) {
$this->logger->add('retailcrm', sprintf("[%s] %s - %s", $method, $exception->getMessage(), $result)); WC_Retailcrm_Logger::debug(get_class($this->retailcrm).'::'.$called, array($exception->getMessage()));
WC_Retailcrm_Logger::debug('', array($exception->getTraceAsString()));
WC_Retailcrm_Logger::add(sprintf("[%s] %s - %s", $called, $exception->getMessage(), $result));
} catch (InvalidArgumentException $exception) { } catch (InvalidArgumentException $exception) {
$this->logger->add('retailcrm', sprintf("[%s] %s - %s", $method, $exception->getMessage(), $result)); WC_Retailcrm_Logger::debug(get_class($this->retailcrm).'::'.$called, array($exception->getMessage()));
WC_Retailcrm_Logger::debug('', array($exception->getTraceAsString()));
WC_Retailcrm_Logger::add(sprintf("[%s] %s - %s", $called, $exception->getMessage(), $result));
} }
return $response; return !empty($response) ? $response : new WC_Retailcrm_Response(900, '{}');
} }
} }
endif; endif;

View File

@ -24,6 +24,9 @@ class WC_Retailcrm_Response implements \ArrayAccess
// response assoc array // response assoc array
protected $response; protected $response;
// response raw data
protected $rawResponse;
/** /**
* ApiResponse constructor. * ApiResponse constructor.
* *
@ -35,6 +38,7 @@ class WC_Retailcrm_Response implements \ArrayAccess
public function __construct($statusCode, $responseBody = null) public function __construct($statusCode, $responseBody = null)
{ {
$this->statusCode = (int) $statusCode; $this->statusCode = (int) $statusCode;
$this->rawResponse = $responseBody;
if (!empty($responseBody)) { if (!empty($responseBody)) {
$response = json_decode($responseBody, true); $response = json_decode($responseBody, true);
@ -166,4 +170,38 @@ class WC_Retailcrm_Response implements \ArrayAccess
return $this->response[$offset]; return $this->response[$offset];
} }
/**
* Returns error string. If there's multiple errors present - they will be squashed into single string.
*
* @return string
*/
public function getErrorString()
{
if ($this->offsetExists('error')) {
return (string) $this->response['error'];
} elseif ($this->offsetExists('errors') && is_array($this->response['errors'])) {
$errorMessage = '';
foreach ($this->response['errors'] as $error) {
$errorMessage .= $error . ' >';
}
if (strlen($errorMessage) > 2) {
return (string) substr($errorMessage, 0, strlen($errorMessage) - 2);
}
return $errorMessage;
}
return '';
}
/**
* @return mixed|null
*/
public function getRawResponse()
{
return $this->rawResponse;
}
} }

View File

@ -17,17 +17,30 @@ if (!class_exists('WC_Retailcrm_Base')) {
*/ */
class WC_Retailcrm_Base extends WC_Retailcrm_Abstracts_Settings class WC_Retailcrm_Base extends WC_Retailcrm_Abstracts_Settings
{ {
/** @var string */
protected $api_url; protected $api_url;
/** @var string */
protected $api_key; protected $api_key;
/** @var \WC_Retailcrm_Proxy|WC_Retailcrm_Client_V4|WC_Retailcrm_Client_V5|bool */
protected $apiClient; protected $apiClient;
/** @var mixed */
protected $order_item; protected $order_item;
/** @var mixed */
protected $order_address; protected $order_address;
/** @var \WC_Retailcrm_Customers */
protected $customers; protected $customers;
/** @var \WC_Retailcrm_Orders */
protected $orders; protected $orders;
/** /**
* Init and hook in the integration. * Init and hook in the integration.
* @param $retailcrm (default = false) * @param \WC_Retailcrm_Proxy|WC_Retailcrm_Client_V4|WC_Retailcrm_Client_V5|bool $retailcrm (default = false)
*/ */
public function __construct($retailcrm = false) { public function __construct($retailcrm = false) {
parent::__construct(); parent::__construct();
@ -83,6 +96,8 @@ if (!class_exists('WC_Retailcrm_Base')) {
add_action('admin_print_footer_scripts', array($this, 'ajax_selected_order'), 99); add_action('admin_print_footer_scripts', array($this, 'ajax_selected_order'), 99);
add_action('woocommerce_created_customer', array($this, 'create_customer'), 10, 1); add_action('woocommerce_created_customer', array($this, 'create_customer'), 10, 1);
add_action('woocommerce_update_customer', array($this, 'update_customer'), 10, 1); add_action('woocommerce_update_customer', array($this, 'update_customer'), 10, 1);
add_action('user_register', array($this, 'create_customer'), 10, 2);
add_action('profile_update', array($this, 'update_customer'), 10, 2);
add_action('wp_print_scripts', array($this, 'initialize_analytics'), 98); add_action('wp_print_scripts', array($this, 'initialize_analytics'), 98);
add_action('wp_print_scripts', array($this, 'initialize_daemon_collector'), 99); add_action('wp_print_scripts', array($this, 'initialize_daemon_collector'), 99);
add_action('wp_print_footer_scripts', array($this, 'send_analytics'), 99); add_action('wp_print_footer_scripts', array($this, 'send_analytics'), 99);
@ -207,11 +222,33 @@ if (!class_exists('WC_Retailcrm_Base')) {
$ids = false; $ids = false;
if (isset($_GET['order_ids_retailcrm'])) { if (isset($_GET['order_ids_retailcrm'])) {
$appendix = array();
$ids = explode(',', $_GET['order_ids_retailcrm']); $ids = explode(',', $_GET['order_ids_retailcrm']);
foreach ($ids as $key => $id) {
if (stripos($id, '-') !== false) {
$idSplit = explode('-', $id);
if (count($idSplit) == 2) {
$expanded = array();
$first = (int) $idSplit[0];
$last = (int) $idSplit[1];
for ($i = $first; $i <= $last; $i++) {
$expanded[] = $i;
}
$appendix = array_merge($appendix, $expanded);
unset($ids[$key]);
}
}
}
$ids = array_unique(array_merge($ids, $appendix));
} }
if ($ids) { if ($ids) {
$this->orders->ordersUpload($ids, true); $this->orders->ordersUpload($ids);
} }
} }
@ -250,14 +287,44 @@ if (!class_exists('WC_Retailcrm_Base')) {
} }
$wcCustomer = new WC_Customer($customer_id); $wcCustomer = new WC_Customer($customer_id);
$response = $client->customersList(array('email' => $wcCustomer->get_billing_email())); $email = $wcCustomer->get_billing_email();
if ((!empty($response) && $response->isSuccessful()) && isset($response['customers']) && count($response['customers']) > 0) { if (empty($email)) {
return; $email = $wcCustomer->get_email();
} }
if (empty($email)) {
return;
} else {
$wcCustomer->set_billing_email($email);
$wcCustomer->save();
}
$response = $client->customersList(array('email' => $email));
if (!empty($response)
&& $response->isSuccessful()
&& isset($response['customers'])
&& count($response['customers']) > 0
) {
$customers = $response['customers'];
$customer = reset($customers);
if (isset($customer['id'])) {
$this->customers->updateCustomerById($customer_id, $customer['id']);
$builder = new WC_Retailcrm_WC_Customer_Builder();
$builder
->setWcCustomer($wcCustomer)
->setPhones(isset($customer['phones']) ? $customer['phones'] : array())
->setAddress(isset($customer['address']) ? $customer['address'] : false)
->build()
->getResult()
->save();
}
} else {
$this->customers->createCustomer($customer_id); $this->customers->createCustomer($customer_id);
} }
}
/** /**
* Edit customer in retailCRM * Edit customer in retailCRM
@ -269,6 +336,10 @@ if (!class_exists('WC_Retailcrm_Base')) {
return; return;
} }
if (empty($customer_id)) {
return;
}
$this->customers->updateCustomer($customer_id); $this->customers->updateCustomer($customer_id);
} }
@ -286,7 +357,10 @@ if (!class_exists('WC_Retailcrm_Base')) {
/** /**
* Edit order in retailCRM * Edit order in retailCRM
*
* @param int $order_id * @param int $order_id
*
* @throws \Exception
*/ */
public function update_order($order_id) public function update_order($order_id)
{ {
@ -359,7 +433,7 @@ if (!class_exists('WC_Retailcrm_Base')) {
return new WC_Retailcrm_Proxy( return new WC_Retailcrm_Proxy(
$this->get_option('api_url'), $this->get_option('api_url'),
$this->get_option('api_key'), $this->get_option('api_key'),
$this->get_option('api_version') $this->get_option('corporate_enabled', 'no') === 'yes'
); );
} }
@ -375,9 +449,8 @@ if (!class_exists('WC_Retailcrm_Base')) {
{ {
$api_client = $this->getApiClient(); $api_client = $this->getApiClient();
$clientId = get_option('retailcrm_client_id'); $clientId = get_option('retailcrm_client_id');
$api_version = $this->get_option('api_version');
WC_Retailcrm_Plugin::integration_module($api_client, $clientId, $api_version, false); WC_Retailcrm_Plugin::integration_module($api_client, $clientId, false);
delete_option('retailcrm_active_in_crm'); delete_option('retailcrm_active_in_crm');
} }
@ -394,14 +467,14 @@ if (!class_exists('WC_Retailcrm_Base')) {
$client_id = uniqid(); $client_id = uniqid();
} }
if ($settings['api_url'] && $settings['api_key'] && $settings['api_version']) { if ($settings['api_url'] && $settings['api_key']) {
$api_client = new WC_Retailcrm_Proxy( $api_client = new WC_Retailcrm_Proxy(
$settings['api_url'], $settings['api_url'],
$settings['api_key'], $settings['api_key'],
$settings['api_version'] $settings['corporate_enabled'] === 'yes'
); );
$result = WC_Retailcrm_Plugin::integration_module($api_client, $client_id, $settings['api_version']); $result = WC_Retailcrm_Plugin::integration_module($api_client, $client_id);
if ($result) { if ($result) {
update_option('retailcrm_active_in_crm', true); update_option('retailcrm_active_in_crm', true);

View File

@ -12,8 +12,16 @@ if (!class_exists('WC_Retailcrm_Customers')) :
/** /**
* Class WC_Retailcrm_Customers * Class WC_Retailcrm_Customers
*/ */
class WC_Retailcrm_Customers { class WC_Retailcrm_Customers
{
/**
* Administrator role
*/
const ADMIN_ROLE = 'administrator';
/**
* Every customer has this role
*/
const CUSTOMER_ROLE = 'customer'; const CUSTOMER_ROLE = 'customer';
/** @var bool | WC_Retailcrm_Proxy | \WC_Retailcrm_Client_V5 */ /** @var bool | WC_Retailcrm_Proxy | \WC_Retailcrm_Client_V5 */
@ -28,6 +36,15 @@ if (!class_exists('WC_Retailcrm_Customers')) :
/** @var array */ /** @var array */
private $customer = array(); private $customer = array();
/** @var array */
private $customerCorporate = array();
/** @var array */
private $customerCorporateCompany = array();
/** @var array */
private $customerCorporateAddress = array();
/** /**
* WC_Retailcrm_Customers constructor. * WC_Retailcrm_Customers constructor.
* *
@ -42,10 +59,41 @@ if (!class_exists('WC_Retailcrm_Customers')) :
$this->customer_address = $customer_address; $this->customer_address = $customer_address;
} }
/**
* setCustomerAddress
*
* @param $address
*
* @return $this
*/
public function setCustomerAddress($address)
{
if ($address instanceof WC_Retailcrm_Customer_Address) {
$this->customer_address = $address;
}
return $this;
}
/**
* Is corporate customers enabled in provided API
*
* @return bool
*/
public function isCorporateEnabled()
{
if (!$this->retailcrm) {
return false;
}
return $this->retailcrm->getCorporateEnabled();
}
/** /**
* Upload customers to CRM * Upload customers to CRM
* *
* @param array $ids * @param array $ids
*
* @return array mixed * @return array mixed
*/ */
public function customersUpload($ids = array()) public function customersUpload($ids = array())
@ -58,7 +106,7 @@ if (!class_exists('WC_Retailcrm_Customers')) :
$data_customers = array(); $data_customers = array();
foreach ($users as $user) { foreach ($users as $user) {
if (!\in_array(self::CUSTOMER_ROLE, $user->roles)) { if (!static::isCustomer($user)) {
continue; continue;
} }
@ -82,9 +130,12 @@ if (!class_exists('WC_Retailcrm_Customers')) :
* *
* @param int | WC_Customer $customer * @param int | WC_Customer $customer
* *
* @param \WC_Order|null $order
*
* @return mixed * @return mixed
* @throws \Exception
*/ */
public function createCustomer($customer) public function createCustomer($customer, $order = null)
{ {
if (!$this->retailcrm) { if (!$this->retailcrm) {
return null; return null;
@ -98,8 +149,8 @@ if (!class_exists('WC_Retailcrm_Customers')) :
return null; return null;
} }
if ($customer->get_role() == self::CUSTOMER_ROLE) { if (self::isCustomer($customer)) {
$this->processCustomer($customer); $this->processCustomer($customer, $order);
$response = $this->retailcrm->customersCreate($this->customer); $response = $this->retailcrm->customersCreate($this->customer);
if ((!empty($response) && $response->isSuccessful()) && isset($response['id'])) { if ((!empty($response) && $response->isSuccessful()) && isset($response['id'])) {
@ -111,11 +162,12 @@ if (!class_exists('WC_Retailcrm_Customers')) :
} }
/** /**
* Edit customer in CRM * Update customer in CRM
* *
* @param int $customer_id * @param $customer_id
* *
* @return WC_Customer $customer * @return void|\WC_Customer
* @throws \Exception
*/ */
public function updateCustomer($customer_id) public function updateCustomer($customer_id)
{ {
@ -125,7 +177,7 @@ if (!class_exists('WC_Retailcrm_Customers')) :
$customer = $this->wcCustomerGet($customer_id); $customer = $this->wcCustomerGet($customer_id);
if ($customer->get_role() == self::CUSTOMER_ROLE){ if (self::isCustomer($customer)) {
$this->processCustomer($customer); $this->processCustomer($customer);
$this->retailcrm->customersEdit($this->customer); $this->retailcrm->customersEdit($this->customer);
} }
@ -133,36 +185,288 @@ if (!class_exists('WC_Retailcrm_Customers')) :
return $customer; return $customer;
} }
/**
* Update customer in CRM by ID
*
* @param int $customer_id
* @param int|string $crmCustomerId
*
* @return void|\WC_Customer
* @throws \Exception
*/
public function updateCustomerById($customer_id, $crmCustomerId)
{
if (!$this->retailcrm) {
return;
}
$customer = $this->wcCustomerGet($customer_id);
if (self::isCustomer($customer)) {
$this->processCustomer($customer);
$this->customer['id'] = $crmCustomerId;
$this->retailcrm->customersEdit($this->customer, 'id');
}
return $customer;
}
/**
* Create corporate customer in CRM
*
* @param int $crmCustomerId
* @param int | WC_Customer $customer
* @param \WC_Order $order
*
* @return mixed
* @throws \Exception
*/
public function createCorporateCustomerForOrder($crmCustomerId, $customer, $order)
{
if (!$this->retailcrm) {
return null;
}
if (is_int($customer)) {
$customer = $this->wcCustomerGet($customer);
}
if (!$customer instanceof WC_Customer) {
return null;
}
if (self::isCustomer($customer)) {
$this->processCorporateCustomer($crmCustomerId, $customer, $order);
$response = $this->retailcrm->customersCorporateCreate($this->customerCorporate);
return $this->fillCorporateCustomer($response);
}
return null;
}
/**
* Create new address in corporate customer (if needed)
*
* @param int $corporateId
* @param \WC_Customer $customer
* @param \WC_Order|null $order
*/
public function fillCorporateAddress($corporateId, $customer, $order = null)
{
$found = false;
$builder = new WC_Retailcrm_Customer_Corporate_Address();
$newAddress = $builder
->setFallbackToShipping(true)
->setIsMain(false)
->setExplicitIsMain(false)
->setWCAddressType(WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_BILLING)
->build($customer, $order)
->get_data();
$addresses = $this->retailcrm->customersCorporateAddresses(
$corporateId,
array(),
null,
100,
'id'
);
if ($addresses && $addresses->isSuccessful() && $addresses->offsetExists('addresses')) {
foreach ($addresses['addresses'] as $address) {
foreach ($newAddress as $field => $value) {
if (isset($address[$field]) && $address[$field] != $value) {
continue 2;
}
}
$found = true;
break;
}
} else {
$found = true;
}
if (!$found) {
$this->retailcrm->customersCorporateAddressesCreate(
$corporateId,
$newAddress,
'id',
$this->retailcrm->getSingleSiteForKey()
);
}
}
/**
* Fills corporate customer with required data after customer was created or updated.
* Create or update response after sending customer must be passed.
*
* @param \WC_Retailcrm_Response $response
*
* @return string|int|null
*/
protected function fillCorporateCustomer($response)
{
if (!$response->isSuccessful() || $response->isSuccessful() && !$response->offsetExists('id')) {
return null;
}
$customerId = $response['id'];
$response = $this->retailcrm->customersCorporateAddressesCreate(
$customerId,
$this->customerCorporateAddress,
'id',
$this->retailcrm->getSingleSiteForKey()
);
if ($response->isSuccessful() && $response->offsetExists('id')) {
$this->customerCorporateCompany['address'] = array(
'id' => $response['id'],
);
$this->retailcrm->customersCorporateCompaniesCreate(
$customerId,
$this->customerCorporateCompany,
'id',
$this->retailcrm->getSingleSiteForKey()
);
}
return $customerId;
}
/** /**
* Process customer * Process customer
* *
* @param WC_Customer $customer * @param WC_Customer $customer
* @param WC_Order|null $order
* *
* @return void * @return void
* @throws \Exception
*/ */
protected function processCustomer($customer) protected function processCustomer($customer, $order = null)
{ {
$createdAt = $customer->get_date_created(); $createdAt = $customer->get_date_created();
$firstName = $customer->get_first_name(); $firstName = $customer->get_first_name();
$lastName = $customer->get_last_name();
$billingPhone = $customer->get_billing_phone();
$email = $customer->get_billing_email();
if (empty($firstName) && empty($lastName) && $order instanceof WC_Order) {
$firstName = $order->get_billing_first_name();
$lastName = $order->get_billing_last_name();
if (empty($firstName) && empty($lastName)) {
$firstName = $order->get_shipping_first_name();
$lastName = $order->get_shipping_last_name();
}
if (empty($firstName)) {
$firstName = $customer->get_username();
}
if (empty($email)) {
$email = $order->get_billing_email();
}
if (empty($billingPhone)) {
$order->get_billing_phone();
}
}
if (empty($createdAt)) {
$createdAt = new WC_DateTime();
}
$data_customer = array( $data_customer = array(
'createdAt' => $createdAt->date('Y-m-d H:i:s'), 'createdAt' => $createdAt->date('Y-m-d H:i:s'),
'firstName' => $firstName ? $firstName : $customer->get_username(), 'firstName' => $firstName ? $firstName : $customer->get_username(),
'lastName' => $customer->get_last_name(), 'lastName' => $lastName,
'email' => $customer->get_billing_email(), 'email' => $customer->get_billing_email(),
'address' => $this->customer_address->build($customer)->get_data() 'address' => $this->customer_address->build($customer, $order)->get_data()
); );
if ($customer->get_id() > 0) { if ($customer->get_id() > 0) {
$data_customer['externalId'] = $customer->get_id(); $data_customer['externalId'] = $customer->get_id();
} }
if ($customer->get_billing_phone()) { if (!empty($billingPhone)) {
$data_customer['phones'][] = array( $data_customer['phones'][] = array(
'number' => $customer->get_billing_phone() 'number' => $customer->get_billing_phone()
); );
} }
$this->customer = apply_filters('retailcrm_process_customer', $data_customer, $customer); $this->customer = apply_filters(
'retailcrm_process_customer',
WC_Retailcrm_Plugin::clearArray($data_customer),
$customer
);
}
/**
* Process corporate customer
*
* @param int $crmCustomerId
* @param WC_Customer $customer
* @param \WC_Order $order
*
* @return void
*/
protected function processCorporateCustomer($crmCustomerId, $customer, $order)
{
$data_company = array(
'isMain' => true,
'name' => $order->get_billing_company()
);
$data_customer = array(
'nickName' => $order->get_billing_company(),
'customerContacts' => array(
array(
'isMain' => true,
'customer' => array(
'id' => $crmCustomerId
)
)
)
);
$orderAddress = new WC_Retailcrm_Order_Address();
$corpAddress = new WC_Retailcrm_Customer_Corporate_Address();
$address = $orderAddress
->setWCAddressType(WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_BILLING)
->build($order)
->get_data();
$shippingAddress = $corpAddress
->setWCAddressType(WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_BILLING)
->setFallbackToBilling(true)
->setIsMain(true)
->build($customer, $order)
->get_data();
if (isset($address['text'])) {
$data_company['contragent']['legalAddress'] = $address['text'];
}
$this->customerCorporate = apply_filters(
'retailcrm_process_customer_corporate',
WC_Retailcrm_Plugin::clearArray($data_customer),
$customer
);
$this->customerCorporateAddress = apply_filters(
'retailcrm_process_customer_corporate_address',
WC_Retailcrm_Plugin::clearArray(array_merge(
$shippingAddress,
array('isMain' => true)
)),
$customer
);
$this->customerCorporateCompany = apply_filters(
'retailcrm_process_customer_corporate_company',
WC_Retailcrm_Plugin::clearArray($data_company),
$customer
);
} }
/** /**
@ -170,7 +474,7 @@ if (!class_exists('WC_Retailcrm_Customers')) :
* *
* @return bool|array * @return bool|array
*/ */
public function searchCustomer($filter) private function searchCustomer($filter)
{ {
if (isset($filter['externalId'])) { if (isset($filter['externalId'])) {
$search = $this->retailcrm->customersGet($filter['externalId']); $search = $this->retailcrm->customersGet($filter['externalId']);
@ -183,15 +487,82 @@ if (!class_exists('WC_Retailcrm_Customers')) :
} }
if (!empty($search) && $search->isSuccessful()) { if (!empty($search) && $search->isSuccessful()) {
$customer = false;
if (isset($search['customers'])) { if (isset($search['customers'])) {
if (empty($search['customers'])) { if (empty($search['customers'])) {
return false; return false;
} }
$arrayCustumers = $search['customers']; if (isset($filter['email']) && count($filter) == 1) {
$customer = reset($arrayCustumers); foreach ($search['customers'] as $finding) {
if (isset($finding['email']) && $finding['email'] == $filter['email']) {
$customer = $finding;
}
}
} else { } else {
$customer = $search['customer']; $dataCustomers = $search['customers'];
$customer = reset($dataCustomers);
}
} else {
$customer = !empty($search['customer']) ? $search['customer'] : false;
}
return $customer;
}
return false;
}
/**
* Returns customer data by externalId or by email, returns false in case of failure
*
* @param $customerExternalId
* @param $customerEmailOrPhone
*
* @return array|bool
*/
public function findCustomerEmailOrId($customerExternalId, $customerEmailOrPhone)
{
$customer = false;
if (!empty($customerExternalId)) {
$customer = $this->searchCustomer(array('externalId' => $customerExternalId));
}
if (!$customer && !empty($customerEmailOrPhone)) {
$customer = $this->searchCustomer(array('email' => $customerEmailOrPhone));
}
return $customer;
}
/**
* Search by provided filter, returns first found customer
*
* @param array $filter
* @param bool $returnGroup Return all customers for group filter instead of first
*
* @return bool|array
*/
public function searchCorporateCustomer($filter, $returnGroup = false)
{
$search = $this->retailcrm->customersCorporateList($filter);
if (!empty($search) && $search->isSuccessful()) {
if (isset($search['customersCorporate'])) {
if (empty($search['customersCorporate'])) {
return false;
}
if ($returnGroup) {
return $search['customersCorporate'];
} else {
$dataCorporateCustomers = $search['customersCorporate'];
$customer = reset($dataCorporateCustomers);
}
} else {
$customer = false;
} }
return $customer; return $customer;
@ -208,7 +579,7 @@ if (!class_exists('WC_Retailcrm_Customers')) :
*/ */
public function buildCustomerFromOrderData($order) public function buildCustomerFromOrderData($order)
{ {
$new_customer = new WC_Customer; $new_customer = new WC_Customer();
foreach ($order->get_address('billing') as $prop => $value) { foreach ($order->get_address('billing') as $prop => $value) {
$new_customer->{'set_billing_' . $prop}($value); $new_customer->{'set_billing_' . $prop}($value);
@ -226,6 +597,7 @@ if (!class_exists('WC_Retailcrm_Customers')) :
* @param int $customer_id * @param int $customer_id
* *
* @return WC_Customer * @return WC_Customer
* @throws \Exception
*/ */
public function wcCustomerGet($customer_id) public function wcCustomerGet($customer_id)
{ {
@ -239,5 +611,24 @@ if (!class_exists('WC_Retailcrm_Customers')) :
{ {
return $this->customer; return $this->customer;
} }
/**
* Returns true if provided WP_User or WC_Customer should be uploaded to CRM
*
* @param \WC_Customer|\WP_User $user
*
* @return bool
*/
public static function isCustomer($user)
{
if ($user instanceof WC_Customer) {
return $user->get_role() == self::CUSTOMER_ROLE || $user->get_role() == self::ADMIN_ROLE;
} elseif ($user instanceof WP_User) {
return in_array(self::CUSTOMER_ROLE, $user->roles)
|| in_array(self::ADMIN_ROLE, $user->roles);
}
return false;
}
} }
endif; endif;

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
*/ */
class WC_Retailcrm_Orders class WC_Retailcrm_Orders
{ {
/** @var bool|WC_Retailcrm_Proxy */ /** @var bool|WC_Retailcrm_Proxy|\WC_Retailcrm_Client_V5|\WC_Retailcrm_Client_V4 */
protected $retailcrm; protected $retailcrm;
/** @var array */ /** @var array */
@ -35,6 +35,9 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
/** @var WC_Retailcrm_Order */ /** @var WC_Retailcrm_Order */
protected $orders; protected $orders;
/** @var array */
private $ordersGetRequestCache = array();
/** @var array */ /** @var array */
private $order = array(); private $order = array();
@ -62,16 +65,23 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
/** /**
* Upload orders to CRM * Upload orders to CRM
* *
* @param bool $withCustomers
* @param array $include * @param array $include
*
* @return array $uploadOrders | null * @return array $uploadOrders | null
* @throws \Exception
*/ */
public function ordersUpload($include = array(), $withCustomers = false) public function ordersUpload($include = array())
{ {
if (!$this->retailcrm) { if (!$this->retailcrm) {
return null; return null;
} }
$uploader = new WC_Retailcrm_Customers(
$this->retailcrm,
$this->retailcrm_settings,
new WC_Retailcrm_Customer_Address()
);
$orders = get_posts(array( $orders = get_posts(array(
'numberposts' => -1, 'numberposts' => -1,
'post_type' => wc_get_order_types('view-orders'), 'post_type' => wc_get_order_types('view-orders'),
@ -79,46 +89,36 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
'include' => $include 'include' => $include
)); ));
$orders_data = array(); $regularUploadErrors = array();
$corporateUploadErrors = array();
foreach ($orders as $data_order) { foreach ($orders as $data_order) {
$order = wc_get_order($data_order->ID); $order = wc_get_order($data_order->ID);
$this->processOrder($order);
$customer = $order->get_user();
$customers = array();
if ($customer != false) { $errorMessage = $this->orderCreate($data_order->ID);
$this->order['customer']['externalId'] = $customer->get('ID');
if ($withCustomers === true) { if (is_string($errorMessage)) {
$customers[] = $customer->get('ID'); if ($this->retailcrm->getCorporateEnabled() && self::isCorporateOrder($order)) {
$corporateUploadErrors[$data_order->ID] = $errorMessage;
} else {
$regularUploadErrors[$data_order->ID] = $errorMessage;
}
} }
} }
$orders_data[] = $this->order; static::logOrdersUploadErrors($regularUploadErrors, 'Error while uploading these regular orders');
} static::logOrdersUploadErrors($corporateUploadErrors, 'Error while uploading these corporate orders');
if ($withCustomers === true && !empty($customers)) { return array();
$this->customers->customersUpload($customers);
}
$uploadOrders = array_chunk($orders_data, 50);
foreach ($uploadOrders as $uploadOrder) {
$this->retailcrm->ordersUpload($uploadOrder);
time_nanosleep(0, 250000000);
}
return $uploadOrders;
} }
/** /**
* Create order * Create order. Returns wc_get_order data or error string.
* *
* @param $order_id * @param $order_id
* *
* @return mixed * @return bool|WC_Order|WC_Order_Refund|string
* @throws Exception * @throws \Exception
*/ */
public function orderCreate($order_id) public function orderCreate($order_id)
{ {
@ -126,67 +126,164 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
return null; return null;
} }
$this->order_payment->reset_data();
$wcOrder = wc_get_order($order_id); $wcOrder = wc_get_order($order_id);
$this->processOrder($wcOrder); $this->processOrder($wcOrder);
$wpUser = $wcOrder->get_user();
if ($wpUser instanceof WP_User) { try {
$wpUserId = (int)$wpUser->get('ID'); $response = $this->retailcrm->ordersCreate($this->order);
$foundCustomer = $this->customers->searchCustomer(array(
'externalId' => $wpUserId
));
if (empty($foundCustomer)) { if ($response instanceof WC_Retailcrm_Response) {
$foundCustomer = $this->customers->searchCustomer(array( if ($response->isSuccessful()) {
'email' => $wcOrder->get_billing_email() return $wcOrder;
));
} }
if (empty($foundCustomer)) { return $response->getErrorString();
$customerId = $this->customers->createCustomer($wpUserId);
if (!empty($customerId)) {
$this->order['customer']['id'] = $customerId;
} }
} else { } catch (InvalidArgumentException $exception) {
if (!empty($foundCustomer['externalId'])) { return $exception->getMessage();
$this->order['customer']['externalId'] = $foundCustomer['externalId'];
} else {
$this->order['customer']['id'] = $foundCustomer['id'];
} }
}
} else {
$foundCustomer = $this->customers->searchCustomer(array(
'email' => $wcOrder->get_billing_email()
));
if (empty($foundCustomer)) {
$wcCustomer = $this->customers->buildCustomerFromOrderData($wcOrder);
$customerId = $this->customers->createCustomer($wcCustomer);
if (!empty($customerId)) {
$this->order['customer']['id'] = $customerId;
}
} else {
if (!empty($foundCustomer['externalId'])) {
$this->order['customer']['externalId'] = $foundCustomer['externalId'];
} else {
$this->order['customer']['id'] = $foundCustomer['id'];
}
}
}
$this->retailcrm->ordersCreate($this->order);
return $wcOrder; return $wcOrder;
} }
/**
* Process order customer data
*
* @param \WC_Order $wcOrder
* @param bool $update
*
* @return bool Returns false if order cannot be processed
* @throws \Exception
*/
protected function processOrderCustomerInfo($wcOrder, $update = false)
{
$customerWasChanged = false;
$wpUser = $wcOrder->get_user();
if ($update) {
$response = $this->getCrmOrder($wcOrder->get_id());
if (!empty($response)) {
$customerWasChanged = self::isOrderCustomerWasChanged($wcOrder, $response);
}
}
if ($wpUser instanceof WP_User) {
if (!WC_Retailcrm_Customers::isCustomer($wpUser)) {
return false;
}
$wpUserId = (int) $wpUser->get('ID');
if (!$update || ($update && $customerWasChanged)) {
$this->fillOrderCreate($wpUserId, $wpUser->get('billing_email'), $wcOrder);
}
} else {
$wcCustomer = $this->customers->buildCustomerFromOrderData($wcOrder);
if (!$update || ($update && $customerWasChanged)) {
$this->fillOrderCreate(0, $wcCustomer->get_billing_email(), $wcOrder);
}
}
if ($update && $customerWasChanged) {
$this->order['firstName'] = $wcOrder->get_shipping_first_name();
$this->order['lastName'] = $wcOrder->get_shipping_last_name();
}
return true;
}
/**
* Fill order on create
*
* @param int $wcCustomerId
* @param string $wcCustomerEmail
* @param \WC_Order $wcOrder
*
* @throws \Exception
*/
protected function fillOrderCreate($wcCustomerId, $wcCustomerEmail, $wcOrder)
{
$foundCustomerId = '';
$foundCustomer = $this->customers->findCustomerEmailOrId($wcCustomerId, $wcCustomerEmail);
if (empty($foundCustomer)) {
$foundCustomerId = $this->customers->createCustomer($wcCustomerId, $wcOrder);
if (!empty($foundCustomerId)) {
$this->order['customer']['id'] = $foundCustomerId;
}
} else {
$this->order['customer']['id'] = $foundCustomer['id'];
$foundCustomerId = $foundCustomer['id'];
}
$this->order['contragent']['contragentType'] = 'individual';
if ($this->retailcrm->getCorporateEnabled() && static::isCorporateOrder($wcOrder)) {
unset($this->order['contragent']['contragentType']);
$crmCorporate = $this->customers->searchCorporateCustomer(array(
'contactIds' => array($foundCustomerId),
'companyName' => $wcOrder->get_billing_company()
));
if (empty($crmCorporate)) {
$crmCorporate = $this->customers->searchCorporateCustomer(array(
'companyName' => $wcOrder->get_billing_company()
));
}
if (empty($crmCorporate)) {
$corporateId = $this->customers->createCorporateCustomerForOrder(
$foundCustomerId,
$wcCustomerId,
$wcOrder
);
$this->order['customer']['id'] = $corporateId;
} else {
$this->customers->fillCorporateAddress(
$crmCorporate['id'],
new WC_Customer($wcCustomerId),
$wcOrder
);
$this->order['customer']['id'] = $crmCorporate['id'];
}
$companiesResponse = $this->retailcrm->customersCorporateCompanies(
$this->order['customer']['id'],
array(),
null,
null,
'id'
);
if (!empty($companiesResponse) && $companiesResponse->isSuccessful()) {
foreach ($companiesResponse['companies'] as $company) {
if ($company['name'] == $wcOrder->get_billing_company()) {
$this->order['company'] = array(
'id' => $company['id'],
'name' => $company['name']
);
break;
}
}
}
$this->order['contact']['id'] = $foundCustomerId;
}
}
/** /**
* Edit order in CRM * Edit order in CRM
* *
* @param int $order_id * @param int $order_id
* *
* @return WC_Order $order | null * @return WC_Order $order | null
* @throws \Exception
*/ */
public function updateOrder($order_id) public function updateOrder($order_id)
{ {
@ -194,20 +291,16 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
return null; return null;
} }
$order = wc_get_order($order_id); $wcOrder = wc_get_order($order_id);
$this->processOrder($order, true); $this->processOrder($wcOrder, true);
if ($this->retailcrm_settings['api_version'] == 'v4') {
$this->order['paymentType'] = $this->retailcrm_settings[$order->get_payment_method()];
}
$response = $this->retailcrm->ordersEdit($this->order); $response = $this->retailcrm->ordersEdit($this->order);
if ((!empty($response) && $response->isSuccessful()) && $this->retailcrm_settings['api_version'] == 'v5') { if (!empty($response) && $response->isSuccessful()) {
$this->payment = $this->orderUpdatePaymentType($order); $this->payment = $this->orderUpdatePaymentType($wcOrder);
} }
return $order; return $wcOrder;
} }
/** /**
@ -223,11 +316,9 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
return null; return null;
} }
$response = $this->retailcrm->ordersGet($order->get_id()); $retailcrmOrder = $this->getCrmOrder($order->get_id());
if (!empty($response) && $response->isSuccessful()) {
$retailcrmOrder = $response['order'];
if (!empty($retailcrmOrder)) {
foreach ($retailcrmOrder['payments'] as $payment_data) { foreach ($retailcrmOrder['payments'] as $payment_data) {
$payment_external_id = explode('-', $payment_data['externalId']); $payment_external_id = explode('-', $payment_data['externalId']);
@ -263,6 +354,7 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
* @param boolean $update * @param boolean $update
* *
* @return void * @return void
* @throws \Exception
*/ */
protected function processOrder($order, $update = false) protected function processOrder($order, $update = false)
{ {
@ -313,8 +405,12 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
} }
} }
$order_data['delivery']['address'] = $this->order_address->build($order)->get_data();
$order_items = array(); $order_items = array();
$order_data['delivery']['address'] = $this->order_address
->setFallbackToBilling(true)
->setWCAddressType(WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_SHIPPING)
->build($order)
->get_data();
/** @var WC_Order_Item_Product $item */ /** @var WC_Order_Item_Product $item */
foreach ($order->get_items() as $item) { foreach ($order->get_items() as $item) {
@ -324,12 +420,19 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
$order_data['items'] = $order_items; $order_data['items'] = $order_items;
if ($this->retailcrm_settings['api_version'] == 'v5' && !$update) { if (!$update) {
$this->order_payment->is_new = true; $this->order_payment->is_new = true;
$order_data['payments'][] = $this->order_payment->build($order)->get_data(); $order_data['payments'][] = $this->order_payment->build($order)->get_data();
} }
$this->order = apply_filters('retailcrm_process_order', $order_data, $order); $this->order = WC_Retailcrm_Plugin::clearArray($order_data);
$this->processOrderCustomerInfo($order, $update);
$this->order = apply_filters(
'retailcrm_process_order',
WC_Retailcrm_Plugin::clearArray($this->order),
$order
);
} }
/** /**
@ -355,6 +458,31 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
return $payment; return $payment;
} }
/**
* ordersGet wrapper with cache (in order to minimize request count).
*
* @param int|string $orderId
* @param bool $cached
*
* @return array
*/
protected function getCrmOrder($orderId, $cached = true)
{
if ($cached && isset($this->ordersGetRequestCache[$orderId])) {
return (array) $this->ordersGetRequestCache[$orderId];
}
$crmOrder = array();
$response = $this->retailcrm->ordersGet($orderId);
if (!empty($response) && $response->isSuccessful() && isset($response['order'])) {
$crmOrder = (array) $response['order'];
$this->ordersGetRequestCache[$orderId] = $crmOrder;
}
return $crmOrder;
}
/** /**
* @return array * @return array
*/ */
@ -370,5 +498,106 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
{ {
return $this->payment; return $this->payment;
} }
/**
* Returns true if provided order is for corporate customer
*
* @param WC_Order $order
*
* @return bool
*/
public static function isCorporateOrder($order)
{
$billingCompany = $order->get_billing_company();
return !empty($billingCompany);
}
/**
* Returns true if passed crm order is corporate
*
* @param array|\ArrayAccess $order
*
* @return bool
*/
public static function isCorporateCrmOrder($order)
{
return (is_array($order) || $order instanceof ArrayAccess)
&& isset($order['customer'])
&& isset($order['customer']['type'])
&& $order['customer']['type'] == 'customer_corporate';
}
/**
* Returns true if customer in order was changed. `true` will be returned if one of these four conditions is met:
*
* 1. If CMS order is corporate and retailCRM order is not corporate or vice versa, then customer obviously
* needs to be updated in retailCRM.
* 2. If billing company from CMS order is not the same as the one in the retailCRM order,
* then company needs to be updated.
* 3. If contact person or individual externalId is different from customer ID in the CMS order, then
* contact person or customer in retailCRM should be updated (even if customer id in the order is not set).
* 4. If contact person or individual email is not the same as the CMS order billing email, then
* contact person or customer in retailCRM should be updated.
*
* @param \WC_Order $wcOrder
* @param array|\ArrayAccess $crmOrder
*
* @return bool
*/
public static function isOrderCustomerWasChanged($wcOrder, $crmOrder)
{
if (!isset($crmOrder['customer'])) {
return false;
}
$customerWasChanged = self::isCorporateOrder($wcOrder) != self::isCorporateCrmOrder($crmOrder);
$synchronizableUserData = self::isCorporateCrmOrder($crmOrder)
? $crmOrder['contact'] : $crmOrder['customer'];
if (!$customerWasChanged) {
if (self::isCorporateCrmOrder($crmOrder)) {
$currentCrmCompany = isset($crmOrder['company']) ? $crmOrder['company']['name'] : '';
if (!empty($currentCrmCompany) && $currentCrmCompany != $wcOrder->get_billing_company()) {
$customerWasChanged = true;
}
}
if (isset($synchronizableUserData['externalId'])
&& $synchronizableUserData['externalId'] != $wcOrder->get_customer_id()
) {
$customerWasChanged = true;
} elseif (isset($synchronizableUserData['email'])
&& $synchronizableUserData['email'] != $wcOrder->get_billing_email()
) {
$customerWasChanged = true;
}
}
return $customerWasChanged;
}
/**
* Logs orders upload errors with prefix log message.
* Array keys must be orders ID's in WooCommerce, values must be strings (error messages).
*
* @param array $errors
* @param string $prefix
*/
public static function logOrdersUploadErrors($errors, $prefix = 'Errors while uploading these orders')
{
if (empty($errors)) {
return;
}
WC_Retailcrm_Logger::add($prefix);
foreach ($errors as $orderId => $error) {
WC_Retailcrm_Logger::add(sprintf("[%d] => %s", $orderId, $error));
}
WC_Retailcrm_Logger::add('==================================');
}
} }
endif; endif;

View File

@ -53,6 +53,12 @@ class WC_Retailcrm_Plugin {
} }
public function activate() { public function activate() {
if (!class_exists( 'WC_Integration' ) ) {
add_action('admin_notices', array(new WC_Integration_Retailcrm(), 'woocommerce_missing_notice'));
return;
}
if (!class_exists('WC_Retailcrm_Icml')) { if (!class_exists('WC_Retailcrm_Icml')) {
require_once (dirname(__FILE__) . '/class-wc-retailcrm-icml.php'); require_once (dirname(__FILE__) . '/class-wc-retailcrm-icml.php');
} }
@ -84,13 +90,13 @@ class WC_Retailcrm_Plugin {
/** /**
* Edit configuration in CRM * Edit configuration in CRM
* *
* @param WC_Retailcrm_Proxy $api_client * @param WC_Retailcrm_Proxy|\WC_Retailcrm_Client_V4|\WC_Retailcrm_Client_V5 $api_client
* @param string $client_id * @param string $client_id
* @param bool $active * @param bool $active
* *
* @return boolean * @return boolean
*/ */
public static function integration_module($api_client, $client_id, $api_version, $active = true) { public static function integration_module($api_client, $client_id, $active = true) {
if (!$api_client) { if (!$api_client) {
return false; return false;
@ -103,18 +109,12 @@ class WC_Retailcrm_Plugin {
'active' => $active, 'active' => $active,
); );
if ($api_version == 'v4') {
$configuration['configurationUrl'] = get_site_url();
$response = $api_client->marketplaceSettingsEdit($configuration);
} else {
$configuration['integrationCode'] = self::INTEGRATION_CODE; $configuration['integrationCode'] = self::INTEGRATION_CODE;
$configuration['baseUrl'] = get_site_url(); $configuration['baseUrl'] = get_site_url();
$configuration['clientId'] = $client_id; $configuration['clientId'] = $client_id;
$configuration['accountUrl'] = get_site_url(); $configuration['accountUrl'] = get_site_url();
$response = $api_client->integrationModulesEdit($configuration); $response = $api_client->integrationModulesEdit($configuration);
}
if (!$response) { if (!$response) {
return false; return false;
@ -127,6 +127,53 @@ class WC_Retailcrm_Plugin {
return false; return false;
} }
/**
* Unset empty fields
*
* @param array $arr input array
*
* @return array
*/
public static function clearArray(array $arr)
{
if (!is_array($arr)) {
return $arr;
}
$result = array();
foreach ($arr as $index => $node) {
$result[$index] = (is_array($node))
? self::clearArray($node)
: $node;
if ($result[$index] === ''
|| $result[$index] === null
|| (is_array($result[$index]) && count($result[$index]) < 1)
) {
unset($result[$index]);
}
}
return $result;
}
/**
* Returns WC_Customer by id. Returns null if there's no such customer.
*
* @param int $id
*
* @return \WC_Customer|null
*/
public static function getWcCustomerById($id)
{
try {
return new WC_Customer($id);
} catch (\Exception $exception) {
return null;
}
}
/** /**
* Check running history * Check running history
* *
@ -137,4 +184,3 @@ class WC_Retailcrm_Plugin {
return self::$history_run; return self::$history_run;
} }
} }

View File

@ -0,0 +1,318 @@
<?php
/**
* Class WC_Retailcrm_Customer_Switcher
* This component provides builder-like interface in order to make it easier to change customer & customer data
* in the order via retailCRM history.
*/
class WC_Retailcrm_Customer_Switcher implements WC_Retailcrm_Builder_Interface
{
/**
* @var \WC_Retailcrm_Customer_Switcher_State $data
*/
private $data;
/**
* @var \WC_Retailcrm_Customer_Switcher_Result|null $result
*/
private $result;
/**
* WC_Retailcrm_Customer_Data_Replacer constructor.
*/
public function __construct()
{
$this->reset();
}
/**
* In fact, this will execute customer change in provided order.
* This will not produce any new entities.
*
* @return $this|\WC_Retailcrm_Builder_Interface
* @throws \WC_Data_Exception
*/
public function build()
{
$this->data->validate();
WC_Retailcrm_Logger::debug(__METHOD__, array('state', $this->data));
$newCustomer = $this->data->getNewCustomer();
$newContact = $this->data->getNewContact();
$newCompany = $this->data->getNewCompanyName();
$companyAddress = $this->data->getCompanyAddress();
if (!empty($newCustomer)) {
WC_Retailcrm_Logger::debug(
__METHOD__,
array(
'Changing to individual customer for order',
$this->data->getWcOrder()->get_id()
)
);
$this->processChangeToRegular($this->data->getWcOrder(), $newCustomer, false);
$this->data->getWcOrder()->set_billing_company('');
} else {
if (!empty($newContact)) {
WC_Retailcrm_Logger::debug(
__METHOD__,
array(
'Changing to contact person customer for order',
$this->data->getWcOrder()->get_id()
)
);
$this->processChangeToRegular($this->data->getWcOrder(), $newContact, true);
}
if (!empty($newCompany)) {
WC_Retailcrm_Logger::debug(
__METHOD__,
array(sprintf(
'Replacing old order id=`%d` company `%s` with new company `%s`',
$this->data->getWcOrder()->get_id(),
$this->data->getWcOrder()->get_billing_company(),
$newCompany
))
);
$this->processCompanyChange();
}
if (!empty($companyAddress)) {
$this->processCompanyAddress();
}
}
return $this;
}
/**
* Change order customer to regular one
*
* @param \WC_Order $wcOrder
* @param array $newCustomer
* @param bool $isContact
*
* @throws \WC_Data_Exception
*/
public function processChangeToRegular($wcOrder, $newCustomer, $isContact)
{
$wcCustomer = null;
WC_Retailcrm_Logger::debug(
__METHOD__,
array(
'Switching in order',
$wcOrder->get_id(),
'to',
$newCustomer
)
);
if (isset($newCustomer['externalId'])) {
$wcCustomer = WC_Retailcrm_Plugin::getWcCustomerById($newCustomer['externalId']);
if (!empty($wcCustomer)) {
$wcOrder->set_customer_id($wcCustomer->get_id());
WC_Retailcrm_Logger::debug(
__METHOD__,
array(
'Set customer to',
$wcCustomer->get_id(),
'in order',
$wcOrder->get_id()
)
);
}
} else {
$wcOrder->set_customer_id(0);
WC_Retailcrm_Logger::debug(
__METHOD__,
array(
'Set customer to 0 (guest) in order',
$wcOrder->get_id()
)
);
}
$fields = array(
'billing_first_name' => self::arrayValue($newCustomer, 'firstName'),
'billing_last_name' => self::arrayValue($newCustomer, 'lastName'),
'billing_email' => self::arrayValue($newCustomer, 'email')
);
foreach ($fields as $field => $value) {
$wcOrder->{'set_' . $field}($value);
}
$address = self::arrayValue($newCustomer, 'address', array());
if ($isContact) {
self::setShippingAddressToOrder($wcOrder, $address);
} else {
self::setBillingAddressToOrder($wcOrder, $address);
self::setShippingAddressToOrder($wcOrder, $address);
}
$wcOrder->set_billing_phone(self::singleCustomerPhone($newCustomer));
$this->result = new WC_Retailcrm_Customer_Switcher_Result($wcCustomer, $wcOrder);
}
/**
* Process company address.
*
* @throws \WC_Data_Exception
*/
protected function processCompanyAddress()
{
$wcOrder = $this->data->getWcOrder();
$companyAddress = $this->data->getCompanyAddress();
if (!empty($companyAddress)) {
self::setBillingAddressToOrder($wcOrder, $companyAddress);
}
if (empty($this->result)) {
$this->result = new WC_Retailcrm_Customer_Switcher_Result(null, $wcOrder);
}
}
/**
* This will update company field in order and create result if it's not set (happens when only company was changed).
*
* @throws \WC_Data_Exception
*/
public function processCompanyChange()
{
$this->data->getWcOrder()->set_billing_company($this->data->getNewCompanyName());
if (empty($this->result)) {
$this->result = new WC_Retailcrm_Customer_Switcher_Result(null, $this->data->getWcOrder());
}
}
/**
* @return $this|\WC_Retailcrm_Builder_Interface
*/
public function reset()
{
$this->data = new WC_Retailcrm_Customer_Switcher_State();
$this->result = null;
return $this;
}
/**
* Set initial state into component
*
* @param \WC_Retailcrm_Customer_Switcher_State $data
*
* @return $this|\WC_Retailcrm_Builder_Interface
*/
public function setData($data)
{
if (!($data instanceof WC_Retailcrm_Customer_Switcher_State)) {
throw new \InvalidArgumentException('Invalid data type');
}
$this->data = $data;
return $this;
}
/**
* @return \WC_Retailcrm_Customer_Switcher_Result|null
*/
public function getResult()
{
return $this->result;
}
/**
* @return \WC_Retailcrm_Customer_Switcher_State
*/
public function getData()
{
return $this->data;
}
/**
* Sets billing address properties in order
*
* @param \WC_Order $wcOrder
* @param array $address
*
* @throws \WC_Data_Exception
*/
private static function setBillingAddressToOrder($wcOrder, $address)
{
$wcOrder->set_billing_state(self::arrayValue($address, 'region', '--'));
$wcOrder->set_billing_postcode(self::arrayValue($address, 'index', '--'));
$wcOrder->set_billing_country(self::arrayValue($address, 'country', '--'));
$wcOrder->set_billing_city(self::arrayValue($address, 'city', '--'));
$wcOrder->set_billing_address_1(self::arrayValue($address, 'text', '--'));
}
/**
* Sets shipping address properties in order
*
* @param \WC_Order $wcOrder
* @param array $address
*
* @throws \WC_Data_Exception
*/
private static function setShippingAddressToOrder($wcOrder, $address)
{
$wcOrder->set_shipping_state(self::arrayValue($address, 'region', '--'));
$wcOrder->set_shipping_postcode(self::arrayValue($address, 'index', '--'));
$wcOrder->set_shipping_country(self::arrayValue($address, 'country', '--'));
$wcOrder->set_shipping_city(self::arrayValue($address, 'city', '--'));
$wcOrder->set_shipping_address_1(self::arrayValue($address, 'text', '--'));
}
/**
* @param array|\ArrayObject|\ArrayAccess $arr
* @param string $key
* @param string $def
*
* @return mixed|string
*/
private static function arrayValue($arr, $key, $def = '')
{
if (!is_array($arr) && !($arr instanceof ArrayObject) && !($arr instanceof ArrayAccess)) {
return $def;
}
if (!array_key_exists($key, $arr) && !empty($arr[$key])) {
return $def;
}
return isset($arr[$key]) ? $arr[$key] : $def;
}
/**
* Returns first phone from order data or null
*
* @param array $customerData
*
* @return string|null
*/
private static function singleCustomerPhone($customerData)
{
if (!array_key_exists('phones', $customerData)) {
return '';
}
if (empty($customerData['phones']) || !is_array($customerData['phones'])) {
return '';
}
$phones = $customerData['phones'];
$phone = reset($phones);
if (!isset($phone['number'])) {
return '';
}
return (string) $phone['number'];
}
}

View File

@ -0,0 +1,402 @@
<?php
/**
* Class WC_Retailcrm_History_Assembler
* Assembles history records into list which closely resembles orders & customers list output from API.
*/
class WC_Retailcrm_History_Assembler
{
/**
* Assembles orders list from history data
*
* @param array $orderHistory
*
* @return array
*/
public static function assemblyOrder($orderHistory)
{
$fields = self::getMappingValues();
$orders = array();
$orderHistory = self::filterHistory($orderHistory, 'order');
foreach ($orderHistory as $change) {
$change['order'] = self::removeEmpty($change['order']);
if(isset($change['order']['items']) && $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(isset($change['order']['contragent']['contragentType']) && $change['order']['contragent']['contragentType']) {
$change['order']['contragentType'] = $change['order']['contragent']['contragentType'];
unset($change['order']['contragent']);
}
if (!empty($orders) && isset($orders[$change['order']['id']])) {
$orders[$change['order']['id']] = array_merge($orders[$change['order']['id']], $change['order']);
} else {
$orders[$change['order']['id']] = $change['order'];
}
if (isset($change['item']) && $change['item']) {
if(isset($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 ($change['oldValue'] === null
&& $change['field'] == 'order_product'
) {
$orders[$change['order']['id']]['items'][$change['item']['id']]['create'] = true;
}
if ($change['newValue'] === null
&& $change['field'] == 'order_product'
) {
$orders[$change['order']['id']]['items'][$change['item']['id']]['delete'] = true;
}
if (!isset($orders[$change['order']['id']]['items'][$change['item']['id']]['create'])
&& isset($fields['item'][$change['field']])
&& $fields['item'][$change['field']]
) {
$orders[$change['order']['id']]['items'][$change['item']['id']][$fields['item'][$change['field']]] = $change['newValue'];
}
} elseif ($change['field'] == 'payments' && isset($change['payment'])) {
if ($change['newValue'] !== null) {
$orders[$change['order']['id']]['payments'][] = self::newValue($change['payment']);
}
} else {
if (isset($fields['delivery'][$change['field']]) && $fields['delivery'][$change['field']] == 'service') {
$orders[$change['order']['id']]['delivery']['service']['code'] = self::newValue($change['newValue']);
} elseif (isset($fields['delivery'][$change['field']]) && $fields['delivery'][$change['field']]) {
$orders[$change['order']['id']]['delivery'][$fields['delivery'][$change['field']]] = self::newValue($change['newValue']);
} elseif (isset($fields['orderAddress'][$change['field']]) && $fields['orderAddress'][$change['field']]) {
$orders[$change['order']['id']]['delivery']['address'][$fields['orderAddress'][$change['field']]] = $change['newValue'];
} elseif (isset($fields['integrationDelivery'][$change['field']]) && $fields['integrationDelivery'][$change['field']]) {
$orders[$change['order']['id']]['delivery']['service'][$fields['integrationDelivery'][$change['field']]] = self::newValue($change['newValue']);
} elseif (isset($fields['customerContragent'][$change['field']]) && $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 (isset($fields['order'][$change['field']]) && $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;
}
/**
* Assembles customers list from history changes
*
* @param array $customerHistory
*
* @return array
*/
public static function assemblyCustomer($customerHistory)
{
$customers = array();
$fields = self::getMappingValues(array('customer'));
$fieldsAddress = self::getMappingValues(array('customerAddress'));
$customerHistory = self::filterHistory($customerHistory, 'customer');
foreach ($customerHistory as $change) {
$change['customer'] = self::removeEmpty($change['customer']);
if (isset($change['deleted'])
&& $change['deleted']
&& isset($customers[$change['customer']['id']])
) {
$customers[$change['customer']['id']]['deleted'] = true;
continue;
}
if ($change['field'] == 'id') {
$customers[$change['customer']['id']] = $change['customer'];
}
if (isset($customers[$change['customer']['id']])) {
$customers[$change['customer']['id']] = array_merge($customers[$change['customer']['id']], $change['customer']);
} else {
$customers[$change['customer']['id']] = $change['customer'];
}
if (isset($fields['customer'][$change['field']])
&& $fields['customer'][$change['field']]
) {
$customers[
$change['customer']['id']
][
$fields['customer'][$change['field']]
] = self::newValue($change['newValue']);
}
if (isset($fieldsAddress['customerAddress'][$change['field']])
&& $fieldsAddress['customerAddress'][$change['field']]
) {
if (!isset($customers[$change['customer']['id']]['address'])) {
$customers[$change['customer']['id']]['address'] = array();
}
$customers[
$change['customer']['id']
][
'address'
][
$fieldsAddress['customerAddress'][$change['field']]
] = self::newValue($change['newValue']);
}
// email_marketing_unsubscribed_at old value will be null and new value will be datetime in
// `Y-m-d H:i:s` format if customer was marked as unsubscribed in retailCRM
if (isset($change['customer']['id']) &&
$change['field'] == 'email_marketing_unsubscribed_at'
) {
if ($change['oldValue'] == null && is_string(self::newValue($change['newValue']))) {
$customers[$change['customer']['id']]['subscribed'] = false;
} elseif (is_string($change['oldValue']) && self::newValue($change['newValue']) == null) {
$customers[$change['customer']['id']]['subscribed'] = true;
}
}
}
return $customers;
}
/**
* Assembles corporate customers list from changes
*
* @param array $customerHistory
*
* @return array
*/
public static function assemblyCorporateCustomer($customerHistory)
{
$fields = self::getMappingValues(array('customerCorporate', 'customerAddress'));
$customersCorporate = array();
foreach ($customerHistory as $change) {
$change['customer'] = self::removeEmpty($change['customer']);
if (isset($change['deleted'])
&& $change['deleted']
&& isset($customersCorporate[$change['customer']['id']])
) {
$customersCorporate[$change['customer']['id']]['deleted'] = true;
continue;
}
if (isset($customersCorporate[$change['customer']['id']])) {
if (isset($customersCorporate[$change['customer']['id']]['deleted'])
&& $customersCorporate[$change['customer']['id']]['deleted']
) {
continue;
}
$customersCorporate[$change['customer']['id']] = array_merge(
$customersCorporate[$change['customer']['id']],
$change['customer']
);
} else {
$customersCorporate[$change['customer']['id']] = $change['customer'];
}
if (isset($fields['customerCorporate'][$change['field']])
&& $fields['customerCorporate'][$change['field']]
) {
$customersCorporate[
$change['customer']['id']
][
$fields['customerCorporate'][$change['field']]
] = self::newValue($change['newValue']);
}
if (isset($fields['customerAddress'][$change['field']])
&& $fields['customerAddress'][$change['field']]
) {
if (empty($customersCorporate[$change['customer']['id']]['address'])) {
$customersCorporate[$change['customer']['id']]['address'] = array();
}
$customersCorporate[
$change['customer']['id']
][
'address'
][
$fields['customerAddress'][$change['field']]
] = self::newValue($change['newValue']);
}
if ($change['field'] == 'address') {
$customersCorporate[
$change['customer']['id']
]['address'] = array_merge($change['address'], self::newValue($change['newValue']));
}
}
foreach ($customersCorporate as $id => &$customer) {
if (empty($customer['id']) && !empty($id)) {
$customer['id'] = $id;
$customer['deleted'] = true;
}
}
return $customersCorporate;
}
/**
* Returns mapping data for retailCRM entities. Used to assembly entities from history.
*
* @param array $groupFilter
*
* @return array
*/
private static function getMappingValues($groupFilter = array())
{
$fields = array();
$mappingFile = realpath(implode(
DIRECTORY_SEPARATOR,
array(__DIR__, '..', '..', 'config', 'objects.xml')
));
if (file_exists($mappingFile)) {
$objects = simplexml_load_file($mappingFile);
foreach($objects->fields->field as $object) {
if (empty($groupFilter) || in_array($object["group"], $groupFilter)) {
$fields[(string)$object["group"]][(string)$object["id"]] = (string)$object;
}
}
}
return $fields;
}
/**
* Value accessor
*
* @param array $value
*
* @return mixed
*/
private static function newValue($value)
{
if (isset($value['code'])) {
return $value['code'];
} else {
return $value;
}
}
/**
* Returns array without values which are considered empty
*
* @param array|\ArrayAccess $inputArray
*
* @return array
*/
private 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;
}
/**
* Filters out history by these terms:
* - Changes from current API key will be added only if CMS changes are more actual than history.
* - All other changes will be merged as usual.
* It fixes these problems:
* - Changes from current API key are merged when it's not needed.
* - Changes from CRM can overwrite more actual changes from CMS due to ignoring current API key changes.
*
* @param array $historyEntries Raw history from CRM
* @param string $recordType Entity field name, e.g. `customer` or `order`.
*
* @return array
*/
private static function filterHistory($historyEntries, $recordType)
{
$history = array();
$organizedHistory = array();
$notOurChanges = array();
foreach ($historyEntries as $entry) {
if (!isset($entry[$recordType]['externalId'])) {
if ($entry['source'] == 'api'
&& isset($change['apiKey']['current'])
&& $entry['apiKey']['current'] == true
&& $entry['field'] != 'externalId'
) {
continue;
} else {
$history[] = $entry;
}
continue;
}
$externalId = $entry[$recordType]['externalId'];
$field = $entry['field'];
if (!isset($organizedHistory[$externalId])) {
$organizedHistory[$externalId] = array();
}
if (!isset($notOurChanges[$externalId])) {
$notOurChanges[$externalId] = array();
}
if ($entry['source'] == 'api'
&& isset($entry['apiKey']['current'])
&& $entry['apiKey']['current'] == true
) {
if (isset($notOurChanges[$externalId][$field]) || $entry['field'] == 'externalId') {
$organizedHistory[$externalId][] = $entry;
} else {
continue;
}
} else {
$organizedHistory[$externalId][] = $entry;
$notOurChanges[$externalId][$field] = true;
}
}
unset($notOurChanges);
foreach ($organizedHistory as $historyChunk) {
$history = array_merge($history, $historyChunk);
}
return $history;
}
}

View File

@ -0,0 +1,125 @@
<?php
/**
* RetailCRM Integration.
*
* @package WC_Retailcrm_Customers
* @category Integration
* @author RetailCRM
*/
if (!class_exists('WC_Retailcrm_Logger') && class_exists('WC_Log_Levels')):
/**
* Class WC_Retailcrm_Logger
*/
class WC_Retailcrm_Logger
{
/** @var string */
const HANDLE = 'retailcrm';
/**
* @var \WC_Logger_Interface $instance
*/
private static $instance;
/**
* @var array $additionalHandlers
*/
private static $additionalHandlers;
/**
* WC_Retailcrm_Logger constructor.
*/
private function __construct() {}
/**
* Instantiates logger with file handler.
*
* @return \WC_Logger_Interface
*/
private static function getInstance()
{
if (empty(static::$instance)) {
static::$instance = new WC_Logger(self::$additionalHandlers);
}
return static::$instance;
}
/**
* @param array $additionalHandlers
*/
public static function setAdditionalHandlers($additionalHandlers)
{
self::$additionalHandlers = $additionalHandlers;
}
/**
* Regular logging
*
* @param string $message
* @param string $level
*/
public static function add($message, $level = WC_Log_Levels::NOTICE)
{
self::getInstance()->add(self::HANDLE, $message, $level);
}
/**
* Regular logging with caller prefix
*
* @param string $caller
* @param string $message
* @param string $level
*/
public static function addCaller($caller, $message, $level = WC_Log_Levels::NOTICE)
{
self::add(sprintf('<%s> => %s', $caller, $message), $level);
}
/**
* Log error
*
* @param string $message
*/
public static function error($message)
{
self::add($message, WC_Log_Levels::ERROR);
}
/**
* Debug logging. Contains a lot of debug data like full requests & responses.
* This log will work only if debug mode is enabled (see retailcrm_is_debug() for details).
* Caller should be specified, or message will be ignored at all.
*
* @param string $method
* @param array|string $messages
*/
public static function debug($method, $messages)
{
if (retailcrm_is_debug()) {
if (!empty($method) && !empty($messages)) {
$result = is_array($messages) ? substr(
array_reduce(
$messages,
function ($carry, $item) {
$carry .= ' ' . print_r($item, true);
return $carry;
}
),
1
) : $messages;
self::getInstance()->add(
self::HANDLE . '_debug',
sprintf(
'<%s> => %s',
$method,
$result
),
WC_Log_Levels::DEBUG
);
}
}
}
}
endif;

View File

@ -0,0 +1,188 @@
<?php
/**
* Class WC_Retailcrm_Paginated_Request
* It will merge request with pagination data into one big monstrous array.
* Use with caution, it can cause problems with very large data sets (due to memory exhaustion, obviously).
*/
class WC_Retailcrm_Paginated_Request
{
/**
* @var \WC_Retailcrm_Proxy|\WC_Retailcrm_Client_V5
*/
private $api;
/**
* @var string
*/
private $method;
/**
* @var array
*/
private $params;
/**
* @var string
*/
private $dataKey;
/**
* @var int
*/
private $limit;
/**
* @var array
*/
private $data;
/**
* WC_Retailcrm_Paginated_Request constructor.
*/
public function __construct()
{
$this->reset();
}
/**
* Sets retailCRM api client to request
*
* @param \WC_Retailcrm_Proxy|\WC_Retailcrm_Client_V5 $api
*
* @return self
*/
public function setApi($api)
{
$this->api = $api;
return $this;
}
/**
* Sets API client method to request
*
* @param string $method
*
* @return self
*/
public function setMethod($method)
{
$this->method = $method;
return $this;
}
/**
* Sets method params for API client (leave `{{page}}` instead of page and `{{limit}}` instead of limit)
*
* @param array $params
*
* @return self
*/
public function setParams($params)
{
$this->params = $params;
return $this;
}
/**
* Sets dataKey (key with data in response)
*
* @param string $dataKey
*
* @return self
*/
public function setDataKey($dataKey)
{
$this->dataKey = $dataKey;
return $this;
}
/**
* Sets record limit per request
*
* @param int $limit
*
* @return self
*/
public function setLimit($limit)
{
$this->limit = $limit;
return $this;
}
/**
* Executes request
*
* @return $this
*/
public function execute()
{
$this->data = array();
$response = true;
$page = 1;
do {
$response = call_user_func_array(
array($this->api, $this->method),
$this->buildParams($this->params, $page)
);
if ($response instanceof WC_Retailcrm_Response && $response->offsetExists($this->dataKey)) {
$this->data = array_merge($response[$this->dataKey]);
$page = $response['pagination']['currentPage'] + 1;
}
time_nanosleep(0, 300000000);
} while ($response && (isset($response['pagination'])
&& $response['pagination']['currentPage'] < $response['pagination']['totalPageCount']));
return $this;
}
/**
* Returns data
*
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* Reset paginated request
*
* @return $this
*/
public function reset()
{
$this->method = '';
$this->limit = 100;
$this->data = array();
return $this;
}
/**
* buildParams
*
* @param array $placeholderParams
* @param int $currentPage
*
* @return mixed
*/
private function buildParams($placeholderParams, $currentPage)
{
foreach ($placeholderParams as $key => $param) {
if ($param == '{{page}}') {
$placeholderParams[$key] = $currentPage;
}
if ($param == '{{limit}}') {
$placeholderParams[$key] = $this->limit;
}
}
return $placeholderParams;
}
}

View File

@ -18,11 +18,23 @@ class WC_Retailcrm_Customer_Address extends WC_Retailcrm_Abstracts_Address
/** /**
* @param WC_Customer $customer * @param WC_Customer $customer
* @param \WC_Order|null $order
* *
* @return self * @return self
*/ */
public function build($customer) public function build($customer, $order = null)
{ {
$customerBillingAddress = $customer->get_billing_address();
if ($order instanceof WC_Order && empty($customerBillingAddress)) {
$data = array(
'index' => $order->get_billing_postcode(),
'countryIso' => $order->get_billing_country(),
'region' => $this->get_state_name($order->get_billing_country(), $order->get_billing_state()),
'city' => $order->get_billing_city(),
'text' => $order->get_billing_address_1() . ', ' . $order->get_billing_address_2()
);
} else {
$data = array( $data = array(
'index' => $customer->get_billing_postcode(), 'index' => $customer->get_billing_postcode(),
'countryIso' => $customer->get_billing_country(), 'countryIso' => $customer->get_billing_country(),
@ -30,6 +42,7 @@ class WC_Retailcrm_Customer_Address extends WC_Retailcrm_Abstracts_Address
'city' => $customer->get_billing_city(), 'city' => $customer->get_billing_city(),
'text' => $customer->get_billing_address_1() . ', ' . $customer->get_billing_address_2() 'text' => $customer->get_billing_address_1() . ', ' . $customer->get_billing_address_2()
); );
}
$this->set_data_fields($data); $this->set_data_fields($data);

View File

@ -0,0 +1,158 @@
<?php
/**
* PHP version 5.3
*
* @category Integration
* @author RetailCRM <integration@retailcrm.ru>
* @license http://retailcrm.ru Proprietary
* @link http://retailcrm.ru
* @see http://help.retailcrm.ru
*/
/**
* Class WC_Retailcrm_Customer_Address
*/
class WC_Retailcrm_Customer_Corporate_Address extends WC_Retailcrm_Abstracts_Address
{
/** @var string $filter_name */
protected $filter_name = 'customer_address';
/** @var bool $isMain */
protected $isMain = true;
/** @var bool $explicitIsMain */
protected $explicitIsMain;
/**
* Sets woocommerce address type to work with
*
* @param string $addressType
*
* @return \WC_Retailcrm_Customer_Corporate_Address
*/
public function setWCAddressType($addressType = WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_SHIPPING)
{
$this->address_type = $addressType;
return $this;
}
/**
* @param bool $fallback_to_shipping
*
* @return WC_Retailcrm_Customer_Corporate_Address
*/
public function setFallbackToShipping($fallback_to_shipping)
{
$this->fallback_to_shipping = $fallback_to_shipping;
return $this;
}
/**
* @param bool $isMain
*
* @return WC_Retailcrm_Customer_Corporate_Address
*/
public function setIsMain($isMain)
{
$this->isMain = $isMain;
return $this;
}
/**
* @param bool $explicitIsMain
*
* @return WC_Retailcrm_Customer_Corporate_Address
*/
public function setExplicitIsMain($explicitIsMain)
{
$this->explicitIsMain = $explicitIsMain;
return $this;
}
/**
* @param WC_Customer $customer
* @param \WC_Order|null $order
*
* @return self
*/
public function build($customer, $order = null)
{
if ($order instanceof WC_Order) {
$address = $this->getOrderAddress($order);
$data = array(
'index' => $address['postcode'],
'countryIso' => $address['country'],
'region' => $address['state'],
'city' => $address['city'],
'name' => $address['company'],
'text' => $this->joinAddresses($address['address_1'], $address['address_2'])
);
} else if (self::ADDRESS_TYPE_SHIPPING === $this->address_type) {
$data = $this->getCustomerShippingAddress($customer);
if (empty($address) && $this->fallback_to_billing) {
$data = $this->getCustomerBillingAddress($customer);
}
} elseif (self::ADDRESS_TYPE_BILLING === $this->address_type) {
$data = $this->getCustomerBillingAddress($customer);
if (empty($address) && $this->fallback_to_shipping) {
$data = $this->getCustomerShippingAddress($customer);
}
}
if ($this->isMain) {
$data['isMain'] = true;
} elseif ($this->explicitIsMain) {
$data['isMain'] = false;
}
$this->set_data_fields($data);
return $this;
}
/**
* Returns built customer billing address
*
* @param \WC_Customer|\WP_User $customer
*
* @return array
*/
public function getCustomerBillingAddress($customer)
{
return array(
'index' => $customer->get_billing_postcode(),
'countryIso' => $customer->get_billing_country(),
'region' => $customer->get_billing_state(),
'city' => $customer->get_billing_city(),
'name' => $customer->get_billing_company(),
'text' => $this->joinAddresses(
$customer->get_billing_address_1(),
$customer->get_billing_address_2()
)
);
}
/**
* Returns built customer shipping address
*
* @param \WC_Customer|\WP_User $customer
*
* @return array
*/
public function getCustomerShippingAddress($customer)
{
return array(
'index' => $customer->get_shipping_postcode(),
'countryIso' => $customer->get_shipping_country(),
'region' => $customer->get_shipping_state(),
'city' => $customer->get_shipping_city(),
'name' => $customer->get_shipping_company(),
'text' => $this->joinAddresses(
$customer->get_shipping_address_1(),
$customer->get_shipping_address_2()
)
);
}
}

View File

@ -0,0 +1,237 @@
<?php
/**
* Class WC_Retailcrm_WC_Customer_Builder
* It converts retailCRM customer data (array) into WC_Customer
*/
class WC_Retailcrm_WC_Customer_Builder extends WC_Retailcrm_Abstract_Builder
{
/**
* @var \WC_Customer $customer
*/
private $customer;
/**
* WC_Retailcrm_WC_Customer_Builder constructor.
*/
public function __construct()
{
$this->reset();
}
/**
* @param string $firstName
*
* @return $this
*/
public function setFirstName($firstName)
{
$this->data['firstName'] = $firstName;
return $this;
}
/**
* @param string $lastName
*
* @return $this
*/
public function setLastName($lastName)
{
$this->data['lastName'] = $lastName;
return $this;
}
/**
* @param string $email
*
* @return $this
*/
public function setEmail($email)
{
$this->data['email'] = $email;
return $this;
}
/**
* @param string $externalId
*
* @return $this
*/
public function setExternalId($externalId)
{
$this->data['externalId'] = $externalId;
return $this;
}
/**
* @param array $phones
*
* @return $this
*/
public function setPhones($phones)
{
if (self::isPhonesArrayValid($phones)) {
$this->data['phones'] = $phones;
}
return $this;
}
/**
* @param array $address
*
* @return $this
*/
public function setAddress($address)
{
if (is_array($address)) {
$this->data['address'] = $address;
}
return $this;
}
/**
* @param \WC_Customer $customer
*
* @return $this
*/
public function setWcCustomer($customer)
{
if ($customer instanceof WC_Customer) {
$this->customer = $customer;
}
return $this;
}
/**
* Sets provided externalId and loads associated customer from DB (it it exists there).
* Returns true if everything went find; returns false if customer wasn't found.
*
* @param string $externalId
*
* @return bool
* @throws \Exception
*/
public function loadExternalId($externalId)
{
try {
$wcCustomer = new WC_Customer($externalId);
} catch (\Exception $exception) {
return false;
}
$this->setExternalId($externalId);
$this->setWcCustomer($wcCustomer);
return true;
}
public function reset()
{
parent::reset();
$this->customer = new WC_Customer();
return $this;
}
/**
* Fill WC_Customer fields with customer data from retailCRM.
* If field is not present in retailCRM customer - it will remain unchanged.
*
* @return $this|\WC_Retailcrm_Builder_Interface
*/
public function build()
{
$this->checkBuilderValidity();
WC_Retailcrm_Logger::debug(__METHOD__, array('Building WC_Customer from data:', $this->data));
$this->customer->set_first_name($this->dataValue('firstName', $this->customer->get_first_name()));
$this->customer->set_last_name($this->dataValue('lastName', $this->customer->get_last_name()));
$this->customer->set_billing_email($this->dataValue('email', $this->customer->get_billing_email()));
$phones = $this->dataValue('phones', array());
if ((is_array($phones) || $phones instanceof Countable) && count($phones) > 0) {
$phoneData = reset($phones);
if (is_array($phoneData) && isset($phoneData['number'])) {
$this->customer->set_billing_phone($phoneData['number']);
}
} elseif (is_string($phones) || is_numeric($phones)) {
$this->customer->set_billing_phone($phones);
}
$address = $this->dataValue('address');
if (!empty($address)) {
$this->customer->set_billing_state(self::arrayValue(
$address,
'region',
$this->customer->get_billing_state())
);
$this->customer->set_billing_postcode(self::arrayValue(
$address,
'index',
$this->customer->get_billing_postcode())
);
$this->customer->set_billing_country(self::arrayValue(
$address,
'country',
$this->customer->get_billing_country())
);
$this->customer->set_billing_city(self::arrayValue(
$address,
'city',
$this->customer->get_billing_city())
);
}
return $this;
}
/**
* @return mixed|\WC_Customer|null
*/
public function getResult()
{
return $this->customer;
}
/**
* Throws an exception if internal state is not ready for data building.
*
* @throws \RuntimeException
*/
private function checkBuilderValidity()
{
if (empty($this->data)) {
throw new \RuntimeException('Empty data');
}
if (!is_array($this->data)) {
throw new \RuntimeException('Data must be an array');
}
}
/**
* Returns true if provided variable contains array with customer phones.
*
* @param mixed $phones
*
* @return bool
*/
private static function isPhonesArrayValid($phones)
{
if (!is_array($phones)) {
return false;
}
foreach ($phones as $phone) {
if (!is_array($phone) || count($phone) != 1 || !array_key_exists('number', $phone)) {
return false;
}
}
return true;
}
}

View File

@ -67,7 +67,7 @@ function get_wc_shipping_methods() {
); );
} }
return apply_filters('retailcrm_shipping_list', $result); return apply_filters('retailcrm_shipping_list', WC_Retailcrm_Plugin::clearArray($result));
} }
function retailcrm_get_delivery_service($method_id, $instance_id) { function retailcrm_get_delivery_service($method_id, $instance_id) {
@ -98,3 +98,13 @@ function retailcrm_get_wc_product($id, $settings) {
return wc_get_product($id); return wc_get_product($id);
} }
/**
* Returns true if either wordpress debug mode or module debugging is enabled
*
* @return bool
*/
function retailcrm_is_debug() {
return (defined('WP_DEBUG') && WP_DEBUG == true)
|| (defined('RCRM_DEBUG') && RCRM_DEBUG == true);
}

View File

@ -0,0 +1,48 @@
<?php
/**
* Interface WC_Retailcrm_Builder_Interface.
* Main interface for builders. All builders
*/
interface WC_Retailcrm_Builder_Interface {
/**
* Sets data into builder
*
* @param array|mixed $data
*
* @return self
*/
public function setData($data);
/**
* Returns data present in the builder
*
* @return array|mixed
*/
public function getData();
/**
* This method should build result with data present in the builder.
* It should return builder instance in spite of actual building result.
* Any exception can be thrown in case of error. It should be processed accordingly.
*
* @return self
* @throws \Exception
*/
public function build();
/**
* This method should reset builder state.
* In other words, after calling reset() builder inner state should become identical to newly created builder's state.
*
* @return self
*/
public function reset();
/**
* Returns builder result. Can be anything (depends on builder).
*
* @return mixed|null
*/
public function getResult();
}

View File

@ -0,0 +1,77 @@
<?php
/**
* Class WC_Retailcrm_Customer_Switcher_Result
* Holds modified order and customer which was set in the order.
* If customer is null, then only order props was updated. Previous customer (if it was registered)
* will be detached from this order.
*/
class WC_Retailcrm_Customer_Switcher_Result
{
/** @var \WC_Customer|null */
private $wcCustomer;
/** @var \WC_Order $wcOrder */
private $wcOrder;
/**
* WC_Retailcrm_Customer_Switcher_Result constructor.
*
* @param \WC_Customer|null $wcCustomer
* @param \WC_Order $wcOrder
*/
public function __construct($wcCustomer, $wcOrder)
{
$this->wcCustomer = $wcCustomer;
$this->wcOrder = $wcOrder;
if ((!is_null($this->wcCustomer) && !($this->wcCustomer instanceof WC_Customer))
|| !($this->wcOrder instanceof WC_Order)
) {
throw new \InvalidArgumentException(sprintf('Incorrect data provided to %s', __CLASS__));
}
}
/**
* @return \WC_Customer|null
*/
public function getWcCustomer()
{
return $this->wcCustomer;
}
/**
* @return \WC_Order
*/
public function getWcOrder()
{
return $this->wcOrder;
}
/**
* Save customer (if exists) and order.
*
* @return $this
*/
public function save()
{
WC_Retailcrm_Logger::debug(
__METHOD__,
array(
'Saving customer and order:',
$this->wcCustomer,
$this->wcOrder
)
);
if (!empty($this->wcCustomer) && $this->wcCustomer->get_id()) {
$this->wcCustomer->save();
}
if (!empty($this->wcOrder) && $this->wcOrder->get_id()) {
$this->wcOrder->save();
}
return $this;
}
}

View File

@ -0,0 +1,178 @@
<?php
/**
* Class WC_Retailcrm_Customer_Switcher_State
* Holds WC_Retailcrm_Customer_Switcher state. It exists only because we need to comply with builder interface.
*/
class WC_Retailcrm_Customer_Switcher_State
{
/** @var \WC_Order $wcOrder */
private $wcOrder;
/** @var array */
private $newCustomer;
/** @var array */
private $newContact;
/** @var string $newCompanyName */
private $newCompanyName;
/** @var array $companyAddress */
private $companyAddress;
/**
* @return \WC_Order
*/
public function getWcOrder()
{
return $this->wcOrder;
}
/**
* @param \WC_Order $wcOrder
*
* @return WC_Retailcrm_Customer_Switcher_State
*/
public function setWcOrder($wcOrder)
{
$this->wcOrder = $wcOrder;
return $this;
}
/**
* @return array
*/
public function getNewCustomer()
{
return $this->newCustomer;
}
/**
* @param array $newCustomer
*
* @return WC_Retailcrm_Customer_Switcher_State
*/
public function setNewCustomer($newCustomer)
{
$this->newCustomer = $newCustomer;
return $this;
}
/**
* @return array
*/
public function getNewContact()
{
return $this->newContact;
}
/**
* @param array $newContact
*
* @return WC_Retailcrm_Customer_Switcher_State
*/
public function setNewContact($newContact)
{
$this->newContact = $newContact;
return $this;
}
/**
* @return string
*/
public function getNewCompanyName()
{
return $this->newCompanyName;
}
/**
* @param string $newCompanyName
*
* @return WC_Retailcrm_Customer_Switcher_State
*/
public function setNewCompanyName($newCompanyName)
{
$this->newCompanyName = $newCompanyName;
return $this;
}
/**
* @return array
*/
public function getCompanyAddress()
{
return $this->companyAddress;
}
/**
* @param array $companyAddress
*
* @return WC_Retailcrm_Customer_Switcher_State
*/
public function setCompanyAddress($companyAddress)
{
$this->companyAddress = $companyAddress;
return $this;
}
/**
* @param array $newCompany
*
* @return WC_Retailcrm_Customer_Switcher_State
*/
public function setNewCompany($newCompany)
{
if (isset($newCompany['name'])) {
$this->setNewCompanyName($newCompany['name']);
}
if (isset($newCompany['address']) && !empty($newCompany['address'])) {
$this->setCompanyAddress($newCompany['address']);
}
return $this;
}
/**
* Returns true if current state may be processable (e.g. when customer or related data was changed).
* It doesn't guarantee state validity.
*
* @return bool
*/
public function feasible()
{
return !(empty($this->newCustomer) && empty($this->newContact) && empty($this->newCompanyName));
}
/**
* Throws an exception if state is not valid
*
* @throws \InvalidArgumentException
* @return void
*/
public function validate()
{
if (empty($this->wcOrder)) {
throw new \InvalidArgumentException('Empty WC_Order.');
}
if (empty($this->newCustomer) && empty($this->newContact) && empty($this->newCompanyName)) {
throw new \InvalidArgumentException('New customer, new contact and new company is empty.');
}
if (!empty($this->newCustomer) && !empty($this->newContact)) {
WC_Retailcrm_Logger::debug(
__METHOD__,
array(
'State data (customer and contact):' . PHP_EOL,
$this->getNewCustomer(),
$this->getNewContact()
)
);
throw new \InvalidArgumentException(
'Too much data in state - cannot determine which customer should be used.'
);
}
}
}

View File

@ -11,6 +11,7 @@
class WC_Retailcrm_Order_Address extends WC_Retailcrm_Abstracts_Address class WC_Retailcrm_Order_Address extends WC_Retailcrm_Abstracts_Address
{ {
/** @var string $filter_name */
protected $filter_name = 'order_address'; protected $filter_name = 'order_address';
/** /**
@ -20,7 +21,7 @@ class WC_Retailcrm_Order_Address extends WC_Retailcrm_Abstracts_Address
*/ */
public function build($order) public function build($order)
{ {
$address = $order->get_address('shipping'); $address = $this->getOrderAddress($order);
if (!empty($address)) { if (!empty($address)) {
$data = array( $data = array(

View File

@ -65,12 +65,7 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data
$this->set_data_fields($data); $this->set_data_fields($data);
$this->set_offer($item); $this->set_offer($item);
$this->set_data_field('discountManualAmount', (float) round($discount_price, 2));
if ($this->settings['api_version'] == 'v5' && round($discount_price, 2)) {
$this->set_data_field('discountManualAmount',round($discount_price, 2));
} elseif ($this->settings['api_version'] == 'v4' && round($discount_price, 2)) {
$this->set_data_field('discount', round($discount_price, 2));
}
return $this; return $this;
} }
@ -114,6 +109,7 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data
* @param $price * @param $price
* *
* @return float|int * @return float|int
* @todo Rounding issues with prices in pennies / cents should be expected here.
*/ */
private function calculate_discount(WC_Order_Item_Product $item, $price) private function calculate_discount(WC_Order_Item_Product $item, $price)
{ {

View File

@ -50,6 +50,7 @@ class WC_Retailcrm_Order_Payment extends WC_Retailcrm_Abstracts_Data
*/ */
public function build($order, $externalId = false) public function build($order, $externalId = false)
{ {
$this->reset_data();
$data = array(); $data = array();
if (!empty($this->settings['send_payment_amount']) if (!empty($this->settings['send_payment_amount'])
@ -79,6 +80,8 @@ class WC_Retailcrm_Order_Payment extends WC_Retailcrm_Abstracts_Data
if ($this->is_new) { if ($this->is_new) {
if (isset($this->settings[$order->get_payment_method()])) { if (isset($this->settings[$order->get_payment_method()])) {
$data['type'] = $this->settings[$order->get_payment_method()]; $data['type'] = $this->settings[$order->get_payment_method()];
} else {
$data = array();
} }
} }
@ -87,6 +90,28 @@ class WC_Retailcrm_Order_Payment extends WC_Retailcrm_Abstracts_Data
return $this; return $this;
} }
/**
* Returns false if payment doesn't have method
*
* @return array
*/
public function get_data()
{
$data = parent::get_data();
if (empty($data['type'])) {
return array();
}
if (!empty($this->settings['send_payment_amount'])
&& $this->settings['send_payment_amount'] === WC_Retailcrm_Base::NO
) {
unset($data['amount']);
}
return $data;
}
public function reset_data() public function reset_data()
{ {
$this->data = array( $this->data = array(

View File

@ -64,13 +64,14 @@ class WC_Retailcrm_Order extends WC_Retailcrm_Abstracts_Data
'countryIso' => $order->get_shipping_country() 'countryIso' => $order->get_shipping_country()
); );
if ($data['countryIso'] == '--') {
$countries = new WC_Countries();
$data['countryIso'] = $countries->get_base_country();
}
$this->set_data_fields($data); $this->set_data_fields($data);
$this->set_number($order); $this->set_number($order);
if ($this->settings['api_version'] != 'v5') {
$this->set_payment_data($order);
}
if (isset($this->settings[$order->get_status()])) { if (isset($this->settings[$order->get_status()])) {
$this->set_data_field('status', $this->settings[$order->get_status()]); $this->set_data_field('status', $this->settings[$order->get_status()]);
} }

Binary file not shown.

Binary file not shown.

View File

@ -45,6 +45,10 @@ API-ключ должен быть для отдельного магазина
2. В появившихся списках справочников настройте соответствие способов доставки и оплаты, а так же статусов заказов. Отметьте галочку "Выгружать остатки", если хотите выгружать остатки из Retailcrm в магазин (подробнее смотрите в описании). 2. В появившихся списках справочников настройте соответствие способов доставки и оплаты, а так же статусов заказов. Отметьте галочку "Выгружать остатки", если хотите выгружать остатки из Retailcrm в магазин (подробнее смотрите в описании).
== Changelog == == Changelog ==
= 4.0.0 =
* Поддержка корпоративных клиентов
* Поддержка изменения покупателя в заказе
= 3.6.4 = = 3.6.4 =
* Передача названия региона / штата / провинции вместо кода * Передача названия региона / штата / провинции вместо кода

View File

@ -1,6 +1,6 @@
<?php <?php
/** /**
* Version: 3.6.4 * Version: 4.0.0
* WC requires at least: 3.0 * WC requires at least: 3.0
* WC tested up to: 3.9.3 * WC tested up to: 3.9.3
* Plugin Name: WooCommerce retailCRM * Plugin Name: WooCommerce retailCRM
@ -21,6 +21,8 @@ if (!class_exists( 'WC_Integration_Retailcrm')) :
* Class WC_Integration_Retailcrm * Class WC_Integration_Retailcrm
*/ */
class WC_Integration_Retailcrm { class WC_Integration_Retailcrm {
const WOOCOMMERCE_SLUG = 'woocommerce';
const WOOCOMMERCE_PLUGIN_PATH = 'woocommerce/woocommerce.php';
private static $instance; private static $instance;
@ -39,16 +41,7 @@ if (!class_exists( 'WC_Integration_Retailcrm')) :
$this->load_plugin_textdomain(); $this->load_plugin_textdomain();
if (class_exists( 'WC_Integration' )) { if (class_exists( 'WC_Integration' )) {
require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-settings.php'); self::load_module();
require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-data.php');
require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-address.php');
require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order.php');
require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order-payment.php');
require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order-item.php');
require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order-address.php');
require_once(dirname(__FILE__ ) . '/include/customer/class-wc-retailcrm-customer-address.php');
require_once(dirname(__FILE__ ) . '/include/class-wc-retailcrm-base.php');
require_once(dirname(__FILE__ ) . '/include/functions.php');
add_filter('woocommerce_integrations', array( $this, 'add_integration')); add_filter('woocommerce_integrations', array( $this, 'add_integration'));
} else { } else {
add_action('admin_notices', array($this, 'woocommerce_missing_notice')); add_action('admin_notices', array($this, 'woocommerce_missing_notice'));
@ -56,7 +49,30 @@ if (!class_exists( 'WC_Integration_Retailcrm')) :
} }
public function woocommerce_missing_notice() { public function woocommerce_missing_notice() {
echo '<div class="error"><p>Woocommerce is not installed</p></div>'; if (static::isWooCommerceInstalled()) {
if (!is_plugin_active(static::WOOCOMMERCE_PLUGIN_PATH)) {
echo '
<div class="error">
<p>
Activate WooCommerce in order to enable retailCRM integration!
<a href="' . wp_nonce_url(admin_url('plugins.php')) . '" aria-label="Activate WooCommerce">
Click here to open plugins manager
</a>
</p>
</div>
';
}
} else {
echo '
<div class="error">
<p>
<a href="'
. static::generatePluginInstallationUrl(static::WOOCOMMERCE_SLUG)
. '" aria-label="Install WooCommerce">Install WooCommerce</a> in order to enable retailCRM integration!
</p>
</div>
';
}
} }
public function load_plugin_textdomain() { public function load_plugin_textdomain() {
@ -74,6 +90,78 @@ if (!class_exists( 'WC_Integration_Retailcrm')) :
$integrations[] = 'WC_Retailcrm_Base'; $integrations[] = 'WC_Retailcrm_Base';
return $integrations; return $integrations;
} }
/**
* Loads module classes.
*/
public static function load_module()
{
require_once(dirname(__FILE__) . '/include/interfaces/class-wc-retailcrm-builder-interface.php');
require_once(dirname(__FILE__) . '/include/models/class-wc-retailcrm-customer-switcher-state.php');
require_once(dirname(__FILE__) . '/include/models/class-wc-retailcrm-customer-switcher-result.php');
require_once(dirname(__FILE__ ) . '/include/components/class-wc-retailcrm-logger.php');
require_once(dirname(__FILE__ ) . '/include/components/class-wc-retailcrm-history-assembler.php');
require_once(dirname(__FILE__ ) . '/include/components/class-wc-retailcrm-paginated-request.php');
require_once(dirname(__FILE__) . '/include/components/class-wc-retailcrm-customer-switcher.php');
require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstract-builder.php');
require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-settings.php');
require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-data.php');
require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-address.php');
require_once(dirname(__FILE__ ) . '/include/customer/woocommerce/class-wc-retailcrm-wc-customer-builder.php');
require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order.php');
require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order-payment.php');
require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order-item.php');
require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order-address.php');
require_once(dirname(__FILE__ ) . '/include/customer/class-wc-retailcrm-customer-address.php');
require_once(dirname(__FILE__ ) . '/include/customer/class-wc-retailcrm-customer-corporate-address.php');
require_once(dirname(__FILE__ ) . '/include/class-wc-retailcrm-base.php');
require_once(dirname(__FILE__ ) . '/include/functions.php');
}
/**
* Returns true if WooCommerce was found in plugin cache
*
* @return bool
*/
private function isWooCommerceInstalled()
{
$plugins = wp_cache_get( 'plugins', 'plugins' );
if (!$plugins) {
$plugins = get_plugins();
} elseif (isset($plugins[''])) {
$plugins = $plugins[''];
}
if (!isset($plugins[static::WOOCOMMERCE_PLUGIN_PATH])) {
return false;
}
return true;
}
/**
* Generate plugin installation url
*
* @param $pluginSlug
*
* @return string
*/
private function generatePluginInstallationUrl($pluginSlug)
{
$action = 'install-plugin';
return wp_nonce_url(
add_query_arg(
array(
'action' => $action,
'plugin' => $pluginSlug
),
admin_url( 'update.php' )
),
$action.'_'.$pluginSlug
);
}
} }
if (!class_exists('WC_Retailcrm_Plugin')) { if (!class_exists('WC_Retailcrm_Plugin')) {

View File

@ -15,7 +15,7 @@
* *
* *
* @link https://wordpress.org/plugins/woo-retailcrm/ * @link https://wordpress.org/plugins/woo-retailcrm/
* @version 3.6.4 * @version 4.0.0
* *
* @package RetailCRM * @package RetailCRM
*/ */

0
tests/bin/install.sh Executable file → Normal file
View File

View File

@ -1,6 +1,7 @@
<?php <?php
$_tests_dir = getenv('WP_TESTS_DIR'); $_tests_dir = getenv('WP_TESTS_DIR');
$_output_logs_to_stdout = getenv('MODULE_LOGS_TO_STDOUT');
$_wcOldBootstrap = '/tmp/woocommerce/tests/bootstrap.php'; $_wcOldBootstrap = '/tmp/woocommerce/tests/bootstrap.php';
$_wcNewBootstrap = '/tmp/woocommerce/tests/legacy/bootstrap.php'; $_wcNewBootstrap = '/tmp/woocommerce/tests/legacy/bootstrap.php';
@ -32,6 +33,13 @@ if (file_exists($_wcOldBootstrap)) {
} }
$plugin_dir = dirname(dirname(__FILE__)) . '/'; $plugin_dir = dirname(dirname(__FILE__)) . '/';
// helpers // helpers
require $plugin_dir . 'src/include/components/class-wc-retailcrm-logger.php';
require $plugin_dir . 'tests/helpers/class-wc-retailcrm-response-helper.php'; require $plugin_dir . 'tests/helpers/class-wc-retailcrm-response-helper.php';
require $plugin_dir . 'tests/helpers/class-wc-retailcrm-test-case-helper.php'; require $plugin_dir . 'tests/helpers/class-wc-retailcrm-test-case-helper.php';
require $plugin_dir . 'tests/helpers/class-wc-retailcrm-log-handler-stdout.php';
if (!empty($_output_logs_to_stdout) && $_output_logs_to_stdout == '1') {
WC_Retailcrm_Logger::setAdditionalHandlers(array(new WC_Retailcrm_Log_Handler_Stdout()));
}

View File

@ -0,0 +1,88 @@
<?php
/**
* PHP version 5.3
*
* @category Integration
* @author RetailCRM <integration@retailcrm.ru>
* @license http://retailcrm.ru Proprietary
* @link http://retailcrm.ru
* @see http://help.retailcrm.ru
*/
class WC_Retailcrm_Customer_Switcher_State_Test extends WC_Retailcrm_Test_Case_Helper
{
public function test_feasible()
{
$state = new WC_Retailcrm_Customer_Switcher_State();
$this->assertFalse($state->feasible());
$state->setNewCustomer(array())
->setNewContact(array())
->setNewCompanyName('');
$this->assertFalse($state->feasible());
$state->setNewCustomer(array('id' => 1));
$this->assertTrue($state->feasible());
$state->setNewCustomer(array())
->setNewContact(array('id' => 1));
$this->assertTrue($state->feasible());
$state->setNewCustomer(array())
->setNewContact(array())
->setNewCompanyName('test');
$this->assertTrue($state->feasible());
$state->setNewCustomer(array())
->setNewContact(array())
->setNewCompany(array('name' => 'test'));
$this->assertTrue($state->feasible());
$state->setNewCustomer(array())
->setNewContact(array())
->setNewCompanyName('');
$this->assertFalse($state->feasible());
}
/**
* @expectedException \InvalidArgumentException
*/
public function test_validate_empty()
{
$state = new WC_Retailcrm_Customer_Switcher_State();
$state->validate();
}
/**
* @expectedException \InvalidArgumentException
*/
public function test_validate_order()
{
$state = new WC_Retailcrm_Customer_Switcher_State();
$state->setWcOrder(new WC_Order())
->validate();
}
/**
* @expectedException \InvalidArgumentException
*/
public function test_validate_customer_and_contact_set()
{
$state = new WC_Retailcrm_Customer_Switcher_State();
$state->setWcOrder(new WC_Order())
->setNewCustomer(array('id' => 1))
->setNewContact(array('id' => 1))
->validate();
}
/**
* @@doesNotPerformAssertions
*/
public function test_validate_ok()
{
$state = new WC_Retailcrm_Customer_Switcher_State();
$state->setWcOrder(new WC_Order())
->setNewCustomer(array('id' => 1))
->validate();
}
}

View File

@ -0,0 +1,137 @@
<?php
/**
* PHP version 5.3
*
* @category Integration
* @author RetailCRM <integration@retailcrm.ru>
* @license http://retailcrm.ru Proprietary
* @link http://retailcrm.ru
* @see http://help.retailcrm.ru
*/
class WC_Retailcrm_WC_Customer_Builder_Test extends WC_Retailcrm_Test_Case_Helper
{
/**
* @expectedException \RuntimeException
*/
public function test_empty()
{
$builder = new WC_Retailcrm_WC_Customer_Builder();
$builder->build();
}
/**
* @expectedException \RuntimeException
*/
public function test_empty_array()
{
$builder = new WC_Retailcrm_WC_Customer_Builder();
$builder->setData(array())->build();
}
/**
* @expectedException \RuntimeException
*/
public function test_not_array()
{
$builder = new WC_Retailcrm_WC_Customer_Builder();
$builder->setData(new stdClass())->build();
}
/**
* @dataProvider customerData
*
* @param array $customerData
*/
public function test_build($customerData)
{
$builder = new WC_Retailcrm_WC_Customer_Builder();
$wcCustomer = $builder->setData($customerData)->build()->getResult();
$this->assertInstanceOf('\WC_Customer', $wcCustomer);
if (isset($customerData['firstName'])) {
$this->assertEquals($customerData['firstName'], $wcCustomer->get_first_name());
}
if (isset($customerData['lastName'])) {
$this->assertEquals($customerData['lastName'], $wcCustomer->get_last_name());
}
if (isset($customerData['email'])) {
$this->assertEquals($customerData['email'], $wcCustomer->get_billing_email());
}
if (isset($customerData['phones']) && count($customerData['phones']) > 0) {
$this->assertEquals($customerData['phones'][0]['number'], $wcCustomer->get_billing_phone());
}
if (isset($customerData['address']) && !empty($customerData['address'])) {
$address = $customerData['address'];
if (isset($address['region'])) {
$this->assertEquals($address['region'], $wcCustomer->get_billing_state());
}
if (isset($address['index'])) {
$this->assertEquals($address['index'], $wcCustomer->get_billing_postcode());
}
if (isset($address['country'])) {
$this->assertEquals($address['country'], $wcCustomer->get_billing_country());
}
if (isset($address['city'])) {
$this->assertEquals($address['city'], $wcCustomer->get_billing_city());
}
}
}
public function customerData()
{
return array(
array(
'customer' => array(
'type' => 'customer',
'id' => 4228,
'externalId' => '2',
)
),
array(
'customer' => array(
'type' => 'customer',
'id' => 4228,
'externalId' => '2',
'isContact' => false,
'createdAt' => '2020-06-01 15:31:46',
'managerId' => 27,
'vip' => false,
'bad' => false,
'site' => 'bitrix-test',
'contragent' => array(
'contragentType' => 'individual',
),
'tags' => array(),
'marginSumm' => 9412,
'totalSumm' => 9412,
'averageSumm' => 9412,
'ordersCount' => 1,
'costSumm' => 0,
'customFields' => array(),
'personalDiscount' => 0,
'cumulativeDiscount' => 0,
'address' => array(
'id' => 3132,
'text' => 'ул. Пушкина дом Колотушкина',
),
'segments' => array(),
'firstName' => 'tester001',
'lastName' => 'tester001',
'email' => 'tester001@example.com',
'emailMarketingUnsubscribedAt' => '2020-06-01 15:34:23',
'phones' => array(array('number' => '2354708915097'))
)
)
);
}
}

View File

@ -0,0 +1,117 @@
<?php
if (!defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles log entries by writing to a stdout
*
* @class WC_Retailcrm_Log_Handler_Stdout
*/
class WC_Retailcrm_Log_Handler_Stdout extends WC_Log_Handler
{
/**
* @var array
*/
protected $cached_logs = array();
/**
* Constructor for the logger.
*/
public function __construct()
{
add_action('plugins_loaded', array($this, 'write_cached_logs'));
}
/**
* @param int $timestamp
* @param string $level
* @param string $message
* @param array $context
*
* @return bool
*/
public function handle( $timestamp, $level, $message, $context )
{
if (isset( $context['source'] ) && $context['source']) {
$handle = $context['source'];
} else {
$handle = 'log';
}
$entry = self::format_entry($timestamp, $level, $message, $context);
return $this->add($entry, $handle);
}
/**
* @param int $timestamp
* @param string $level
* @param string $message
* @param array $context
*
* @return string
*/
protected static function format_entry($timestamp, $level, $message, $context)
{
if (isset($context['_legacy'] ) && true === $context['_legacy']) {
if (isset($context['source']) && $context['source']) {
$handle = $context['source'];
} else {
$handle = 'log';
}
$message = apply_filters('woocommerce_logger_add_message', $message, $handle);
$time = date_i18n('m-d-Y @ H:i:s');
$entry = sprintf('%s - %s', $time, $message);
} else {
$entry = parent::format_entry( $timestamp, $level, $message, $context );
}
return $entry;
}
/**
* @param string $entry Log entry text.
* @param string $handle Log entry handle.
*
* @return bool True if write was successful.
*/
protected function add($entry, $handle)
{
$result = false;
if (is_resource(STDOUT)) {
$result = fwrite(STDOUT, $entry . PHP_EOL);
} else {
$this->cache_log($entry, $handle);
}
return false !== $result;
}
/**
* Cache log to write later.
*
* @param string $entry Log entry text.
* @param string $handle Log entry handle.
*/
protected function cache_log($entry, $handle)
{
$this->cached_logs[] = array(
'entry' => $entry,
'handle' => $handle,
);
}
/**
* Write cached logs.
*/
public function write_cached_logs()
{
foreach ($this->cached_logs as $log) {
$this->add($log['entry'], $log['handle']);
}
}
}

View File

@ -6,20 +6,19 @@
class WC_Retailcrm_Test_Case_Helper extends WC_Unit_Test_Case class WC_Retailcrm_Test_Case_Helper extends WC_Unit_Test_Case
{ {
/** /**
* @param string $apiVersion
*
* @return array * @return array
*/ */
protected function setOptions($apiVersion = 'v5') protected function setOptions()
{ {
$options = array( $options = array(
'api_url' => 'https://example.retailcrm.ru', 'api_url' => 'https://example.retailcrm.ru',
'api_key' => 'dhsHJGYdjkHHJKJSGjhasjhgajsgJGHsg', 'api_key' => 'dhsHJGYdjkHHJKJSGjhasjhgajsgJGHsg',
'api_version' => $apiVersion, 'api_version' => 'v5',
'p_draft' => 'no', 'p_draft' => 'no',
'p_pending' => 'no', 'p_pending' => 'no',
'p_private' => 'no', 'p_private' => 'no',
'p_publish' => 'no', 'p_publish' => 'no',
'send_payment_amount' => 'yes',
'order_methods' => '', 'order_methods' => '',
'flat_rate_shipping' => 'delivery', 'flat_rate_shipping' => 'delivery',
'free_shipping' => 'delivery2', 'free_shipping' => 'delivery2',
@ -48,6 +47,43 @@ class WC_Retailcrm_Test_Case_Helper extends WC_Unit_Test_Case
return $options; return $options;
} }
/**
* Removes all data from the DB.
*/
protected function deleteAllData()
{
if (function_exists('_delete_all_data')) {
_delete_all_data();
} else {
global $wpdb;
foreach ( array(
$wpdb->posts,
$wpdb->postmeta,
$wpdb->comments,
$wpdb->commentmeta,
$wpdb->term_relationships,
$wpdb->termmeta,
) as $table ) {
//phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$wpdb->query( "DELETE FROM {$table}" );
}
foreach ( array(
$wpdb->terms,
$wpdb->term_taxonomy,
) as $table ) {
//phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$wpdb->query( "DELETE FROM {$table} WHERE term_id != 1" );
}
$wpdb->query( "UPDATE {$wpdb->term_taxonomy} SET count = 0" );
$wpdb->query( "DELETE FROM {$wpdb->users} WHERE ID != 1" );
$wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE user_id != 1" );
}
}
/** /**
* @return array * @return array
*/ */

View File

@ -0,0 +1,51 @@
<?php
/**
* PHP version 5.3
*
* @category Integration
* @author RetailCRM <integration@retailcrm.ru>
* @license http://retailcrm.ru Proprietary
* @link http://retailcrm.ru
* @see http://help.retailcrm.ru
*/
class WC_Retailcrm_Customer_Switcher_Result_Test extends WC_Retailcrm_Test_Case_Helper
{
/**
* @expectedException \InvalidArgumentException
*/
public function test_invalid_both()
{
new WC_Retailcrm_Customer_Switcher_Result(new stdClass(), new stdClass());
}
/**
* @expectedException \InvalidArgumentException
*/
public function test_invalid_customer()
{
new WC_Retailcrm_Customer_Switcher_Result(new stdClass(), new WC_Order());
}
/**
* @expectedException \InvalidArgumentException
*/
public function test_invalid_order()
{
new WC_Retailcrm_Customer_Switcher_Result(new WC_Customer(), new stdClass());
}
public function test_valid()
{
$result = new WC_Retailcrm_Customer_Switcher_Result(new WC_Customer(), new WC_Order());
$this->assertInstanceOf('\WC_Customer', $result->getWcCustomer());
$this->assertInstanceOf('\WC_Order', $result->getWcOrder());
}
public function test_valid_no_customer()
{
$result = new WC_Retailcrm_Customer_Switcher_Result(null, new WC_Order());
$this->assertEmpty($result->getWcCustomer())
; $this->assertInstanceOf('\WC_Order', $result->getWcOrder());
}
}

View File

@ -26,8 +26,11 @@ class WC_Retailcrm_Order_Address_Test extends WC_Retailcrm_Test_Case_Helper
public function test_build() public function test_build()
{ {
$order_address = new WC_Retailcrm_Order_Address; $order_address = new WC_Retailcrm_Order_Address();
$data = $order_address->build($this->order)->get_data(); $data = $order_address
->setWCAddressType(WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_BILLING)
->build($this->order)
->get_data();
$this->assertArrayHasKey('index', $data); $this->assertArrayHasKey('index', $data);
$this->assertArrayHasKey('city', $data); $this->assertArrayHasKey('city', $data);

View File

@ -19,6 +19,7 @@ class WC_Retailcrm_Order_Payment_Test extends WC_Retailcrm_Test_Case_Helper
parent::setUp(); parent::setUp();
$this->order = WC_Helper_Order::create_order(); $this->order = WC_Helper_Order::create_order();
$this->setOptions();
} }
/** /**
@ -28,11 +29,18 @@ class WC_Retailcrm_Order_Payment_Test extends WC_Retailcrm_Test_Case_Helper
*/ */
public function test_build($externalId) public function test_build($externalId)
{ {
$order_payment = new WC_Retailcrm_Order_Payment($this->getOptions()); $settings = $this->getOptions();
$settings['send_payment_amount'] = 'no';
$order_payment = new WC_Retailcrm_Order_Payment($settings);
$data = $order_payment->build($this->order, $externalId)->get_data(); $data = $order_payment->build($this->order, $externalId)->get_data();
$this->assertNotEmpty($data);
if (!empty($externalId)) {
$this->assertArrayHasKey('externalId', $data); $this->assertArrayHasKey('externalId', $data);
}
$this->assertArrayHasKey('type', $data); $this->assertArrayHasKey('type', $data);
$this->assertArrayNotHasKey('amount', $data); $this->assertArrayNotHasKey('amount', $data);
$this->assertArrayHasKey('order', $data); $this->assertArrayHasKey('order', $data);
@ -51,7 +59,12 @@ class WC_Retailcrm_Order_Payment_Test extends WC_Retailcrm_Test_Case_Helper
$data = $order_payment->build($this->order, $externalId)->get_data(); $data = $order_payment->build($this->order, $externalId)->get_data();
$this->assertNotEmpty($data);
if (!empty($externalId)) {
$this->assertArrayHasKey('externalId', $data); $this->assertArrayHasKey('externalId', $data);
}
$this->assertArrayHasKey('type', $data); $this->assertArrayHasKey('type', $data);
$this->assertArrayHasKey('amount', $data); $this->assertArrayHasKey('amount', $data);
$this->assertArrayHasKey('order', $data); $this->assertArrayHasKey('order', $data);

View File

@ -45,7 +45,6 @@ class WC_Retailcrm_Base_Test extends WC_Retailcrm_Test_Case_Helper
$this->assertInternalType('array', $this->unit->form_fields); $this->assertInternalType('array', $this->unit->form_fields);
$this->assertArrayHasKey('api_url', $this->unit->form_fields); $this->assertArrayHasKey('api_url', $this->unit->form_fields);
$this->assertArrayHasKey('api_key', $this->unit->form_fields); $this->assertArrayHasKey('api_key', $this->unit->form_fields);
$this->assertArrayHasKey('api_version', $this->unit->form_fields);
foreach (get_post_statuses() as $key => $status) { foreach (get_post_statuses() as $key => $status) {
$this->assertArrayHasKey('p_' . $key, $this->unit->form_fields); $this->assertArrayHasKey('p_' . $key, $this->unit->form_fields);

View File

@ -38,6 +38,8 @@ class WC_Retailcrm_Customers_Test extends WC_Retailcrm_Test_Case_Helper
->willReturn($this->responseMock); ->willReturn($this->responseMock);
$this->customer = new WC_Customer(); $this->customer = new WC_Customer();
$this->customer->set_first_name('Tester');
$this->customer->set_last_name('Tester');
$this->customer->set_email(uniqid(md5(date('Y-m-d H:i:s'))) . '@mail.com'); $this->customer->set_email(uniqid(md5(date('Y-m-d H:i:s'))) . '@mail.com');
$this->customer->set_billing_email($this->customer->get_email()); $this->customer->set_billing_email($this->customer->get_email());
$this->customer->set_password('password'); $this->customer->set_password('password');
@ -124,7 +126,9 @@ class WC_Retailcrm_Customers_Test extends WC_Retailcrm_Test_Case_Helper
/** /**
* @param $retailcrm * @param $retailcrm
*
* @dataProvider dataProviderApiClient * @dataProvider dataProviderApiClient
* @throws \Exception
*/ */
public function test_create_customer_empty_response($retailcrm) public function test_create_customer_empty_response($retailcrm)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -28,12 +28,11 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
/** /**
* @param $retailcrm * @param $retailcrm
* @param $apiVersion
* @dataProvider dataProviderRetailcrm * @dataProvider dataProviderRetailcrm
*/ */
public function test_order_upload($retailcrm, $apiVersion) public function test_order_upload($retailcrm)
{ {
$this->options = $this->setOptions($apiVersion); $this->options = $this->setOptions();
$retailcrm_orders = $this->getRetailcrmOrders($retailcrm); $retailcrm_orders = $this->getRetailcrmOrders($retailcrm);
$upload_orders = $retailcrm_orders->ordersUpload(); $upload_orders = $retailcrm_orders->ordersUpload();
@ -46,10 +45,9 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
/** /**
* @param $retailcrm * @param $retailcrm
* @param $apiVersion
* @dataProvider dataProviderRetailcrm * @dataProvider dataProviderRetailcrm
*/ */
public function test_order_create($retailcrm, $apiVersion) public function test_order_create($retailcrm)
{ {
if ($retailcrm) { if ($retailcrm) {
$responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper') $responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
@ -82,7 +80,7 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
} }
$this->createTestOrder(); $this->createTestOrder();
$this->options = $this->setOptions($apiVersion); $this->options = $this->setOptions();
$retailcrm_orders = $this->getRetailcrmOrders($retailcrm); $retailcrm_orders = $this->getRetailcrmOrders($retailcrm);
$order = $retailcrm_orders->orderCreate($this->order->get_id()); $order = $retailcrm_orders->orderCreate($this->order->get_id());
$order_send = $retailcrm_orders->getOrder(); $order_send = $retailcrm_orders->getOrder();
@ -114,16 +112,11 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
$this->assertEquals('WooCity', $order_send['delivery']['address']['city']); $this->assertEquals('WooCity', $order_send['delivery']['address']['city']);
$this->assertEquals('delivery', $order_send['delivery']['code']); $this->assertEquals('delivery', $order_send['delivery']['code']);
if ($apiVersion == 'v4') {
$this->assertArrayHasKey('paymentType', $order_send);
$this->assertEquals('payment1', $order_send['paymentType']);
} elseif ($apiVersion == 'v5') {
$this->assertArrayHasKey('payments', $order_send); $this->assertArrayHasKey('payments', $order_send);
$this->assertInternalType('array', $order_send['payments']); $this->assertInternalType('array', $order_send['payments']);
$this->assertArrayHasKey('type', $order_send['payments'][0]); $this->assertArrayHasKey('type', $order_send['payments'][0]);
$this->assertArrayHasKey('externalId', $order_send['payments'][0]); $this->assertArrayHasKey('externalId', $order_send['payments'][0]);
$this->assertEquals('payment1', $order_send['payments'][0]['type']); $this->assertEquals('payment1', $order_send['payments'][0]['type']);
}
} else { } else {
$this->assertEquals(null, $order); $this->assertEquals(null, $order);
} }
@ -132,15 +125,15 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
/** /**
* @param $isSuccessful * @param $isSuccessful
* @param $retailcrm * @param $retailcrm
* @param $apiVersion
* @dataProvider dataProviderUpdateOrder * @dataProvider dataProviderUpdateOrder
*/ */
public function test_update_order($isSuccessful, $retailcrm, $apiVersion) public function test_update_order($isSuccessful, $retailcrm)
{ {
$this->createTestOrder(); $this->createTestOrder();
$this->options = $this->setOptions($apiVersion); $this->options = $this->setOptions();
if ($retailcrm && $apiVersion == 'v5') { if ($retailcrm) {
$responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper') $responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
->disableOriginalConstructor() ->disableOriginalConstructor()
->setMethods(array( ->setMethods(array(
@ -200,10 +193,6 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
$this->assertEquals('WooCity', $order_send['delivery']['address']['city']); $this->assertEquals('WooCity', $order_send['delivery']['address']['city']);
$this->assertEquals('delivery', $order_send['delivery']['code']); $this->assertEquals('delivery', $order_send['delivery']['code']);
if ($apiVersion == 'v4') {
$this->assertArrayHasKey('paymentType', $order_send);
$this->assertEquals('payment1', $order_send['paymentType']);
} elseif ($apiVersion == 'v5') {
$payment = $retailcrm_orders->getPayment(); $payment = $retailcrm_orders->getPayment();
$this->assertInternalType('array', $payment); $this->assertInternalType('array', $payment);
@ -219,7 +208,6 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
$this->assertArrayNotHasKey('amount', $payment); $this->assertArrayNotHasKey('amount', $payment);
} }
} }
}
} else { } else {
$this->assertEquals(null, $order); $this->assertEquals(null, $order);
} }
@ -232,43 +220,19 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
return array( return array(
array( array(
'is_successful' => true, 'is_successful' => true,
'retailcrm' => $this->apiMock, 'retailcrm' => $this->apiMock
'api_version' => 'v5'
), ),
array( array(
'is_successful' => true, 'is_successful' => true,
'retailcrm' => false, 'retailcrm' => false
'api_version' => 'v5'
), ),
array( array(
'is_successful' => false, 'is_successful' => false,
'retailcrm' => false, 'retailcrm' => false
'api_version' => 'v5'
), ),
array( array(
'is_successful' => false, 'is_successful' => false,
'retailcrm' => $this->apiMock, 'retailcrm' => $this->apiMock
'api_version' => 'v5'
),
array(
'is_successful' => false,
'retailcrm' => $this->apiMock,
'api_version' => 'v4'
),
array(
'is_successful' => true,
'retailcrm' => $this->apiMock,
'api_version' => 'v4'
),
array(
'is_successful' => false,
'retailcrm' => false,
'api_version' => 'v4'
),
array(
'is_successful' => true,
'retailcrm' => false,
'api_version' => 'v4'
) )
); );
} }
@ -279,20 +243,10 @@ class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
return array( return array(
array( array(
'retailcrm' => $this->apiMock, 'retailcrm' => $this->apiMock
'api_version' => 'v4'
), ),
array( array(
'retailcrm' => false, 'retailcrm' => false
'api_version' => 'v4'
),
array(
'retailcrm' => $this->apiMock,
'api_version' => 'v5'
),
array(
'retailcrm' => false,
'api_version' => 'v5'
) )
); );
} }

View File

@ -26,14 +26,13 @@ class WC_Retailcrm_Plugin_Test extends WC_Retailcrm_Test_Case_Helper
/** /**
* @param $retailcrm * @param $retailcrm
* @param $response * @param $response
* @param $apiVersion
* *
* @dataProvider dataProviderIntegrationModule * @dataProvider dataProviderIntegrationModule
*/ */
public function test_integration_module($retailcrm,$response, $apiVersion) public function test_integration_module($retailcrm, $response)
{ {
$client_id = uniqid(); $client_id = uniqid();
$result = WC_Retailcrm_Plugin::integration_module($retailcrm, $client_id, $apiVersion); $result = WC_Retailcrm_Plugin::integration_module($retailcrm, $client_id);
if (!$retailcrm || $response['success'] == false) { if (!$retailcrm || $response['success'] == false) {
$this->assertEquals(false, $result); $this->assertEquals(false, $result);
@ -58,15 +57,6 @@ class WC_Retailcrm_Plugin_Test extends WC_Retailcrm_Test_Case_Helper
private function getResponseData() private function getResponseData()
{ {
return array( return array(
'v4' => array(
"true" => array(
"success" => true
),
"false" => array(
"success" => false
)
),
'v5' => array(
"true" => array( "true" => array(
"success" => true "success" => true
), ),
@ -74,71 +64,35 @@ class WC_Retailcrm_Plugin_Test extends WC_Retailcrm_Test_Case_Helper
"success" => false, "success" => false,
"errorMsg" => "Forbidden" "errorMsg" => "Forbidden"
) )
)
); );
} }
public function dataProviderIntegrationModule() public function dataProviderIntegrationModule()
{ {
$this->setUp(); $this->setUp();
$responseData = $this->getResponseData();
return array( return array(
array( array(
'retailcrm' => $this->getApiMock( 'retailcrm' => $this->getApiMock($responseData['true']),
'v4', 'response' => $responseData['true']
$this->getResponseData['v4']['true']
),
'response' => $this->getResponseData['v4']['true'],
'apiVersion' => 'v4'
), ),
array( array(
'retailcrm' => false, 'retailcrm' => false,
'response' => $this->getResponseData['v4']['true'], 'response' => $responseData['true']
'apiVersion' => 'v4'
), ),
array( array(
'retailcrm' => $this->getApiMock( 'retailcrm' => $this->getApiMock($responseData['false']),
'v4', 'response' => $responseData['false']
$this->getResponseData['v4']['false']
),
'response' => $this->getResponseData['v4']['false'],
'apiVersion' => 'v4'
), ),
array( array(
'retailcrm' => false, 'retailcrm' => false,
'response' => $this->getResponseData['v4']['false'], 'response' => $responseData['false']
'apiVersion' => 'v4'
),
array(
'retailcrm' => $this->getApiMock(
'v5',
$this->getResponseData['v5']['true']
),
'response' => $this->getResponseData['v5']['true'],
'apiVersion' => 'v5'
),
array(
'retailcrm' => false,
'response' => $this->getResponseData['v5']['true'],
'apiVersion' => 'v5'
),
array(
'retailcrm' => $this->getApiMock(
'v5',
$this->getResponseData['v5']['false']
),
'response' => $this->getResponseData['v5']['false'],
'apiVersion' => 'v5'
),
array(
'retailcrm' => false,
'response' => $this->getResponseData['v5']['false'],
'apiVersion' => 'v5'
) )
); );
} }
private function getApiMock($apiVersion, $response) private function getApiMock($response)
{ {
$responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper') $responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
->disableOriginalConstructor() ->disableOriginalConstructor()
@ -159,18 +113,6 @@ class WC_Retailcrm_Plugin_Test extends WC_Retailcrm_Test_Case_Helper
$responseMock->setResponse($response); $responseMock->setResponse($response);
if ($apiVersion == 'v4') {
$apiMock = $this->getMockBuilder('\WC_Retailcrm_Proxy')
->disableOriginalConstructor()
->setMethods(array(
'marketplaceSettingsEdit'
))
->getMock();
$apiMock->expects($this->any())
->method('marketplaceSettingsEdit')
->willReturn($responseMock);
} else {
$apiMock = $this->getMockBuilder('\WC_Retailcrm_Proxy') $apiMock = $this->getMockBuilder('\WC_Retailcrm_Proxy')
->disableOriginalConstructor() ->disableOriginalConstructor()
->setMethods(array( ->setMethods(array(
@ -181,7 +123,6 @@ class WC_Retailcrm_Plugin_Test extends WC_Retailcrm_Test_Case_Helper
$apiMock->expects($this->any()) $apiMock->expects($this->any())
->method('integrationModulesEdit') ->method('integrationModulesEdit')
->willReturn($responseMock); ->willReturn($responseMock);
}
return $apiMock; return $apiMock;
} }