1
0
mirror of synced 2025-01-30 14:51:42 +03:00
* Tests
* Travis
* Deployment script
This commit is contained in:
Akolzin Dmitry 2018-04-27 11:19:02 +03:00 committed by Alex Lushpai
parent 7ad9ae7886
commit b5b6419ca4
45 changed files with 4187 additions and 1458 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
/nbproject/private/
/nbproject/private/
/vendor/

36
.travis.yml Normal file
View File

@ -0,0 +1,36 @@
language: php
sudo: false
php:
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
env:
- WP_VERSION=latest WP_MULTISITE=0
matrix:
fast_finish: true
include:
- php: 5.3
dist: precise
- php: 7.2
env: WP_VERSION=latest WP_MULTISITE=0 RUN_PHPCS=1
before_script:
- bash tests/bin/install.sh wc_retailcrm_test root '' localhost $WP_VERSION
script:
- bash tests/bin/script.sh
deploy:
skip_cleanup: true
provider: script
script: make
on:
php: 7.1
branch: master
condition: "$DEPLOY = true"

View File

@ -1,27 +1,32 @@
## 2018-03-22 v.2.1.4
## 2018-04-26 v3.0.0
* Добавлены тесты
* Произведен рефакторинг кода
* Добавлены хуки
## 2018-03-22 v2.1.4
* Исправлена ошибка при активированном модуле без настроек
* Добавлен фильтр при формировании массива заказа
* Исправлена генерация icml с неполной картинкой товара
## 2018-03-22 v.2.1.3
## 2018-03-22 v2.1.3
* Исправлена ошибка на php5.3
## 2018-03-21 v.2.1.2
## 2018-03-21 v2.1.2
* Добавлена локализация плагина
* Добавлена интеграция с UA
## 2018-03-12 v.2.1.1
## 2018-03-12 v2.1.1
* Исправлена ошибка редактирования информации о клиенте
## 2018-02-26 v.2.1.0
## 2018-02-26 v2.1.0
* Переработана механика генерации icml каталога товаров
* В icml каталог добавлена выгрузка налоговой ставки
* Исправлен пересчет итогов после изменения количества товара в RetailCRM
## 2018-02-19 v.2.0.6
## 2018-02-19 v2.0.6
* Исправлено возникновение Warning на PHP 7.2 при генерации каталога товаров
* Добавлена настройка выгрузки заказов из RetailCRM с определенными способами оформления
* Выгрузка изменений из RetailCRM осуществляется по sinceId
## 2018-02-02 v.2.0.5
## 2018-02-02 v2.0.5
* Исправлен неверный подсчет скидки на товары

19
Makefile Normal file
View File

@ -0,0 +1,19 @@
FILE = $(TRAVIS_BUILD_DIR)/VERSION
VERSION = `cat $(FILE)`
all: svn_clone prepare svn_commit remove_dir
svn_clone:
mkdir /tmp/svn_plugin_dir
svn co $(SVNREPOURL) /tmp/svn_plugin_dir --username $(USERNAME) --password $(PASSWORD) --no-auth-cache
prepare: /tmp/svn_plugin_dir
svn copy /tmp/svn_plugin_dir/trunk /tmp/svn_plugin_dir/tags/$(VERSION) --username $(USERNAME) --password $(PASSWORD) --no-auth-cache
rm -rf /tmp/svn_plugin_dir/trunk/*
cp -R $(TRAVIS_BUILD_DIR)/src/* /tmp/svn_plugin_dir/trunk
svn_commit: /tmp/svn_plugin_dir/tags
svn ci /tmp/svn_plugin_dir -m $(VERSION) --username $(USERNAME) --password $(PASSWORD) --no-auth-cache
remove_dir:
rm -rf /tmp/svn_plugin_dir

1
VERSION Normal file
View File

@ -0,0 +1 @@
3.0.0

16
composer.json Normal file
View File

@ -0,0 +1,16 @@
{
"name": "retailcrm/woocommerce-retailcrm",
"description": "Integration plugin for WooCommerce & RetailCRM",
"type": "wordpress-plugin",
"authors": [
{
"name": "RetailDriver LLC",
"email": "integration@retailcrm.ru"
}
],
"minimum-stability": "dev",
"require": {},
"require-dev": {
"phpunit/phpunit": "6.*"
}
}

1481
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

29
phpunit.xml.dist Normal file
View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="tests/phpunit/bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
verbose="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="true"
>
<testsuites>
<testsuite name="Retailcrm WooCommerce Test Suite">
<directory suffix=".php">tests/phpunit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src/include</directory>
<exclude>
<directory suffix=".php">src/include/api</directory>
<file>src/retailcrm.php</file>
<file>src/uninstall.php</file>
</exclude>
</whitelist>
</filter>
</phpunit>

View File

@ -0,0 +1,803 @@
<?php
/**
* RetailCRM Integration.
*
* @package WC_Retailcrm_Base
* @category Integration
* @author RetailCRM
*/
if (!class_exists('WC_Retailcrm_Base')) {
/**
* Class WC_Retailcrm_Base
*/
class WC_Retailcrm_Base extends WC_Integration {
public static $option_key;
protected $api_url;
protected $api_key;
private $apiClient;
/**
* Init and hook in the integration.
* @param $retailcrm (default = false)
*/
public function __construct($retailcrm = false) {
//global $woocommerce;
if ( ! class_exists( 'WC_Retailcrm_Proxy' ) ) {
include_once( __DIR__ . '/api/class-wc-retailcrm-proxy.php' );
}
$this->id = 'integration-retailcrm';
$this->method_title = __('RetailCRM', 'retailcrm');
$this->method_description = __('Integration with eComlogic managament system.', 'retailcrm');
if ($retailcrm === false) {
$this->apiClient = $this->getApiClient();
} else {
$this->apiClient = $retailcrm;
}
self::$option_key = $this->get_option_key();
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Actions.
add_action('woocommerce_update_options_integration_' . $this->id, array($this, 'process_admin_options'));
add_filter('cron_schedules', array($this, 'filter_cron_schedules'), 10, 1);
add_action('woocommerce_checkout_order_processed', array($this, 'retailcrm_process_order'), 10, 1);
add_action('retailcrm_history', array($this, 'retailcrm_history_get'));
add_action('retailcrm_icml', array($this, 'generate_icml'));
add_action('retailcrm_inventories', array($this, 'load_stocks'));
add_action('init', array($this, 'register_load_inventories'));
add_action('init', array($this, 'register_icml_generation'));
add_action('init', array($this, 'register_retailcrm_history'));
add_action('wp_ajax_do_upload', array($this, 'upload_to_crm'));
add_action('wp_ajax_generate_icml', array($this, 'generate_icml'));
add_action('admin_print_footer_scripts', array($this, 'ajax_upload'), 99);
add_action('admin_print_footer_scripts', array($this, 'ajax_generate_icml'), 99);
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_order', array($this, 'update_order'), 11, 1);
add_action('wp_print_scripts', array($this, 'initialize_analytics'), 98);
add_action('wp_print_footer_scripts', array($this, 'send_analytics'), 99);
}
/**
* Check custom file
*
* @param string $file
*
* @return string
*/
public static function checkCustomFile($file) {
if (file_exists( WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-' . $file . '.php' )) {
return WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-' . $file . '.php';
}
return 'class-wc-retailcrm-' . $file . '.php';
}
public function filter_cron_schedules($schedules) {
return array_merge(
$schedules,
array(
'five_minutes' => array(
'interval' => 300, // seconds
'display' => __('Every 5 minutes')
),
'three_hours' => array(
'interval' => 10800, // seconds
'display' => __('Every 3 hours')
),
'fiveteen_minutes' => array(
'interval' => 900, // seconds
'display' => __('Every 15 minutes')
)
)
);
}
public function generate_icml() {
if (!class_exists('WC_Retailcrm_Icml')) {
require_once (self::checkCustomFile('icml'));
}
$retailcrm_icml = new WC_Retailcrm_Icml();
$retailcrm_icml->generate();
}
/**
* Get history
*/
public function retailcrm_history_get() {
if (!class_exists('WC_Retailcrm_History')) {
include_once(self::checkCustomFile('history'));
}
$retailcrm_history = new WC_Retailcrm_History($this->apiClient);
$retailcrm_history->getHistory();
}
/**
* @param int $order_id
*/
public function retailcrm_process_order($order_id) {
if (!class_exists('WC_Retailcrm_Orders')) {
include_once(self::checkCustomFile('orders'));
}
$retailcm_order = new WC_Retailcrm_Orders($this->apiClient);
$retailcm_order->orderCreate($order_id);
}
/**
* Load stock from retailCRM
*/
public function load_stocks() {
if (!class_exists('WC_Retailcrm_Inventories')) {
include_once(self::checkCustomFile('inventories'));
}
$inventories = new WC_Retailcrm_Inventories($this->apiClient);
$inventories->updateQuantity();
}
public function register_load_inventories() {
if ( !wp_next_scheduled( 'retailcrm_inventories' ) ) {
// Schedule the event
wp_schedule_event( time(), 'fiveteen_minutes', 'retailcrm_inventories' );
}
}
public function register_icml_generation() {
// Make sure this event hasn't been scheduled
if ( !wp_next_scheduled( 'retailcrm_icml' ) ) {
// Schedule the event
wp_schedule_event( time(), 'three_hours', 'retailcrm_icml' );
}
}
public function register_retailcrm_history() {
// Make sure this event hasn't been scheduled
if ( !wp_next_scheduled( 'retailcrm_history' ) ) {
// Schedule the event
wp_schedule_event( time(), 'five_minutes', 'retailcrm_history' );
}
}
/**
* Upload archive customers and order to retailCRM
*/
public function upload_to_crm() {
if (!class_exists('WC_Retailcrm_Orders')) {
include_once(self::checkCustomFile('orders'));
}
if (!class_exists('WC_Retailcrm_Customers')) {
include_once(self::checkCustomFile('customers'));
}
$options = array_filter(get_option(self::$option_key));
$retailcrm_customers = new WC_Retailcrm_Customers($this->apiClient);
$retailcrm_orders = new WC_Retailcrm_Orders($this->apiClient);
$retailcrm_customers->customersUpload();
$retailcrm_orders->ordersUpload();
$options['uploads'] = 'yes';
update_option('woocommerce_integration-retailcrm_settings', $options);
}
public function ajax_upload() {
$ajax_url = admin_url('admin-ajax.php');
?>
<script type="text/javascript" >
jQuery('#uploads-retailcrm').bind('click', function() {
jQuery.ajax({
type: "POST",
url: '<?php echo $ajax_url; ?>?action=do_upload',
success: function (response) {
alert('<?php echo __('Customers and orders were unloaded', 'retailcrm'); ?>');
console.log('AJAX response : ',response);
}
});
});
</script>
<?php
}
public function ajax_generate_icml() {
$ajax_url = admin_url('admin-ajax.php');
?>
<script type="text/javascript" >
jQuery('#icml-retailcrm').bind('click', function() {
jQuery.ajax({
type: "POST",
url: '<?php echo $ajax_url; ?>?action=generate_icml',
success: function (response) {
alert('<?php echo __('Catalog were generated', 'retailcrm'); ?>');
console.log('AJAX response : ', response);
}
});
});
</script>
<?php
}
/**
* Create customer in retailCRM
* @param int $customer_id
*/
public function create_customer($customer_id) {
if (!class_exists( 'WC_Retailcrm_Customers')) {
include_once(self::checkCustomFile('customers'));
}
$retailcrm_customer = new WC_Retailcrm_Customers($this->apiClient);
$retailcrm_customer->createCustomer($customer_id);
}
/**
* Edit customer in retailCRM
* @param int $customer_id
*/
public function update_customer($customer_id) {
if (!class_exists('WC_Retailcrm_Customers')) {
include_once(self::checkCustomFile('customers'));
}
$retailcrm_customer = new WC_Retailcrm_Customers($this->apiClient);
$retailcrm_customer->updateCustomer($customer_id);
}
/**
* Edit order in retailCRM
* @param int $order_id
*/
public function update_order($order_id) {
if (!class_exists('WC_Retailcrm_Orders')) {
include_once(self::checkCustomFile('orders'));
}
$retailcrm_order = new WC_Retailcrm_Orders($this->apiClient);
$retailcrm_order->updateOrder($order_id);
}
/**
* Init google analytics code
*/
public function initialize_analytics() {
if (!class_exists('WC_Retailcrm_Google_Analytics')) {
include_once(self::checkCustomFile('ga'));
}
if ($this->get_option('ua') && $this->get_option('ua_code')) {
$retailcrm_analytics = WC_Retailcrm_Google_Analytics::getInstance($this->settings);
echo $retailcrm_analytics->initialize_analytics();
} else {
echo '';
}
}
/**
* Google analytics send code
*/
public function send_analytics() {
if (!class_exists('WC_Retailcrm_Google_Analytics')) {
include_once(self::checkCustomFile('ga'));
}
if ($this->get_option('ua') && $this->get_option('ua_code')) {
$retailcrm_analytics = WC_Retailcrm_Google_Analytics::getInstance($this->settings);
echo $retailcrm_analytics->send_analytics();
} else {
echo '';
}
}
/**
* Initialize integration settings form fields.
*/
public function init_form_fields() {
$this->form_fields = array(
array( 'title' => __( 'General Options', 'retailcrm' ), 'type' => 'title', 'desc' => '', 'id' => 'general_options' ),
'api_url' => array(
'title' => __( 'API URL', 'retailcrm' ),
'type' => 'text',
'description' => __( 'Enter with your API URL (https://yourdomain.ecomlogic.com).', 'retailcrm' ),
'desc_tip' => true,
'default' => ''
),
'api_key' => array(
'title' => __( 'API Key', 'retailcrm' ),
'type' => 'text',
'description' => __( 'Enter with your API Key. You can find this in eComlogic admin interface.', 'retailcrm' ),
'desc_tip' => true,
'default' => ''
)
);
$api_version_list = array(
'v4' => 'v4',
'v5' => 'v5'
);
$this->form_fields[] = array(
'title' => __( 'API settings', 'retailcrm' ),
'type' => 'title',
'description' => '',
'id' => 'api_options'
);
$this->form_fields['api_version'] = array(
'title' => __( 'API version', 'retailcrm' ),
'description' => __( 'Select the API version you want to use', 'retailcrm' ),
'css' => 'min-width:50px;',
'class' => 'select',
'type' => 'select',
'options' => $api_version_list,
'desc_tip' => true,
);
$this->form_fields[] = array(
'title' => __( 'Catalog settings', 'retailcrm' ),
'type' => 'title',
'description' => '',
'id' => 'catalog_options'
);
foreach (get_post_statuses() as $status_key => $status_value) {
$this->form_fields['p_' . $status_key] = array(
'title' => $status_value,
'label' => ' ',
'description' => '',
'class' => 'checkbox',
'type' => 'checkbox',
'desc_tip' => true,
);
}
if ($this->apiClient) {
if (isset($_GET['page']) && $_GET['page'] == 'wc-settings'
&& isset($_GET['tab']) && $_GET['tab'] == 'integration'
) {
add_action('admin_print_footer_scripts', array($this, 'show_blocks'), 99);
/**
* Order methods options
*/
$order_methods_option = array();
$order_methods_list = $this->apiClient->orderMethodsList();
if ($order_methods_list->isSuccessful()) {
foreach ($order_methods_list['orderMethods'] as $order_method) {
if ($order_method['active'] == false) {
continue;
}
$order_methods_option[$order_method['code']] = $order_method['name'];
}
$this->form_fields[] = array(
'title' => __('Order methods', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'order_methods_options'
);
$this->form_fields['order_methods'] = array(
'label' => ' ',
'title' => __('Ordering methods available for downloading from eComlogic', 'retailcrm'),
'class' => '',
'type' => 'multiselect',
'description' => __('Select the order methods that will be uploaded from eComlogic to site', 'retailcrm'),
'options' => $order_methods_option,
'select_buttons' => true
);
}
/**
* Shipping options
*/
$shipping_option_list = array();
$retailcrm_shipping_list = $this->apiClient->deliveryTypesList();
if ($retailcrm_shipping_list->isSuccessful()) {
foreach ($retailcrm_shipping_list['deliveryTypes'] as $retailcrm_shipping_type) {
$shipping_option_list[$retailcrm_shipping_type['code']] = $retailcrm_shipping_type['name'];
}
$wc_shipping_list = get_wc_shipping_methods();
$this->form_fields[] = array(
'title' => __('Shipping methods', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'shipping_options'
);
foreach ($wc_shipping_list as $shipping_code => $shipping) {
if (isset($shipping['enabled']) && $shipping['enabled'] == 'yes') {
$this->form_fields[$shipping_code] = array(
'title' => __($shipping['title'], 'woocommerce'),
'description' => __($shipping['description'], 'woocommerce'),
'css' => 'min-width:350px;',
'class' => 'select',
'type' => 'select',
'options' => $shipping_option_list,
'desc_tip' => true,
);
}
}
}
/**
* Payment options
*/
$payment_option_list = array();
$retailcrm_payment_list = $this->apiClient->paymentTypesList();
if ($retailcrm_payment_list->isSuccessful()) {
foreach ($retailcrm_payment_list['paymentTypes'] as $retailcrm_payment_type) {
$payment_option_list[$retailcrm_payment_type['code']] = $retailcrm_payment_type['name'];
}
$wc_payment = WC_Payment_Gateways::instance();
$this->form_fields[] = array(
'title' => __('Payment methods', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'payment_options'
);
foreach ($wc_payment->get_available_payment_gateways() as $payment) {
if (isset($payment->enabled) && $payment->enabled == 'yes') {
$this->form_fields[$payment->id] = array(
'title' => __($payment->method_title, 'woocommerce'),
'description' => __($payment->method_description, 'woocommerce'),
'css' => 'min-width:350px;',
'class' => 'select',
'type' => 'select',
'options' => $payment_option_list,
'desc_tip' => true,
);
}
}
}
/**
* Statuses options
*/
$statuses_option_list = array();
$retailcrm_statuses_list = $this->apiClient->statusesList();
if ($retailcrm_statuses_list->isSuccessful()) {
foreach ($retailcrm_statuses_list['statuses'] as $retailcrm_status) {
$statuses_option_list[$retailcrm_status['code']] = $retailcrm_status['name'];
}
$wc_statuses = wc_get_order_statuses();
$this->form_fields[] = array(
'title' => __('Statuses', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'statuses_options'
);
foreach ($wc_statuses as $idx => $name) {
$uid = str_replace('wc-', '', $idx);
$this->form_fields[$uid] = array(
'title' => __($name, 'woocommerce'),
'css' => 'min-width:350px;',
'class' => 'select',
'type' => 'select',
'options' => $statuses_option_list,
'desc_tip' => true,
);
}
}
/**
* Inventories options
*/
$this->form_fields[] = array(
'title' => __('Inventories settings', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'invent_options'
);
$this->form_fields['sync'] = array(
'label' => __('Sync inventories', 'retailcrm'),
'title' => __('Inventories', 'retailcrm'),
'class' => 'checkbox',
'type' => 'checkbox',
'description' => __('Check this checkbox if you want to unload the rest of the products from CRM to site.', 'retailcrm')
);
/**
* UA options
*/
$this->form_fields[] = array(
'title' => __('UA settings', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'invent_options'
);
$this->form_fields['ua'] = array(
'label' => __('Activate UA', 'retailcrm'),
'title' => __('UA', 'retailcrm'),
'class' => 'checkbox',
'type' => 'checkbox',
'description' => __('Check this checkbox if you want to unload information to UA.', 'retailcrm')
);
$this->form_fields['ua_code'] = array(
'title' => __('UA code', 'retailcrm'),
'class' => 'input',
'type' => 'input'
);
$this->form_fields['ua_custom'] = array(
'title' => __('Custom parameter', 'retailcrm'),
'class' => 'input',
'type' => 'input'
);
/**
* Uploads options
*/
$options = array_filter(get_option(self::$option_key));
if (!isset($options['uploads'])) {
$this->form_fields[] = array(
'title' => __('Uploads settings', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'upload_options'
);
$this->form_fields['upload-button'] = array(
'label' => __('Upload', 'retailcrm'),
'title' => __('Upload all customers and orders', 'retailcrm' ),
'type' => 'button',
'description' => __('Batch unloading of existing customers and orders.', 'retailcrm' ),
'desc_tip' => true,
'id' => 'uploads-retailcrm'
);
}
/*
* Generate icml file
*/
$this->form_fields[] = array(
'title' => __( 'Generate ICML catalog', 'retailcrm' ),
'type' => 'title',
'description' => '',
'id' => 'icml_options'
);
$this->form_fields[] = array(
'label' => __('Generate', 'retailcrm'),
'title' => __('Generate ICML', 'retailcrm'),
'type' => 'button',
'description' => __('This functionality allows you to generate a catalog of products for downloading to CRM.', 'retailcrm'),
'desc_tip' => true,
'id' => 'icml-retailcrm'
);
}
}
}
/**
* Generate html button
*
* @param string $key
* @param array $data
*
* @return string
*/
public function generate_button_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$defaults = array(
'class' => 'button-secondary',
'css' => '',
'custom_attributes' => array(),
'desc_tip' => false,
'description' => '',
'title' => '',
);
$data = wp_parse_args( $data, $defaults );
ob_start();
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<?php echo $this->get_tooltip_html( $data ); ?>
</th>
<td class="forminp">
<fieldset>
<legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['label'] ); ?></span></legend>
<button id="<?php echo $data['id']; ?>" class="<?php echo esc_attr( $data['class'] ); ?>" type="button" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" <?php echo $this->get_custom_attribute_html( $data ); ?>><?php echo wp_kses_post( $data['label'] ); ?></button>
<?php echo $this->get_description_html( $data ); ?>
</fieldset>
</td>
</tr>
<?php
return ob_get_clean();
}
/**
* Generate html title block settings
*
* @param string $key
* @param array $data
*
* @return string
*/
public function generate_heading_html($key, $data) {
$field_key = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'class' => '',
);
$data = wp_parse_args( $data, $defaults );
ob_start();
?>
</table>
<h2 class="wc-settings-sub-title retailcrm_hidden <?php echo esc_attr( $data['class'] ); ?>" id="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <span style="opacity:0.5;float: right;">&#11015;</span></h2>
<?php if ( ! empty( $data['description'] ) ) : ?>
<p><?php echo wp_kses_post( $data['description'] ); ?></p>
<?php endif; ?>
<table class="form-table" style="display: none;">
<?php
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 ($response && $response->isSuccessful()) {
if (!in_array($versionMap[$value], $response['versions'])) {
WC_Admin_Settings::add_error( esc_html__( 'The selected version of the API is unavailable', 'retailcrm' ) );
$value = '';
}
return $value;
}
}
/**
* Validate API url
*
* @param string $key
* @param string $value
*
* @return string
*/
public function validate_api_url_field($key, $value) {
$post = $this->get_post_data();
$api = new WC_Retailcrm_Proxy(
$value,
$post[$this->plugin_id . $this->id . '_api_key']
);
$response = $api->apiVersions();
if ($response == null) {
WC_Admin_Settings::add_error(esc_html__( 'Enter the correct CRM address', 'retailcrm'));
$value = '';
}
return $value;
}
/**
* Validate API key
*
* @param string $key
* @param string $value
*
* @return string
*/
public function validate_api_key_field( $key, $value ) {
$post = $this->get_post_data();
$api = new WC_Retailcrm_Proxy(
$post[$this->plugin_id . $this->id . '_api_url'],
$value
);
$response = $api->apiVersions();
if (!is_object($response)) {
$value = '';
}
if (!$response->isSuccessful()) {
WC_Admin_Settings::add_error( esc_html__( 'Enter the correct API key', 'retailcrm' ) );
$value = '';
}
return $value;
}
/**
* Scritp show|hide block settings
*/
function show_blocks() {
?>
<script type="text/javascript">
jQuery('h2.retailcrm_hidden').hover().css({
'cursor':'pointer',
'width':'300px'
});
jQuery('h2.retailcrm_hidden').toggle(
function() {
jQuery(this).next('table.form-table').show(100);
jQuery(this).find('span').html('&#11014;');
},
function() {
jQuery(this).next('table.form-table').hide(100);
jQuery(this).find('span').html('&#11015;');
}
);
</script>
<?php
}
/**
* Get retailcrm api client
*
* @return bool|WC_Retailcrm_Proxy
*/
public function getApiClient() {
if ($this->get_option('api_url') && $this->get_option('api_key')) {
return new WC_Retailcrm_Proxy(
$this->get_option('api_url'),
$this->get_option('api_key'),
$this->get_option('api_version')
);
}
return false;
}
}
}

View File

@ -0,0 +1,168 @@
<?php
/**
* RetailCRM Integration.
*
* @package WC_Retailcrm_Customers
* @category Integration
* @author RetailCRM
*/
if (!class_exists('WC_Retailcrm_Customers')) :
/**
* Class WC_Retailcrm_Customers
*/
class WC_Retailcrm_Customers {
const CUSTOMER_ROLE = 'customer';
protected $retailcrm;
protected $retailcrm_settings;
private $customer = array();
/**
* WC_Retailcrm_Customers constructor.
*
* @param $retailcrm
*/
public function __construct($retailcrm = false)
{
$this->retailcrm_settings = get_option(WC_Retailcrm_Base::$option_key);
$this->retailcrm = $retailcrm;
}
/**
* Upload customers to CRM
*
* @return array $data
*/
public function customersUpload()
{
if (!$this->retailcrm) {
return;
}
$users = get_users();
$data_customers = array();
foreach ($users as $user) {
if (!\in_array(self::CUSTOMER_ROLE, $user->roles)) {
continue;
}
$customer = $this->wcCustomerGet($user->ID);
$this->processCustomer($customer);
$data_customers[] = $this->customer;
}
$data = \array_chunk($data_customers, 50);
foreach ($data as $array_customers) {
$this->retailcrm->customersUpload($array_customers);
time_nanosleep(0, 250000000);
}
return $data;
}
/**
* Create customer in CRM
*
* @param int $customer_id
*
* @return WC_Customer $customer
*/
public function createCustomer($customer_id)
{
if (!$this->retailcrm) {
return;
}
$customer = $this->wcCustomerGet($customer_id);
if ($customer->get_role() == self::CUSTOMER_ROLE) {
$this->processCustomer($customer);
$this->retailcrm->customersCreate($this->customer);
}
return $customer;
}
/**
* Edit customer in CRM
*
* @param int $customer_id
*
* @return WC_Customer $customer
*/
public function updateCustomer($customer_id)
{
if (!$this->retailcrm) {
return;
}
$customer = $this->wcCustomerGet($customer_id);
if ($customer->get_role() == self::CUSTOMER_ROLE){
$this->processCustomer($customer);
$this->retailcrm->customersEdit($this->customer);
}
return $customer;
}
/**
* Process customer
*
* @param WC_Customer $customer
*
* @return void
*/
protected function processCustomer($customer)
{
$createdAt = $customer->get_date_created();
$firstName = $customer->get_first_name();
$data_customer = array(
'createdAt' => $createdAt->date('Y-m-d H:i:s'),
'externalId' => $customer->get_id(),
'firstName' => $firstName ? $firstName : $customer->get_username(),
'lastName' => $customer->get_last_name(),
'email' => $customer->get_email(),
'address' => array(
'index' => $customer->get_billing_postcode(),
'countryIso' => $customer->get_billing_country(),
'region' => $customer->get_billing_state(),
'city' => $customer->get_billing_city(),
'text' => $customer->get_billing_address_1() . ',' . $customer->get_billing_address_2()
)
);
if ($customer->get_billing_phone()) {
$data_customer['phones'][] = array(
'number' => $customer->get_billing_phone()
);
}
$this->customer = apply_filters('retailcrm_process_customer', $data_customer);
}
/**
* @param int $customer_id
*
* @return WC_Customer
*/
public function wcCustomerGet($customer_id)
{
return new WC_Customer($customer_id);
}
/**
* @return array
*/
public function getCustomer()
{
return $this->customer;
}
}
endif;

View File

@ -0,0 +1,115 @@
<?php
if (!class_exists('WC_Retailcrm_Google_Analytics')) {
class WC_Retailcrm_Google_Analytics {
private static $instance;
private $options;
/**
* @return WC_Retailcrm_Google_Analytics
*/
public static function getInstance($options = array())
{
if (self::$instance === null) {
self::$instance = new self($options);
}
return self::$instance;
}
/**
* WC_Retailcrm_Google_Analytics constructor.
*
* @param array $options
*/
private function __construct($options = array())
{
$this->options = $options;
}
/**
* @return string
*/
public function initialize_analytics() {
return apply_filters('retailcrm_initialize_analytics' ,"
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '" . $this->options['ua_code'] . "', 'auto');
function getRetailCrmCookie(name) {
var matches = document.cookie.match(new RegExp(
'(?:^|; )' + name + '=([^;]*)'
));
return matches ? decodeURIComponent(matches[1]) : '';
}
ga('set', 'dimension" . $this->options['ua_custom'] ."', getRetailCrmCookie('_ga'));
ga('send', 'pageview');
</script>
");
}
/**
* @return string
*/
public function send_analytics() {
$js = '';
$order_id = wc_get_order_id_by_order_key($_GET['key']);
$order = wc_get_order($order_id);
foreach ($order->get_items() as $item) {
$uid = ($item['variation_id'] > 0) ? $item['variation_id'] : $item['product_id'];
$_product = wc_get_product($uid);
if ($_product) {
$order_item = array(
'id' => $uid,
'name' => $item['name'],
'price' => (float)$_product->get_price(),
'quantity' => $item['qty'],
);
$order_items[] = $order_item;
}
}
$url = parse_url(get_site_url());
$domain = $url['host'];
$js .= "
<script type=\"text/javascript\">
ga('require', 'ecommerce', 'ecommerce.js');
ga('ecommerce:addTransaction', {
'id':" . $order->get_id() . ",
'affiliation':" . $domain . ",
'revenue':" . $order->get_total() . ",
'shipping':" . $order->get_total_tax() . ",
'tax':" . $order->get_shipping_total() . "
});
";
foreach ($order_items as $item) {
$js .= "
ga('ecommerce:addItem', {
'id':" . $order->get_id() . ",
'sku':" . $item['id'] . ",
'name': '" . $item['name'] . "',
'price': " . $item['price'] . ",
'quantity': " . $item['quantity'] . "
});
}
ga('ecommerce:send');
</script>
";
}
return apply_filters('retailcrm_send_analytics', $js);
}
}
}

View File

@ -18,29 +18,23 @@ if ( ! class_exists( 'WC_Retailcrm_History' ) ) :
protected $startDateCustomers;
protected $startDate;
protected $retailcrm_settings;
protected $retailcrm;
protected $order_methods = array();
/**
* Constructor WC_Retailcrm_History
* WC_Retailcrm_History constructor.
* @param bool $retailcrm
*/
public function __construct()
public function __construct($retailcrm = false)
{
$this->retailcrm_settings = get_option( 'woocommerce_integration-retailcrm_settings' );
$this->retailcrm_settings = get_option(WC_Retailcrm_Base::$option_key);
if (isset($this->retailcrm_settings['order_methods'])) {
$this->order_methods = $this->retailcrm_settings['order_methods'];
unset($this->retailcrm_settings['order_methods']);
}
if ( ! class_exists( 'WC_Retailcrm_Proxy' ) ) {
include_once( WP_PLUGIN_DIR . '/woo-retailcrm/include/api/class-wc-retailcrm-proxy.php' );
}
$this->retailcrm = new WC_Retailcrm_Proxy(
$this->retailcrm_settings['api_url'],
$this->retailcrm_settings['api_key'],
$this->retailcrm_settings['api_version']
);
$this->retailcrm = $retailcrm;
$this->startDate = new DateTime(date('Y-m-d H:i:s', strtotime('-1 days', strtotime(date('Y-m-d H:i:s')))));
$this->startDateOrders = $this->startDate;

View File

@ -544,7 +544,7 @@ if ( ! class_exists( 'WC_Retailcrm_Icml' ) ) :
* @return array
*/
private function checkPostStatuses() {
$options = get_option( 'woocommerce_integration-retailcrm_settings' );
$options = get_option(WC_Retailcrm_Base::$option_key);
$status_args = array();
foreach (get_post_statuses() as $key => $value) {

View File

@ -0,0 +1,89 @@
<?php
/**
* RetailCRM Integration.
*
* @package WC_Retailcrm_Inventories
* @category Integration
* @author RetailCRM
*/
if (!class_exists('WC_Retailcrm_Inventories')) :
/**
* Class WC_Retailcrm_Inventories
*/
class WC_Retailcrm_Inventories
{
protected $retailcrm;
protected $retailcrm_settings;
/**
* WC_Retailcrm_Inventories constructor.
* @param bool $retailcrm
*/
public function __construct($retailcrm = false)
{
$this->retailcrm_settings = get_option(WC_Retailcrm_Base::$option_key);
$this->retailcrm = $retailcrm;
}
/**
* Load stock from retailCRM
*
* @return mixed
*/
public function load_stocks()
{
$success = array();
if (!$this->retailcrm) {
return null;
}
$page = 1;
do {
$result = $this->retailcrm->storeInventories(array(), $page, 250);
if (!$result->isSuccessful()) {
return null;
}
$totalPageCount = $result['pagination']['totalPageCount'];
$page++;
foreach ($result['offers'] as $offer) {
if (isset($offer['externalId'])) {
$product = wc_get_product($offer['externalId']);
if ($product instanceof WC_Product) {
if ($product->get_type() == 'variable') {
continue;
}
$product->set_manage_stock(true);
$product->set_stock_quantity($offer['quantity']);
$success[] = $product->save();
}
}
}
} while ($page <= $totalPageCount);
return $success;
}
/**
* Update stock quantity in WooCommerce
*
* @return mixed
*/
public function updateQuantity()
{
if ($this->retailcrm_settings['sync'] == 'yes') {
return $this->load_stocks();
}
return false;
}
}
endif;

View File

@ -17,26 +17,26 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
protected $retailcrm_settings;
protected $retailcrm;
public function __construct()
private $order = array();
private $payment = array();
public function __construct($retailcrm = false)
{
$this->retailcrm_settings = get_option( 'woocommerce_integration-retailcrm_settings' );
if ( ! class_exists( 'WC_Retailcrm_Proxy' ) ) {
include_once( WP_PLUGIN_DIR . '/woo-retailcrm/include/api/class-wc-retailcrm-proxy.php' );
}
$this->retailcrm = new WC_Retailcrm_Proxy(
$this->retailcrm_settings['api_url'],
$this->retailcrm_settings['api_key'],
$this->retailcrm_settings['api_version']
);
$this->retailcrm_settings = get_option(WC_Retailcrm_Base::$option_key);
$this->retailcrm = $retailcrm;
}
/**
* Upload orders to CRM
*
* @return array $uploadOrders | null
*/
public function ordersUpload()
{
if (!$this->retailcrm) {
return null;
}
$orders = get_posts(array(
'numberposts' => -1,
'post_type' => wc_get_order_types('view-orders'),
@ -46,35 +46,41 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
$orders_data = array();
foreach ($orders as $data_order) {
$order_data = $this->processOrder($data_order->ID);
$order = new WC_Order($data_order->ID);
$order = wc_get_order($data_order->ID);
$this->processOrder($order);
$customer = $order->get_user();
if ($customer != false) {
$order_data['customer']['externalId'] = $customer->get('ID');
$this->order['customer']['externalId'] = $customer->get('ID');
}
$orders_data[] = $order_data;
$orders_data[] = $this->order;
}
$uploadOrders = array_chunk($orders_data, 50);
foreach ($uploadOrders as $uploadOrder) {
$this->retailcrm->ordersUpload($uploadOrder);
$this->retailcrm->ordersUpload($uploadOrder);
}
return $uploadOrders;
}
/**
* Create order
*
* @param $order_id
*
* @return WC_Order $order | null
*/
public function orderCreate($order_id)
{
$order_data = $this->processOrder($order_id);
if (!$this->retailcrm) {
return null;
}
$order = new WC_Order($order_id);
$order = wc_get_order($order_id);
$this->processOrder($order);
$customer = $order->get_user();
if ($customer != false) {
@ -83,199 +89,106 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
if (!$search->isSuccessful()) {
$customer_data = array(
'externalId' => $customer->get('ID'),
'firstName' => $order_data['firstName'],
'lastName' => $order_data['lastName'],
'email' => $order_data['email']
'firstName' => $this->order['firstName'],
'lastName' => $this->order['lastName'],
'email' => $this->order['email']
);
$this->retailcrm->customersCreate($customer_data);
} else {
$order_data['customer']['externalId'] = $search['customer']['externalId'];
$this->order['customer']['externalId'] = $search['customer']['externalId'];
}
}
$this->retailcrm->ordersCreate($order_data);
$this->retailcrm->ordersCreate($this->order);
return $order;
}
/**
* Update shipping address
* Edit order in CRM
*
* @param $order_id, $address
*/
public function orderUpdateShippingAddress($order_id, $address) {
$address['externalId'] = $order_id;
$this->retailcrm->ordersEdit($address);
}
/**
* Update order status
* @param int $order_id
*
* @param $order_id
* @return WC_Order $order | null
*/
public function orderUpdateStatus($order_id) {
$order = new WC_Order( $order_id );
public function updateOrder($order_id)
{
if (!$this->retailcrm) {
return null;
}
$order_data = array(
'externalId' => $order_id,
'status' => $this->retailcrm_settings[$order->get_status()]
);
$order = wc_get_order($order_id);
$this->processOrder($order, true);
$this->retailcrm->ordersEdit($order_data);
if ($this->retailcrm_settings['api_version'] == 'v4') {
$this->order['paymentType'] = $this->retailcrm_settings[$order->get_payment_method()];
}
$response = $this->retailcrm->ordersEdit($this->order);
if ($response->isSuccessful() && $this->retailcrm_settings['api_version'] == 'v5') {
$this->payment = $this->orderUpdatePaymentType($order);
}
return $order;
}
/**
* Update order payment type
*
* @param $order_id
*
* @return null
* @param WC_Order $order
*
* @return null | array $payment
*/
public function orderUpdatePaymentType($order_id, $payment_method) {
if (!isset($this->retailcrm_settings[$payment_method])) {
return;
protected function orderUpdatePaymentType($order)
{
if (!isset($this->retailcrm_settings[$order->get_payment_method()])) {
return null;
}
if ($this->retailcrm_settings['api_version'] != 'v5') {
$order_data = array(
'externalId' => $order_id,
'paymentType' => $this->retailcrm_settings[$payment_method]
);
$response = $this->retailcrm->ordersGet($order->get_id());
$this->retailcrm->ordersEdit($order_data);
} else {
$response = $this->retailcrm->ordersGet($order_id);
if ($response->isSuccessful()) {
$retailcrmOrder = $response['order'];
if ($response->isSuccessful()) {
$order = $response['order'];
}
foreach ($order['payments'] as $payment_data) {
if ($payment_data['externalId'] == $order_id) {
foreach ($retailcrmOrder['payments'] as $payment_data) {
if ($payment_data['externalId'] == $order->get_id()) {
$payment = $payment_data;
}
}
$order = new WC_Order($order_id);
if (isset($payment) && $payment['type'] != $this->retailcrm_settings[$order->payment_method]) {
$response = $this->retailcrm->ordersPaymentDelete($payment['id']);
if ($response->isSuccessful()) {
$this->createPayment($order, $order_id);
}
}
}
}
/**
* Update order payment
*
* @param $order_id
*/
public function orderUpdatePayment($order_id) {
if ($this->retailcrm_settings['api_version'] != 'v5') {
$order_data = array(
'externalId' => $order_id,
'paymentStatus' => 'paid'
);
$this->retailcrm->ordersEdit($order_data);
} else {
$payment = array(
'externalId' => $order_id,
'status' => 'paid'
);
$this->retailcrm->ordersPaymentsEdit($payment);
}
}
if (isset($payment) && $payment['type'] != $this->retailcrm_settings[$order->get_payment_method()]) {
$response = $this->retailcrm->ordersPaymentDelete($payment['id']);
/**
* Update order items
*
* @param $order_id, $data
*/
public function orderUpdateItems($order_id, $data) {
$order = new WC_Order( $order_id );
if ($response->isSuccessful()) {
$payment = $this->createPayment($order);
$order_data['externalId'] = $order_id;
$shipping_method = end($data['shipping_method']);
$shipping_cost = end($data['shipping_cost']);
$products = $order->get_items();
$items = array();
foreach ($products as $order_item_id => $product) {
if ($product['variation_id'] > 0) {
$offer_id = $product['variation_id'];
} else {
$offer_id = $product['product_id'];
}
$_product = wc_get_product($offer_id);
if ($this->retailcrm_settings['api_version'] != 'v3') {
$items[] = array(
'offer' => array('externalId' => $offer_id),
'productName' => $product['name'],
'initialPrice' => (float)$_product->get_price(),
'quantity' => $product['qty']
);
} else {
$items[] = array(
'productId' => $offer_id,
'productName' => $product['name'],
'initialPrice' => (float)$_product->get_price(),
'quantity' => $product['qty']
);
return $payment;
}
}
$order_data['items'] = $items;
if (!empty($shipping_method) && !empty($this->retailcrm_settings[$shipping_method])) {
$order_data['delivery']['code'] = $this->retailcrm_settings[$shipping_method];
}
if (!empty($shipping_cost)) {
$shipping_cost = str_replace(',', '.', $shipping_cost);
$order_data['delivery']['cost'] = $shipping_cost;
}
$this->retailcrm->ordersEdit($order_data);
return null;
}
/**
* get order data depending on woocommerce version
* Get order data
*
* @param int $order_id
* @param WC_Order $order
*
* @return arr
* @return array $order_data_arr
*/
public function getOrderData($order_id) {
$order = new WC_Order( $order_id );
protected function getOrderData($order) {
$order_data_arr = array();
$order_info = $order->get_data();
if (version_compare(get_option('woocommerce_db_version'), '3.0', '<' )) {
$order_data_arr['id'] = $order->id;
$order_data_arr['date'] = $order->order_date;
$order_data_arr['payment_method'] = $order->payment_method;
$order_data_arr['discount_total'] = $order->data['discount_total'];
$order_data_arr['discount_tax'] = $order->data['discount_tax'];
$order_data_arr['customer_comment'] = $order->data['customerComment'];
} else {
$order_info = $order->get_data();
$order_data_arr['id'] = $order_info['id'];
$order_data_arr['payment_method'] = $order->get_payment_method();
$order_data_arr['date'] = $order_info['date_created']->date('Y-m-d H:i:s');
$order_data_arr['discount_total'] = $order_info['discount_total'];
$order_data_arr['discount_tax'] = $order_info['discount_tax'];
$order_data_arr['customer_comment'] = $order->get_customer_note();
}
$order_data_arr['id'] = $order_info['id'];
$order_data_arr['payment_method'] = $order->get_payment_method();
$order_data_arr['date'] = $order_info['date_created']->date('Y-m-d H:i:s');
$order_data_arr['discount_total'] = $order_info['discount_total'];
$order_data_arr['discount_tax'] = $order_info['discount_tax'];
$order_data_arr['customer_comment'] = $order->get_customer_note();
return $order_data_arr;
}
@ -283,19 +196,18 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
/**
* process to combine order data
*
* @param int $order_id
* @param WC_Order $order
* @param boolean $update
*
* @return array $order_data
*
* @return void
*/
public function processOrder($order_id, $update = false)
protected function processOrder($order, $update = false)
{
if ( !$order_id ){
if (!$order instanceof WC_Order) {
return;
}
$order = new WC_Order( $order_id );
$order_data_info = $this->getOrderData($order_id);
$order_data_info = $this->getOrderData($order);
$order_data = array();
$order_data['externalId'] = $order_data_info['id'];
@ -303,13 +215,16 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
$order_data['createdAt'] = trim($order_data_info['date']);
$order_data['customerComment'] = $order_data_info['customer_comment'];
if ( !empty( $order_data_info['payment_method'] ) && !empty($this->retailcrm_settings[$order_data_info['payment_method']]) && $this->retailcrm_settings['api_version'] != 'v5') {
if (!empty($order_data_info['payment_method'])
&& !empty($this->retailcrm_settings[$order_data_info['payment_method']])
&& $this->retailcrm_settings['api_version'] != 'v5'
) {
$order_data['paymentType'] = $this->retailcrm_settings[$order_data_info['payment_method']];
}
if ($order->get_items( 'shipping' )) {
if ($order->get_items('shipping')) {
$shippings = $order->get_items( 'shipping' );
$shipping = end($shippings);
$shipping = reset($shippings);
$shipping_code = explode(':', $shipping['method_id']);
if (isset($this->retailcrm_settings[$shipping['method_id']])) {
@ -405,11 +320,11 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
if ($this->retailcrm_settings['api_version'] == 'v5') {
$payment = array(
'amount' => $order->get_total(),
'externalId' => $order_id
'externalId' => $order->get_id()
);
$payment['order'] = array(
'externalId' => $order_id
'externalId' => $order->get_id()
);
if (!empty($order_data_info['payment_method']) && !empty($this->retailcrm_settings[$order_data_info['payment_method']])) {
@ -427,12 +342,10 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
if (!$update) {
$order_data['payments'][] = $payment;
} else {
$this->editPayment($payment);
}
}
return apply_filters('retailcrm_process_order', $order_data);
$this->order = apply_filters('retailcrm_process_order', $order_data);
}
/**
@ -441,21 +354,21 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
* @param WC_Order $order
* @param int $order_id
*
* @return void
* @return array $payment
*/
protected function createPayment($order, $order_id)
protected function createPayment($order)
{
$payment = array(
'amount' => $order->get_total(),
'externalId' => $order_id
'externalId' => $order->get_id()
);
$payment['order'] = array(
'externalId' => $order_id
'externalId' => $order->get_id()
);
if (!empty($order->payment_method) && !empty($this->retailcrm_settings[$order->payment_method])) {
$payment['type'] = $this->retailcrm_settings[$order->payment_method];
if (isset($this->retailcrm_settings[$order->get_payment_method()])) {
$payment['type'] = $this->retailcrm_settings[$order->get_payment_method()];
}
if ($order->is_paid()) {
@ -468,38 +381,24 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
}
$this->retailcrm->ordersPaymentCreate($payment);
return $payment;
}
/**
* Edit payment in CRM
*
* @param array $payment
*
* @return void
* @return array
*/
protected function editPayment($payment)
public function getOrder()
{
$this->retailcrm->ordersPaymentEdit($payment);
return $this->order;
}
/**
* Edit order in CRM
*
* @param int $order_id
*
* @return void
* @return array
*/
public function updateOrder($order_id)
public function getPayment()
{
$order = $this->processOrder($order_id, true);
$response = $this->retailcrm->ordersEdit($order);
$orderWc = new WC_Order($order_id);
if ($response->isSuccessful()) {
$this->orderUpdatePaymentType($order_id, $orderWc->get_payment_method());
}
return $this->payment;
}
}
endif;

View File

@ -0,0 +1,55 @@
<?php
class WC_Retailcrm_Plugin {
public $file;
private static $instance = null;
public static function getInstance($file) {
if (self::$instance === null) {
self::$instance = new self($file);
}
return self::$instance;
}
private function __construct($file) {
$this->file = $file;
}
public function register_activation_hook() {
register_activation_hook($this->file, array($this, 'activate'));
}
public function register_deactivation_hook() {
register_deactivation_hook($this->file, array($this, 'deactivate'));
}
public function activate() {
if (!class_exists('WC_Retailcrm_Icml')) {
require_once (dirname(__FILE__) . '/class-wc-retailcrm-icml.php');
}
if (!class_exists('WC_Retailcrm_Base')) {
require_once (dirname(__FILE__) . '/class-wc-retailcrm-base.php');
}
$retailcrm_icml = new WC_Retailcrm_Icml();
$retailcrm_icml->generate();
}
public function deactivate() {
if ( wp_next_scheduled ( 'retailcrm_icml' )) {
wp_clear_scheduled_hook('retailcrm_icml');
}
if ( wp_next_scheduled ( 'retailcrm_history' )) {
wp_clear_scheduled_hook('retailcrm_history');
}
if ( wp_next_scheduled ( 'retailcrm_inventories' )) {
wp_clear_scheduled_hook('retailcrm_inventories');
}
}
}

174
src/readme.txt Normal file
View File

@ -0,0 +1,174 @@
=== Woocommerce RetailCRM ===
Contributors: retailCRM
Donate link: http://retailcrm.ru/
Tags: Интеграция, Retailcrm
Requires PHP: 5.3
Requires at least: 4.7
Tested up to: 4.9.5
Stable tag: 4.9
License: GPLv1 or later
License URI: http://www.gnu.org/licenses/gpl-1.0.html
== Description ==
= Возможности плагина =
Плагин для интеграции Woocommerce и Retailcrm. Плагин позволяет сгенерировать каталог товаров для выгрузки в Retailcrm, настроить двусторонний обмен заказами Woocommerce и Retailcrm, отправлять и принимать изменения по заказам, выгружать остатки из Retailcrm в магазин. При включении функции выгрузки остатков каждые 15 минут остатки по товарам будут выгружаться в магазин (настройка имеет смысл при включении ручного редактирования остатков в Retailcrm, остатки из магазина выгружаются вместе с каталогом товаров каждые 4 часа). Внимание!!! При включении выгрузки остатков плагин включит управление остатками для товаров. Товары, отсутствующие на складе будут скрыты на сайте для посетителей.
= Выгрузка изменений из Retailcrm =
Каждые 5 минут плагин подгружает изменения из Retailcrm в Woocommerce.
= Кастомизация =
Вы можете вносить изменения в базовые классы плагина, разместив копию класса из дериктории include в директории wp-content/retailcrm-custom.
== Installation ==
= Активация и настройка =
После активации плагина необходимо открыть настройки Woocommerce, выбрать вкладку "Интеграция" и в настройках RetailCRM указать адрес CRM (например https://example.retailcrm.ru) и API-ключ, сгенерированный в CRM (инструкция по добавлению ключа в CRM - http://www.retailcrm.ru/docs/Users/ApiKeys), выбрать желаемую версию API (API v5 доступна только c версии Retailcrm 6.0 и выше)
== Frequently Asked Questions ==
= Нет списка справочников для настройки соответствия =
Проверьте, что для созданного API-ключа доступны все методы
= Заказы не попадают в Retailcrm =
API-ключ должен быть для отдельного магазина
== Screenshots ==
1. Введите адрес CRM, API-ключ и выберите версию API, нажмите на кнопку сохраниения настроек. Если после сохранения не появилось никаких других настроек, обновите страницу.
2. В появившихся списках справочников настройте соответствие способов доставки и оплаты, а так же статусов заказов. Отметьте галочку "Выгружать остатки", если хотите выгружать остатки из Retailcrm в магазин (подробнее смотрите в описании).
== Changelog ==
= 3.0.0 =
* Произведен рефакторинг кода
= 2.1.4 =
* Исправлена ошибка при активированном модуле без настроек
* Добавлен фильтр при формировании массива заказа
* Исправлена генерация icml с неполной картинкой товара
= 2.1.3 =
* Исправлена ошибка на php5.3
= 2.1.2 =
* Добавлена локализация плагина
* Добавлена интеграция с UA
= 2.1.1 =
* Исправлена ошибка с редактированием клиента
= 2.1.0 =
* Переработана механика генерации icml каталога товаров
* В icml каталог добавлена выгрузка налоговой ставки
* Исправлен пересчет итогов после изменения количества товара в RetailCRM
= 2.0.6 =
* Исправлено возникновение Warning на PHP 7.2 при генерации каталога товаров
* Добавлена настройка выгрузки заказов из RetailCRM с определенными способами оформления
* Выгрузка изменений из RetailCRM осуществляется по sinceId
= 2.0.5 =
* Исправлен неверный подсчет скидки на товары
= 2.0.4 =
* Улучшена механика пакетной выгрузки клиентов и заказов
* Добавлена возможность выгрузки заказов с товарами, которые уже удалены с сайта
= 2.0.3 =
* Изменен механизм рассчета стоимости товара в заказе
* Улучшена передача информации об изменениях в заказе
* Устранены мелкие баги
= 2.0.2 =
* Изменен механизм передачи скидок в CRM
= 2.0.1 =
* Добавлена выгрузка размеров товаров
* Улучшена выгрузка веса товаров
* Улучшена механика выгрузки заказов из CRM
= 2.0.0 =
* Улучшен поиск типов доставок на сайте
* Добавлена кнопка генерации icml каталога в настройках плагина
* Переработан механизм выгрузки заказов из CRM
* Улучшена генерация каталога, добавлена выгрузка размеров
= 1.2.3 =
* Добален опциональный выбор статусов товаров, выгружаемых в каталоге
* Улучшен механизм формирования цены товара в заказе (с учетом скидок и налогов)
= 1.2.2 =
* Исправлены ошибки
= 1.2.1 =
* Доработана система кастомизации.
= 1.2.0 =
* Улучшена возможность кастомизации плагина.
* Добавлена возможность кастомизации обработки остатков, клиентов и истории.
= 1.1 =
* Добавлена возможность выбора версии API.
* Исправелены ошибки.
== Upgrade Notice ==
= 3.0.0 =
* Произведен рефакторинг кода
= 2.1.4 =
Исправлена ошибка при активированном модуле без настроек
Добавлен фильтр при формировании массива заказа
Исправлена генерация icml с неполной картинкой товара
= 2.1.3 =
Исправлена ошибка на php5.3
= 2.1.2 =
Добавлена локализация плагина
Добавлена интеграция с UA
= 2.1.1 =
Исправлена ошибка с редактированием клиента
= 2.1.0 =
Переработана механика генерации icml каталога товаров
В icml каталог добавлена выгрузка налоговой ставки
Исправлен пересчет итогов после изменения количества товара в RetailCRM
= 2.0.6 =
Исправлено возникновение Warning на PHP 7.2 при генерации каталога товаров
Добавлена настройка выгрузки заказов из RetailCRM с определенными способами оформления
= 2.0.4 =
Улучшена механика пакетной выгрузки клиентов и заказов
Добавлена возможность выгрузки заказов с товарами, которые уже удалены с сайта
= 2.0.3 =
Изменен механизм рассчета стоимости товара в заказе
Улучшена передача информации об изменениях в заказе
Устранены мелкие баги
= 2.0.2 =
Изменен механизм передачи скидок в CRM
= 2.0.1 =
Добавлена выгрузка размеров товаров
Улучшена выгрузка веса товаров
Улучшена механика выгрузки заказов из CRM
= 2.0.0 =
Улучшен поиск типов доставок на сайте
Добавлена кнопка генерации icml каталога в настройках плагина
Переработан механизм выгрузки заказов из CRM
Улучшена генерация каталога, добавлена выгрузка размеров
= 1.2.3 =
Исправлены ошибки, доработан функционал

76
src/retailcrm.php Normal file
View File

@ -0,0 +1,76 @@
<?php
/**
* Version: 3.0.0
* WC requires at least: 3.0
* WC tested up to: 3.3
* Plugin Name: WooCommerce RetailCRM
* Plugin URI: https://wordpress.org/plugins/woo-retailcrm/
* Description: Integration plugin for WooCommerce & RetailCRM
* Author: RetailDriver LLC
* Author URI: http://retailcrm.ru/
* Text Domain: retailcrm
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if (!class_exists( 'WC_Integration_Retailcrm')) :
/**
* Class WC_Integration_Retailcrm
*/
class WC_Integration_Retailcrm {
private static $instance;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Construct the plugin.
*/
public function __construct() {
add_action('plugins_loaded', array($this, 'load_plugin_textdomain'));
if ( class_exists( 'WC_Integration' ) ) {
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'));
} else {
// throw an admin error if you like
}
}
public function load_plugin_textdomain() {
load_plugin_textdomain('retailcrm', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
}
/**
* Add a new integration to WooCommerce.
*
* @param $integrations
*
* @return array
*/
public function add_integration( $integrations ) {
$integrations[] = 'WC_Retailcrm_Base';
return $integrations;
}
}
if (!class_exists('WC_Retailcrm_Plugin')) {
require_once (dirname(__FILE__) . '/include/class-wc-retailcrm-plugin.php');
}
$plugin = WC_Retailcrm_Plugin::getInstance(__FILE__);
$plugin->register_activation_hook();
$plugin->register_deactivation_hook();
add_action( 'plugins_loaded', array( 'WC_Integration_Retailcrm', 'get_instance' ), 0 );
endif;

View File

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

137
tests/bin/install.sh Executable file
View File

@ -0,0 +1,137 @@
#!/usr/bin/env bash
# See https://raw.githubusercontent.com/wp-cli/scaffold-command/master/templates/install-wp-tests.sh
if [ $# -lt 3 ]; then
echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]"
exit 1
fi
DB_NAME=$1
DB_USER=$2
DB_PASS=$3
DB_HOST=${4-localhost}
WP_VERSION=${5-latest}
SKIP_DB_CREATE=${6-false}
WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib}
WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/}
download() {
if [ `which curl` ]; then
curl -s "$1" > "$2";
elif [ `which wget` ]; then
wget -nv -O "$2" "$1"
fi
}
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then
WP_TESTS_TAG="tags/$WP_VERSION"
elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
WP_TESTS_TAG="trunk"
else
# http serves a single offer, whereas https serves multiple. we only want one
download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
if [[ -z "$LATEST_VERSION" ]]; then
echo "Latest WordPress version could not be found"
exit 1
fi
WP_TESTS_TAG="tags/$LATEST_VERSION"
fi
set -ex
install_wp() {
if [ -d $WP_CORE_DIR ]; then
return;
fi
mkdir -p $WP_CORE_DIR
if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
mkdir -p /tmp/wordpress-nightly
download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip
unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/
mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR
else
if [ $WP_VERSION == 'latest' ]; then
local ARCHIVE_NAME='latest'
else
local ARCHIVE_NAME="wordpress-$WP_VERSION"
fi
download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz
tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
fi
download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
}
install_woocommerce() {
cd /tmp
git clone https://github.com/woocommerce/woocommerce.git
cd woocommerce
git checkout master
cd -
}
install_test_suite() {
# portable in-place argument for both GNU sed and Mac OSX sed
if [[ $(uname -s) == 'Darwin' ]]; then
local ioption='-i .bak'
else
local ioption='-i'
fi
# set up testing suite if it doesn't yet exist
if [ ! -d $WP_TESTS_DIR ]; then
# set up testing suite
mkdir -p $WP_TESTS_DIR
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
fi
if [ ! -f wp-tests-config.php ]; then
download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
# remove all forward slashes in the end
WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
fi
}
install_db() {
if [ ${SKIP_DB_CREATE} = "true" ]; then
return 0
fi
# parse DB_HOST for port or socket references
local PARTS=(${DB_HOST//\:/ })
local DB_HOSTNAME=${PARTS[0]};
local DB_SOCK_OR_PORT=${PARTS[1]};
local EXTRA=""
if ! [ -z $DB_HOSTNAME ] ; then
if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
elif ! [ -z $DB_SOCK_OR_PORT ] ; then
EXTRA=" --socket=$DB_SOCK_OR_PORT"
elif ! [ -z $DB_HOSTNAME ] ; then
EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
fi
fi
# create database
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
}
install_wp
install_test_suite
install_woocommerce
install_db

8
tests/bin/script.sh Normal file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
if [[ ${RUN_PHPCS} == 1 ]]; then
composer install
vendor/phpunit/phpunit/phpunit -c phpunit.xml.dist
else
phpunit -c phpunit.xml.dist
fi

View File

@ -0,0 +1,13 @@
<?php
if (!class_exists('WC_Retailcrm_Response')) {
require_once dirname(__FILE__) . '/../../src/include/api/class-wc-retailcrm-response.php';
}
class WC_Retailcrm_Response_Helper extends WC_Retailcrm_Response
{
public function setResponse($response)
{
$this->response = $response;
}
}

View File

@ -0,0 +1,45 @@
<?php
class WC_Retailcrm_Test_Case_Helper extends WC_Unit_Test_Case
{
protected function setOptions($apiVesrion)
{
$options = array(
'api_url' => 'https://example.retailcrm.ru',
'api_key' => 'dhsHJGYdjkHHJKJSGjhasjhgajsgJGHsg',
'api_version' => $apiVesrion,
'p_draft' => 'no',
'p_pending' => 'no',
'p_private' => 'no',
'p_publish' => 'no',
'order_methods' => '',
'flat_rate' => 'delivery',
'flat_rate:1' => 'delivery1',
'free_shipping:7' => 'delivery2',
'flat_rate:8' => 'delivery3',
'local_pickup:9' => 'delivery4',
'flat_rate_shipping' => 'delivery5',
'bacs' => 'payment1',
'cheque' => 'payment2',
'cod' => 'payment3',
'paypal' => 'payment4',
'ppec_paypal' => 'payment5',
'pending' => 'status1',
'processing' => 'status2',
'on-hold' => 'status3',
'completed' => 'status4',
'cancelled' => 'status5',
'refunded' => 'status6',
'failed' => 'status7',
'sync' => 'no',
'ua' => 'no',
'ua_code' => '',
'ua_custom' => '',
'upload-button' => ''
);
update_option(WC_Retailcrm_Base::$option_key, $options);
return $options;
}
}

View File

@ -0,0 +1,27 @@
<?php
$_tests_dir = getenv('WP_TESTS_DIR');
if (!$_tests_dir) {
$_tests_dir = '/tmp/wordpress-tests-lib';
}
require_once $_tests_dir . '/includes/functions.php';
function _manually_load_plugin() {
$plugin_dir = dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/';
require $plugin_dir . 'woocommerce-retailcrm/src/include/class-wc-retailcrm-orders.php';
require $plugin_dir . 'woocommerce-retailcrm/src/include/class-wc-retailcrm-customers.php';
require $plugin_dir . 'woocommerce-retailcrm/src/include/class-wc-retailcrm-inventories.php';
require $plugin_dir . 'woocommerce-retailcrm/src/retailcrm.php';
}
tests_add_filter('muplugins_loaded', '_manually_load_plugin');
require '/tmp/woocommerce/tests/bootstrap.php';
$plugin_dir = dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/';
// helpers
require $plugin_dir . 'woocommerce-retailcrm/tests/helpers/class-wc-retailcrm-response-helper.php';
require $plugin_dir . 'woocommerce-retailcrm/tests/helpers/class-wc-retailcrm-test-case-helper.php';

View File

@ -0,0 +1,221 @@
<?php
class WC_Retailcrm_Base_Test extends WC_Retailcrm_Test_Case_Helper
{
protected $apiMock;
protected $responseMockOrderMethods;
protected $responseMockDeliveryTypes;
protected $responseMockPaymentTypes;
protected $responseMockStatuses;
private $unit;
public function setUp()
{
$this->apiMock = $this->getMockBuilder('\WC_Retailcrm_Proxy')
->disableOriginalConstructor()
->setMethods(array(
'orderMethodsList',
'deliveryTypesList',
'paymentTypesList',
'statusesList'
))
->getMock();
$this->setMockOrderMethods();
$this->setMockDeliveryTypes();
$this->setMockPaymentTypes();
$this->setMockStatuses();
$_GET['page'] = 'wc-settings';
$_GET['tab'] = 'integration';
$this->setOptions('v5');
$this->unit = new \WC_Retailcrm_Base($this->apiMock);
}
public function test_retailcrm_check_custom_file()
{
$file = \WC_Retailcrm_Base::checkCustomFile('ga');
$this->assertInternalType('string', $file);
}
public function test_retailcrm_form_fields()
{
$this->assertInternalType('array', $this->unit->form_fields);
$this->assertArrayHasKey('api_url', $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) {
$this->assertArrayHasKey('p_' . $key, $this->unit->form_fields);
}
$this->assertArrayHasKey('order_methods', $this->unit->form_fields);
foreach (get_wc_shipping_methods() as $code => $value) {
if (isset($value['enabled']) && $value['enabled'] == 'yes') {
$this->assertArrayHasKey($code, $this->unit->form_fields);
}
}
$wc_payment = WC_Payment_Gateways::instance();
foreach ($wc_payment->get_available_payment_gateways() as $payment) {
if (isset($payment->enabled) && $payment->enabled == 'yes') {
$this->assertArrayHasKey($payment->id, $this->unit->form_fields);
}
}
foreach (wc_get_order_statuses() as $idx => $name ) {
$uid = str_replace('wc-', '', $idx);
$this->assertArrayHasKey($uid, $this->unit->form_fields);
}
}
private function getResponseOrderMethods()
{
return array(
'success' => true,
'orderMethods' => array(
array(
'name' => 'orderMethod1',
'code' => 'orderMethod1',
'active' => true
),
array(
'name' => 'orderMethod2',
'code' => 'orderMethod2',
'active' => true
)
)
);
}
private function getResponseDeliveryTypes()
{
return array(
'success' => true,
'deliveryTypes' => array(
array(
'name' => 'delivery1',
'code' => 'delivery1'
),
array(
'name' => 'delivery2',
'code' => 'delivery2'
)
)
);
}
private function getResponsePaymentTypes()
{
return array(
'success' => true,
'paymentTypes' => array(
array(
'name' => 'payment1',
'code' => 'payment1'
),
array(
'name' => 'payment2',
'code' => 'payment2'
)
)
);
}
private function getResponseStatuses()
{
return array(
'success' => true,
'statuses' => array(
array(
'name' => 'status1',
'code' => 'status1'
),
array(
'name' => 'status2',
'code' => 'status2'
)
)
);
}
private function setMockOrderMethods()
{
$this->responseMockOrderMethods = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
->disableOriginalConstructor()
->setMethods(array(
'isSuccessful'
))
->getMock();
$this->responseMockOrderMethods->expects($this->any())
->method('isSuccessful')
->willReturn(true);
$this->responseMockOrderMethods->setResponse($this->getResponseOrderMethods());
$this->apiMock->expects($this->any())
->method('orderMethodsList')
->willReturn($this->responseMockOrderMethods);
}
private function setMockDeliveryTypes()
{
$this->responseMockDeliveryTypes = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
->disableOriginalConstructor()
->setMethods(array(
'isSuccessful'
))
->getMock();
$this->responseMockDeliveryTypes->expects($this->any())
->method('isSuccessful')
->willReturn(true);
$this->responseMockDeliveryTypes->setResponse($this->getResponseDeliveryTypes());
$this->apiMock->expects($this->any())
->method('deliveryTypesList')
->willReturn($this->responseMockDeliveryTypes);
}
private function setMockPaymentTypes()
{
$this->responseMockPaymentTypes = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
->disableOriginalConstructor()
->setMethods(array(
'isSuccessful'
))
->getMock();
$this->responseMockPaymentTypes->expects($this->any())
->method('isSuccessful')
->willReturn(true);
$this->responseMockPaymentTypes->setResponse($this->getResponsePaymentTypes());
$this->apiMock->expects($this->any())
->method('paymentTypesList')
->willReturn($this->responseMockPaymentTypes);
}
private function setMockStatuses()
{
$this->responseMockStatuses = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
->disableOriginalConstructor()
->setMethods(array(
'isSuccessful'
))
->getMock();
$this->responseMockStatuses->expects($this->any())
->method('isSuccessful')
->willReturn(true);
$this->responseMockStatuses->setResponse($this->getResponseStatuses());
$this->apiMock->expects($this->any())
->method('statusesList')
->willReturn($this->responseMockStatuses);
}
}

View File

@ -0,0 +1,132 @@
<?php
class WC_Retailcrm_Customers_Test extends WC_Retailcrm_Test_Case_Helper
{
protected $apiMock;
protected $responseMock;
protected $customer;
public function setUp()
{
$this->responseMock = $this->getMockBuilder('\WC_Retailcrm_Response')
->disableOriginalConstructor()
->setMethods(array(
'isSuccessful'
))
->getMock();
$this->apiMock = $this->getMockBuilder('\WC_Retailcrm_Proxy')
->disableOriginalConstructor()
->setMethods(array(
'ordersGet',
'ordersUpload',
'ordersCreate',
'ordersEdit',
'customersGet',
'customersUpload',
'customersCreate',
'customersEdit'
))
->getMock();
$this->customer = new WC_Customer();
$this->customer->set_email(uniqid(md5(date('Y-m-d H:i:s'))) . '@mail.com');
$this->customer->set_password('password');
$this->customer->set_role(WC_Retailcrm_Customers::CUSTOMER_ROLE);
$this->customer->set_billing_phone('89000000000');
$this->customer->save();
}
/**
* @param retailcrm
* @dataProvider dataProviderApiClient
*/
public function test_wc_customer_get($retailcrm)
{
$wc_customer = new WC_Customer($this->customer->get_id());
$retailcrm_customer = new WC_Retailcrm_Customers($retailcrm);
$this->assertEquals($wc_customer, $retailcrm_customer->wcCustomerGet($this->customer->get_id()));
}
/**
* @param retailcrm
* @dataProvider dataProviderApiClient
*/
public function test_customers_upload($retailcrm)
{
$retailcrm_customer = new WC_Retailcrm_Customers($retailcrm);
$data = $retailcrm_customer->customersUpload();
if ($retailcrm) {
$this->assertInternalType('array', $data);
$this->assertInternalType('array', $data[0]);
$this->assertArrayHasKey('externalId', $data[0][0]);
} else {
$this->assertEquals(null, $data);
}
}
/**
* @param $retailcrm
* @dataProvider dataProviderApiClient
*/
public function test_create_customer($retailcrm)
{
$retailcrm_customer = new WC_Retailcrm_Customers($retailcrm);
$customer = $retailcrm_customer->createCustomer($this->customer->get_id());
$customer_send = $retailcrm_customer->getCustomer();
if ($retailcrm) {
$this->assertArrayHasKey('externalId', $customer_send);
$this->assertArrayHasKey('firstName', $customer_send);
$this->assertArrayHasKey('createdAt', $customer_send);
$this->assertArrayHasKey('email', $customer_send);
$this->assertNotEmpty($customer_send['externalId']);
$this->assertNotEmpty($customer_send['firstName']);
$this->assertNotEmpty($customer_send['email']);
$this->assertInstanceOf('WC_Customer', $customer);
} else {
$this->assertEquals(null, $customer);
$this->assertEquals(array(), $customer_send);
}
}
/**
* @param $retailcrm
* @dataProvider dataProviderApiClient
*/
public function test_update_customer($retailcrm)
{
$retailcrm_customer = new WC_Retailcrm_Customers($retailcrm);
$customer = $retailcrm_customer->updateCustomer($this->customer->get_id());
$customer_send = $retailcrm_customer->getCustomer();
if ($retailcrm) {
$this->assertArrayHasKey('externalId', $customer_send);
$this->assertArrayHasKey('firstName', $customer_send);
$this->assertArrayHasKey('createdAt', $customer_send);
$this->assertArrayHasKey('email', $customer_send);
$this->assertNotEmpty($customer_send['externalId']);
$this->assertNotEmpty($customer_send['firstName']);
$this->assertNotEmpty($customer_send['email']);
$this->assertInstanceOf('WC_Customer', $customer);
} else {
$this->assertEquals(null, $customer);
$this->assertEquals(array(), $customer_send);
}
}
public function dataProviderApiClient()
{
$this->setUp();
return array(
array(
'retailcrm' => $this->apiMock
),
array(
'retailcrm' => false
)
);
}
}

View File

@ -0,0 +1,123 @@
<?php
class WC_Retailcrm_Inventories_Test extends WC_Retailcrm_Test_Case_Helper
{
protected $apiMock;
protected $responseMock;
protected $offer;
public function setUp()
{
$this->responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
->disableOriginalConstructor()
->setMethods(array(
'isSuccessful'
))
->getMock();
$this->apiMock = $this->getMockBuilder('\WC_Retailcrm_Proxy')
->disableOriginalConstructor()
->setMethods(array(
'storeInventories'
))
->getMock();
parent::setUp();
}
/**
* @param $retailcrm
* @param $response
*
* @dataProvider dataProviderLoadStocks
*/
public function test_load_stocks($retailcrm, $response)
{
$offer = WC_Helper_Product::create_simple_product();
$offer->save();
if ($response['success'] == true) {
$response['offers'][0]['externalId'] = $offer->get_id();
$this->responseMock->expects($this->any())
->method('isSuccessful')
->willReturn(true);
} elseif ($response['success'] == false) {
$this->responseMock->expects($this->any())
->method('isSuccessful')
->willReturn(false);
}
$this->responseMock->setResponse($response);
if ($retailcrm) {
$retailcrm->expects($this->any())
->method('storeInventories')
->willReturn($this->responseMock);
}
$retailcrm_inventories = new WC_Retailcrm_Inventories($retailcrm);
$result = $retailcrm_inventories->load_stocks();
if ($retailcrm && $response['success'] == true) {
$product = new WC_Product_Simple($result[0]);
$this->assertInstanceOf('WC_Product', $product);
$this->assertEquals(10, $product->get_stock_quantity());
$this->assertContains($product->get_id(), $result);
$this->assertInternalType('array', $result);
} else {
$this->assertEquals(null, $result);
}
}
private function getResponseData()
{
return array(
'true' => array(
'success' => true,
'pagination' => array(
'limit' => 250,
'totalCount' => 1,
'currentPage' => 1,
'totalPageCount' => 1
),
'offers' => array(
array(
'id' => 1,
'xmlId' => 'xmlId',
'quantity' => 10
)
)
),
'false' => array(
'success' => false,
'errorMsg' => 'Forbidden'
)
);
}
public function dataProviderLoadStocks()
{
$this->setUp();
$response = $this->getResponseData();
return array(
array(
'retailcrm' => $this->apiMock,
'response' => $response['true']
),
array(
'retailcrm' => false,
'response' => $response['true']
),
array(
'retailcrm' => $this->apiMock,
'response' => $response['false']
),
array(
'retailcrm' => false,
'response' => $response['false']
)
);
}
}

View File

@ -0,0 +1,285 @@
<?php
class WC_Retailcrm_Orders_Test extends WC_Retailcrm_Test_Case_Helper
{
protected $apiMock;
protected $responseMock;
protected $order;
protected $options;
public function setUp()
{
$this->apiMock = $this->getMockBuilder('\WC_Retailcrm_Proxy')
->disableOriginalConstructor()
->setMethods(array(
'ordersGet',
'ordersUpload',
'ordersCreate',
'ordersEdit',
'customersGet',
'customersCreate',
'ordersPaymentCreate',
'ordersPaymentDelete'
))
->getMock();
parent::setUp();
}
/**
* @param $retailcrm
* @param $apiVersion
* @dataProvider dataProviderRetailcrm
*/
public function test_order_upload($retailcrm, $apiVersion)
{
$this->options = $this->setOptions($apiVersion);
$retailcrm_orders = new WC_Retailcrm_Orders($retailcrm);
$upload_orders = $retailcrm_orders->ordersUpload();
if ($retailcrm) {
$this->assertInternalType('array', $upload_orders);
} else {
$this->assertEquals(null, $upload_orders);
}
}
/**
* @param $retailcrm
* @param $apiVersion
* @dataProvider dataProviderRetailcrm
*/
public function test_order_create($retailcrm, $apiVersion)
{
$this->createTestOrder();
$this->options = $this->setOptions($apiVersion);
$retailcrm_orders = new WC_Retailcrm_Orders($retailcrm);
$order = $retailcrm_orders->orderCreate($this->order->get_id());
$order_send = $retailcrm_orders->getOrder();
if ($retailcrm) {
$this->assertInstanceOf('WC_Order', $order);
$this->assertInternalType('array', $order_send);
$this->assertArrayHasKey('status', $order_send);
$this->assertArrayHasKey('externalId', $order_send);
$this->assertArrayHasKey('firstName', $order_send);
$this->assertArrayHasKey('lastName', $order_send);
$this->assertArrayHasKey('email', $order_send);
$this->assertArrayHasKey('delivery', $order_send);
$this->assertArrayHasKey('code', $order_send['delivery']);
$this->assertArrayHasKey('address', $order_send['delivery']);
$this->assertArrayHasKey('index', $order_send['delivery']['address']);
$this->assertArrayHasKey('city', $order_send['delivery']['address']);
$this->assertEquals($this->order->get_id(), $order_send['externalId']);
$this->assertEquals('status1', $order_send['status']);
$this->assertEquals('Jeroen', $order_send['firstName']);
$this->assertEquals('Sormani', $order_send['lastName']);
$this->assertEquals('admin@example.org', $order_send['email']);
$this->assertEquals('US', $order_send['countryIso']);
$this->assertEquals('123456', $order_send['delivery']['address']['index']);
$this->assertEquals('WooCity', $order_send['delivery']['address']['city']);
$this->assertEquals('delivery5', $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->assertInternalType('array', $order_send['payments']);
$this->assertArrayHasKey('type', $order_send['payments'][0]);
$this->assertEquals('payment1', $order_send['payments'][0]['type']);
}
} else {
$this->assertEquals(null, $order);
}
}
/**
* @param $isSuccessful
* @param $retailcrm
* @param $apiVersion
* @dataProvider dataProviderUpdateOrder
*/
public function test_update_order($isSuccessful, $retailcrm, $apiVersion)
{
$this->createTestOrder();
$this->options = $this->setOptions($apiVersion);
if ($retailcrm && $apiVersion == 'v5') {
$responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
->disableOriginalConstructor()
->setMethods(array(
'isSuccessful'
))
->getMock();
$responseMock->expects($this->any())
->method('isSuccessful')
->willReturn($isSuccessful);
$retailcrm->expects($this->any())
->method('ordersEdit')
->willReturn($responseMock);
$retailcrm->expects($this->any())
->method('ordersPaymentDelete')
->willReturn($responseMock);
$response = $this->getResponseData($this->order->get_id());
$responseMock->setResponse($response);
$retailcrm->expects($this->any())
->method('ordersGet')
->willReturn($responseMock);
}
$retailcrm_orders = new WC_Retailcrm_Orders($retailcrm);
$order = $retailcrm_orders->updateOrder($this->order->get_id());
$order_send = $retailcrm_orders->getOrder();
if ($retailcrm) {
$this->assertInstanceOf('WC_Order', $order);
$this->assertInternalType('array', $order_send);
$this->assertArrayHasKey('status', $order_send);
$this->assertArrayHasKey('externalId', $order_send);
$this->assertArrayHasKey('firstName', $order_send);
$this->assertArrayHasKey('lastName', $order_send);
$this->assertArrayHasKey('email', $order_send);
$this->assertArrayHasKey('delivery', $order_send);
$this->assertArrayHasKey('code', $order_send['delivery']);
$this->assertArrayHasKey('address', $order_send['delivery']);
$this->assertArrayHasKey('index', $order_send['delivery']['address']);
$this->assertArrayHasKey('city', $order_send['delivery']['address']);
$this->assertEquals($this->order->get_id(), $order_send['externalId']);
$this->assertEquals('status1', $order_send['status']);
$this->assertEquals('Jeroen', $order_send['firstName']);
$this->assertEquals('Sormani', $order_send['lastName']);
$this->assertEquals('admin@example.org', $order_send['email']);
$this->assertEquals('US', $order_send['countryIso']);
$this->assertEquals('123456', $order_send['delivery']['address']['index']);
$this->assertEquals('WooCity', $order_send['delivery']['address']['city']);
$this->assertEquals('delivery5', $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();
$this->assertInternalType('array', $payment);
if (!empty($payment)) {
$this->assertArrayHasKey('type', $payment);
$this->assertArrayHasKey('amount', $payment);
$this->assertArrayHasKey('order', $payment);
$this->assertEquals('payment1', $payment['type']);
}
}
} else {
$this->assertEquals(null, $order);
}
}
public function dataProviderUpdateOrder()
{
$this->setUp();
return array(
array(
'is_successful' => true,
'retailcrm' => $this->apiMock,
'api_version' => 'v5'
),
array(
'is_successful' => true,
'retailcrm' => false,
'api_version' => 'v5'
),
array(
'is_successful' => false,
'retailcrm' => false,
'api_version' => 'v5'
),
array(
'is_successful' => false,
'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'
)
);
}
public function dataProviderRetailcrm()
{
$this->setUp();
return array(
array(
'retailcrm' => $this->apiMock,
'api_version' => 'v4'
),
array(
'retailcrm' => false,
'api_version' => 'v4'
),
array(
'retailcrm' => $this->apiMock,
'api_version' => 'v5'
),
array(
'retailcrm' => false,
'api_version' => 'v5'
)
);
}
private function createTestOrder()
{
$this->order = WC_Helper_Order::create_order(0);
// var_dump($this->order);
// $this->order = new WC_Order();
// $this->order->set_payment_method('bacs');
// $this->order->set_billing_first_name('testFirstName');
// $this->order->set_billing_last_name('testLastName');
// $this->order->set_billing_country('RU');
// $this->order->set_billing_address_1('testAddress1');
// $this->order->set_billing_city('testCity');
// $this->order->set_billing_postcode('111111');
// $this->order->set_billing_email('test@mail.com');
// $this->order->save();
}
private function getResponseData($externalId)
{
return array(
'success' => true,
'order' => array(
'payments' => array(
array(
'id' => 1,
'externalId' => $externalId,
'type' => 'payment2'
)
)
)
);
}
}

View File

@ -1,527 +0,0 @@
<?php
/**
* RetailCRM Integration.
*
* @package WC_Retailcrm_Base
* @category Integration
* @author RetailCRM
*/
if ( ! class_exists( 'WC_Retailcrm_Base' ) ) :
/**
* Class WC_Retailcrm_Base
*/
class WC_Retailcrm_Base extends WC_Integration {
protected $api_url;
protected $api_key;
/**
* Init and hook in the integration.
*/
public function __construct() {
//global $woocommerce;
if ( ! class_exists( 'WC_Retailcrm_Proxy' ) ) {
include_once( __DIR__ . '/api/class-wc-retailcrm-proxy.php' );
}
$this->id = 'integration-retailcrm';
$this->method_title = __('RetailCRM', 'retailcrm');
$this->method_description = __('Integration with eComlogic managament system.', 'retailcrm');
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Actions.
add_action( 'woocommerce_update_options_integration_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* Initialize integration settings form fields.
*/
public function init_form_fields() {
$this->form_fields = array(
array( 'title' => __( 'General Options', 'retailcrm' ), 'type' => 'title', 'desc' => '', 'id' => 'general_options' ),
'api_url' => array(
'title' => __( 'API URL', 'retailcrm' ),
'type' => 'text',
'description' => __( 'Enter with your API URL (https://yourdomain.ecomlogic.com).', 'retailcrm' ),
'desc_tip' => true,
'default' => ''
),
'api_key' => array(
'title' => __( 'API Key', 'retailcrm' ),
'type' => 'text',
'description' => __( 'Enter with your API Key. You can find this in eComlogic admin interface.', 'retailcrm' ),
'desc_tip' => true,
'default' => ''
)
);
$api_version_list = array('v4' => 'v4','v5' => 'v5');
$this->form_fields[] = array(
'title' => __( 'API settings', 'retailcrm' ),
'type' => 'title',
'description' => '',
'id' => 'api_options'
);
$this->form_fields['api_version'] = array(
'title' => __( 'API version', 'retailcrm' ),
'description' => __( 'Select the API version you want to use', 'retailcrm' ),
'css' => 'min-width:50px;',
'class' => 'select',
'type' => 'select',
'options' => $api_version_list,
'desc_tip' => true,
);
$this->form_fields[] = array(
'title' => __( 'Catalog settings', 'retailcrm' ),
'type' => 'title',
'description' => '',
'id' => 'catalog_options'
);
foreach (get_post_statuses() as $status_key => $status_value) {
$this->form_fields['p_' . $status_key] = array(
'title' => $status_value,
'label' => ' ',
'description' => '',
'class' => 'checkbox',
'type' => 'checkbox',
'desc_tip' => true,
);
}
if ($this->get_option( 'api_url' ) != '' && $this->get_option( 'api_key' ) != '') {
if (isset($_GET['page']) && $_GET['page'] == 'wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'integration') {
add_action('admin_print_footer_scripts', array($this, 'show_blocks'), 99);
$retailcrm = new WC_Retailcrm_Proxy(
$this->get_option( 'api_url' ),
$this->get_option( 'api_key' ),
$this->get_option( 'api_version')
);
/**
* Order methods options
*/
$order_methods_option = array();
$order_methods_list = $retailcrm->orderMethodsList();
if ($order_methods_list->isSuccessful()) {
foreach ($order_methods_list['orderMethods'] as $order_method) {
if ($order_method['active'] == false) {
continue;
}
$order_methods_option[$order_method['code']] = $order_method['name'];
}
$this->form_fields[] = array(
'title' => __('Order methods', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'order_methods_options'
);
$this->form_fields['order_methods'] = array(
'label' => ' ',
'title' => __('Ordering methods available for downloading from eComlogic', 'retailcrm'),
'class' => '',
'type' => 'multiselect',
'description' => __('Select the order methods that will be uploaded from eComlogic to site', 'retailcrm'),
'options' => $order_methods_option,
'select_buttons' => true
);
}
/**
* Shipping options
*/
$shipping_option_list = array();
$retailcrm_shipping_list = $retailcrm->deliveryTypesList();
if ($retailcrm_shipping_list->isSuccessful()) {
foreach ($retailcrm_shipping_list['deliveryTypes'] as $retailcrm_shipping_type) {
$shipping_option_list[$retailcrm_shipping_type['code']] = $retailcrm_shipping_type['name'];
}
$wc_shipping_list = get_wc_shipping_methods();
$this->form_fields[] = array(
'title' => __('Shipping methods', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'shipping_options'
);
foreach ( $wc_shipping_list as $shipping_code => $shipping ) {
if ( isset( $shipping['enabled'] ) && $shipping['enabled'] == 'yes' ) {
$this->form_fields[$shipping_code] = array(
'title' => __($shipping['title'], 'woocommerce'),
'description' => __($shipping['description'], 'woocommerce'),
'css' => 'min-width:350px;',
'class' => 'select',
'type' => 'select',
'options' => $shipping_option_list,
'desc_tip' => true,
);
}
}
}
/**
* Payment options
*/
$payment_option_list = array();
$retailcrm_payment_list = $retailcrm->paymentTypesList();
if ($retailcrm_payment_list->isSuccessful()) {
foreach ($retailcrm_payment_list['paymentTypes'] as $retailcrm_payment_type) {
$payment_option_list[$retailcrm_payment_type['code']] = $retailcrm_payment_type['name'];
}
$wc_payment = new WC_Payment_Gateways();
$this->form_fields[] = array(
'title' => __('Payment methods', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'payment_options'
);
foreach ( $wc_payment->payment_gateways as $payment ) {
if ( isset( $payment->enabled ) && $payment->enabled == 'yes' ) {
$key = $payment->id;
$name = $key;
$this->form_fields[$name] = array(
'title' => __($payment->method_title, 'woocommerce'),
'description' => __($payment->method_description, 'woocommerce'),
'css' => 'min-width:350px;',
'class' => 'select',
'type' => 'select',
'options' => $payment_option_list,
'desc_tip' => true,
);
}
}
}
/**
* Statuses options
*/
$statuses_option_list = array();
$retailcrm_statuses_list = $retailcrm->statusesList();
if ($retailcrm_statuses_list->isSuccessful()) {
foreach ($retailcrm_statuses_list['statuses'] as $retailcrm_status) {
$statuses_option_list[$retailcrm_status['code']] = $retailcrm_status['name'];
}
$wc_statuses = wc_get_order_statuses();
$this->form_fields[] = array(
'title' => __('Statuses', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'statuses_options'
);
foreach ( $wc_statuses as $idx => $name ) {
$uid = str_replace('wc-', '', $idx);
$this->form_fields[$uid] = array(
'title' => __($name, 'woocommerce'),
'css' => 'min-width:350px;',
'class' => 'select',
'type' => 'select',
'options' => $statuses_option_list,
'desc_tip' => true,
);
}
}
/**
* Inventories options
*/
$this->form_fields[] = array(
'title' => __('Inventories settings', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'invent_options'
);
$this->form_fields['sync'] = array(
'label' => __('Sync inventories', 'retailcrm'),
'title' => __('Inventories', 'retailcrm'),
'class' => 'checkbox',
'type' => 'checkbox',
'description' => __('Check this checkbox if you want to unload the rest of the products from CRM to site.', 'retailcrm')
);
/**
* UA options
*/
$this->form_fields[] = array(
'title' => __('UA settings', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'invent_options'
);
$this->form_fields['ua'] = array(
'label' => __('Activate UA', 'retailcrm'),
'title' => __('UA', 'retailcrm'),
'class' => 'checkbox',
'type' => 'checkbox',
'description' => __('Check this checkbox if you want to unload information to UA.', 'retailcrm')
);
$this->form_fields['ua_code'] = array(
'title' => __('UA code', 'retailcrm'),
'class' => 'input',
'type' => 'input'
);
$this->form_fields['ua_custom'] = array(
'title' => __('Custom parameter', 'retailcrm'),
'class' => 'input',
'type' => 'input'
);
/**
* Uploads options
*/
$options = array_filter(get_option( 'woocommerce_integration-retailcrm_settings' ));
if (!isset($options['uploads'])) {
$this->form_fields[] = array(
'title' => __('Uploads settings', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'upload_options'
);
$this->form_fields['upload-button'] = array(
'label' => __('Upload', 'retailcrm'),
'title' => __('Upload all customers and orders', 'retailcrm' ),
'type' => 'button',
'description' => __('Batch unloading of existing customers and orders.', 'retailcrm' ),
'desc_tip' => true,
'id' => 'uploads-retailcrm'
);
}
/*
* Generate icml file
*/
$this->form_fields[] = array(
'title' => __( 'Generate ICML catalog', 'retailcrm' ),
'type' => 'title',
'description' => '',
'id' => 'icml_options'
);
$this->form_fields[] = array(
'label' => __('Generate', 'retailcrm'),
'title' => __('Generate ICML', 'retailcrm'),
'type' => 'button',
'description' => __('This functionality allows you to generate a catalog of products for downloading to CRM.', 'retailcrm'),
'desc_tip' => true,
'id' => 'icml-retailcrm'
);
}
}
}
/**
* Generate html button
*
* @param string $key
* @param array $data
*
* @return string
*/
public function generate_button_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$defaults = array(
'class' => 'button-secondary',
'css' => '',
'custom_attributes' => array(),
'desc_tip' => false,
'description' => '',
'title' => '',
);
$data = wp_parse_args( $data, $defaults );
ob_start();
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<?php echo $this->get_tooltip_html( $data ); ?>
</th>
<td class="forminp">
<fieldset>
<legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['label'] ); ?></span></legend>
<button id="<?php echo $data['id']; ?>" class="<?php echo esc_attr( $data['class'] ); ?>" type="button" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" <?php echo $this->get_custom_attribute_html( $data ); ?>><?php echo wp_kses_post( $data['label'] ); ?></button>
<?php echo $this->get_description_html( $data ); ?>
</fieldset>
</td>
</tr>
<?php
return ob_get_clean();
}
/**
* Generate html title block settings
*
* @param string $key
* @param array $data
*
* @return string
*/
public function generate_heading_html($key, $data) {
$field_key = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'class' => '',
);
$data = wp_parse_args( $data, $defaults );
ob_start();
?>
</table>
<h2 class="wc-settings-sub-title retailcrm_hidden <?php echo esc_attr( $data['class'] ); ?>" id="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <span style="opacity:0.5;float: right;">&#11015;</span></h2>
<?php if ( ! empty( $data['description'] ) ) : ?>
<p><?php echo wp_kses_post( $data['description'] ); ?></p>
<?php endif; ?>
<table class="form-table" style="display: none;">
<?php
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 ($response && $response->isSuccessful()) {
if (!in_array($versionMap[$value], $response['versions'])) {
WC_Admin_Settings::add_error( esc_html__( 'The selected version of the API is unavailable', 'retailcrm' ) );
$value = '';
}
return $value;
}
}
/**
* Validate API url
*
* @param string $key
* @param string $value
*
* @return string
*/
public function validate_api_url_field( $key, $value ) {
$post = $this->get_post_data();
$api = new WC_Retailcrm_Proxy(
$value,
$post[$this->plugin_id . $this->id . '_api_key']
);
$response = $api->apiVersions();
if ($response == NULL) {
WC_Admin_Settings::add_error( esc_html__( 'Enter the correct CRM address', 'retailcrm' ) );
$value = '';
}
return $value;
}
/**
* Validate API key
*
* @param string $key
* @param string $value
*
* @return string
*/
public function validate_api_key_field( $key, $value ) {
$post = $this->get_post_data();
$api = new WC_Retailcrm_Proxy(
$post[$this->plugin_id . $this->id . '_api_url'],
$value
);
$response = $api->apiVersions();
if (!is_object($response)) {
$value = '';
}
if (!$response->isSuccessful()) {
WC_Admin_Settings::add_error( esc_html__( 'Enter the correct API key', 'retailcrm' ) );
$value = '';
}
return $value;
}
/**
* Scritp show|hide block settings
*/
function show_blocks() {
?>
<script type="text/javascript">
jQuery('h2.retailcrm_hidden').hover().css({
'cursor':'pointer',
'width':'300px'
});
jQuery('h2.retailcrm_hidden').toggle(
function() {
jQuery(this).next('table.form-table').show(100);
jQuery(this).find('span').html('&#11014;');
},
function() {
jQuery(this).next('table.form-table').hide(100);
jQuery(this).find('span').html('&#11015;');
}
);
</script>
<?php
}
}
endif;

View File

@ -1,151 +0,0 @@
<?php
/**
* RetailCRM Integration.
*
* @package WC_Retailcrm_Customers
* @category Integration
* @author RetailCRM
*/
if ( ! class_exists( 'WC_Retailcrm_Customers' ) ) :
/**
* Class WC_Retailcrm_Customers
*/
class WC_Retailcrm_Customers
{
public function __construct()
{
$this->retailcrm_settings = get_option( 'woocommerce_integration-retailcrm_settings' );
if ( ! class_exists( 'WC_Retailcrm_Proxy' ) ) {
include_once( WP_PLUGIN_DIR . '/woo-retailcrm/include/api/class-wc-retailcrm-proxy.php' );
}
$this->retailcrm = new WC_Retailcrm_Proxy(
$this->retailcrm_settings['api_url'],
$this->retailcrm_settings['api_key'],
$this->retailcrm_settings['api_version']
);
}
/**
* Upload customers to CRM
*
* @return void
*/
public function customersUpload()
{
$users = get_users();
$data_customers = array();
foreach ($users as $user) {
if (!in_array('customer', $user->roles)) {
continue;
}
$customer = new WC_Customer($user->ID);
$firstName = $customer->get_first_name();
$data_customer = array(
'createdAt' => $user->data->user_registered,
'externalId' => $user->ID,
'firstName' => $firstName ? $firstName : $customer->get_username(),
'lastName' => $customer->get_last_name(),
'email' => $user->data->user_email,
'address' => array(
'index' => $customer->get_billing_postcode(),
'countryIso' => $customer->get_billing_country(),
'region' => $customer->get_billing_state(),
'city' => $customer->get_billing_city(),
'text' => $customer->get_billing_address_1() . ',' . $customer->get_billing_address_2()
)
);
if ($customer->get_billing_phone()) {
$data_customer['phones'][] = array(
'number' => $customer->get_billing_phone()
);
}
$data_customers[] = $data_customer;
}
$data = array_chunk($data_customers, 50);
foreach ($data as $array_customers) {
$this->retailcrm->customersUpload($array_customers);
}
}
/**
* Create customer in CRM
*
* @param int $customer_id
*
* @return void
*/
public function createCustomer($customer_id)
{
$customer = new WC_Customer($customer_id);
if ($customer->get_role() == 'customer'){
$data_customer = $this->processCustomer($customer);
$this->retailcrm->customersCreate($data_customer);
}
}
/**
* Edit customer in CRM
*
* @param int $customer_id
*
* @return void
*/
public function updateCustomer($customer_id)
{
$customer = new WC_Customer($customer_id);
if ($customer->get_role() == 'customer'){
$data_customer = $this->processCustomer($customer);
$this->retailcrm->customersEdit($data_customer);
}
}
/**
* Process customer
*
* @param object $customer
*
* @return array $data_customer
*/
protected function processCustomer($customer)
{
$createdAt = $customer->get_date_created();
$firstName = $customer->get_first_name();
$data_customer = array(
'createdAt' => $createdAt->date('Y-m-d H:i:s'),
'externalId' => $customer->get_id(),
'firstName' => $firstName ? $firstName : $customer->get_username(),
'lastName' => $customer->get_last_name(),
'email' => $customer->get_email(),
'address' => array(
'index' => $customer->get_billing_postcode(),
'countryIso' => $customer->get_billing_country(),
'region' => $customer->get_billing_state(),
'city' => $customer->get_billing_city(),
'text' => $customer->get_billing_address_1() . ',' . $customer->get_billing_address_2()
)
);
if ($customer->get_billing_phone()) {
$data_customer['phones'][] = array(
'number' => $customer->get_billing_phone()
);
}
return $data_customer;
}
}
endif;

View File

@ -1,70 +0,0 @@
<?php
/**
* RetailCRM Integration.
*
* @package WC_Retailcrm_Inventories
* @category Integration
* @author RetailCRM
*/
if ( ! class_exists( 'WC_Retailcrm_Inventories' ) ) :
/**
* Class WC_Retailcrm_Inventories
*/
class WC_Retailcrm_Inventories
{
public function __construct()
{
$this->retailcrm_settings = get_option( 'woocommerce_integration-retailcrm_settings' );
if ( ! class_exists( 'WC_Retailcrm_Proxy' ) ) {
include_once( WP_PLUGIN_DIR . '/woo-retailcrm/include/api/class-wc-retailcrm-proxy.php' );
}
$this->retailcrm = new WC_Retailcrm_Proxy(
$this->retailcrm_settings['api_url'],
$this->retailcrm_settings['api_key'],
$this->retailcrm_settings['api_version']
);
}
public function load_stocks()
{
$page = 1;
do {
$result = $this->retailcrm->storeInventories(array(), $page, 250);
$totalPageCount = $result['pagination']['totalPageCount'];
$page++;
foreach ($result['offers'] as $offer) {
if (isset($offer['externalId'])) {
$product = wc_get_product($offer['externalId']);
if ($product != false) {
if ($product->get_type() == 'variable') {
continue;
}
update_post_meta($offer['externalId'], '_manage_stock', 'yes');
$product->set_stock_quantity($offer['quantity']);
$product->save();
}
}
}
} while ($page <= $totalPageCount);
}
public function updateQuantity()
{
$options = array_filter(get_option( 'woocommerce_integration-retailcrm_settings' ));
if ($options['sync'] == 'yes') {
$this->load_stocks();
} else {
return false;
}
}
}
endif;

View File

@ -1,475 +0,0 @@
<?php
/**
* Version: 2.1.4
* Plugin Name: WooCommerce RetailCRM
* Plugin URI: https://wordpress.org/plugins/woo-retailcrm/
* Description: Integration plugin for WooCommerce & RetailCRM
* Author: RetailDriver LLC
* Author URI: http://retailcrm.ru/
* Text Domain: retailcrm
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if (!class_exists( 'WC_Integration_Retailcrm')) :
/**
* Class WC_Integration_Retailcrm
*/
class WC_Integration_Retailcrm {
/**
* Construct the plugin.
*/
public function __construct() {
add_action( 'plugins_loaded', array( $this, 'init' ) );
}
/**
* Initialize the plugin.
*/
public function init() {
if ( class_exists( 'WC_Integration' ) ) {
include_once 'include/class-wc-retailcrm-base.php';
include_once 'include/functions.php';
add_filter( 'woocommerce_integrations', array( $this, 'add_integration' ) );
} else {
// throw an admin error if you like
}
}
/**
* Add a new integration to WooCommerce.
*
* @param $integrations
*
* @return array
*/
public function add_integration( $integrations ) {
$integrations[] = 'WC_Retailcrm_Base';
return $integrations;
}
}
$WC_Integration_Retailcrm = new WC_Integration_Retailcrm( __FILE__ );
endif;
/*
* Check icml custom class
*/
function check_custom_icml()
{
if (file_exists( WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-icml.php' )) {
$file = WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-icml.php';
} else {
$file = __DIR__ . '/include/class-wc-retailcrm-icml.php';
}
return $file;
}
/*
* Check orders custom class
*/
function check_custom_orders()
{
if (file_exists( WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-orders.php' )) {
$file = WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-orders.php';
} else {
$file = __DIR__ . '/include/class-wc-retailcrm-orders.php';
}
return $file;
}
/*
* Check customers custom class
*/
function check_custom_customers()
{
if (file_exists( WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-customers.php' )) {
$file = WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-customers.php';
} else {
$file = __DIR__ . '/include/class-wc-retailcrm-customers.php';
}
return $file;
}
/*
* Check inventories custom class
*/
function check_custom_inventories()
{
if (file_exists( WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-inventories.php' )) {
$file = WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-inventories.php';
} else {
$file = __DIR__ . '/include/class-wc-retailcrm-inventories.php';
}
return $file;
}
/*
* Check history custom class
*/
function check_custom_history()
{
if (file_exists( WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-history.php' )) {
$file = WP_CONTENT_DIR . '/retailcrm-custom/class-wc-retailcrm-history.php';
} else {
$file = __DIR__ . '/include/class-wc-retailcrm-history.php';
}
return $file;
}
/**
* Activation action
*/
function retailcrm_install()
{
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option( 'active_plugins')))) {
generate_icml();
}
}
/**
* Deactivation action
*/
function retailcrm_deactivation()
{
if ( wp_next_scheduled ( 'retailcrm_icml' )) {
wp_clear_scheduled_hook('retailcrm_icml');
}
}
/**
* Load stocks from CRM
*/
function load_stocks()
{
if ( ! class_exists( 'WC_Retailcrm_Inventories' ) ) {
include_once( check_custom_inventories() );
}
$inventories = new WC_Retailcrm_Inventories();
$inventories->updateQuantity();
}
/**
* Generate ICML file
*/
function generate_icml()
{
if ( ! class_exists( 'WC_Retailcrm_Icml' ) ) {
include_once( check_custom_icml() );
}
$icml = new WC_Retailcrm_Icml();
$icml->generate();
}
/**
* Create order
*
* @param $order_id
*/
function retailcrm_process_order($order_id)
{
if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) {
include_once( check_custom_orders() );
}
$order_class = new WC_Retailcrm_Orders();
$order_class->orderCreate($order_id);
}
/**
* Update order status
*
* @param $order_id
*/
function retailcrm_update_order_status($order_id)
{
if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) {
include_once( check_custom_orders() );
}
$order_class = new WC_Retailcrm_Orders();
$order_class->orderUpdateStatus($order_id);
}
/**
* Update order payment
*
* @param $order_id
*/
function retailcrm_update_order_payment($order_id)
{
if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) {
include_once( check_custom_orders() );
}
$order_class = new WC_Retailcrm_Orders();
$order_class->orderUpdatePayment($order_id);
}
/**
* Update order items
*
* @param $order_id, $data
*/
function retailcrm_update_order_items($order_id, $data)
{
if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) {
include_once( check_custom_orders() );
}
$order_class = new WC_Retailcrm_Orders();
$order_class->orderUpdateItems($order_id, $data);
}
function retailcrm_history_get()
{
if ( ! class_exists( 'WC_Retailcrm_History' ) ) {
include_once( check_custom_history() );
}
$history_class = new WC_Retailcrm_History();
$history_class->getHistory();
}
function create_customer($customer_id) {
if ( ! class_exists( 'WC_Retailcrm_Customers' ) ) {
include_once( check_custom_customers() );
}
$customer_class = new WC_Retailcrm_Customers();
$customer_class->createCustomer($customer_id);
}
function update_customer($customer_id) {
if ( ! class_exists( 'WC_Retailcrm_Customers' ) ) {
include_once( check_custom_customers() );
}
$customer_class = new WC_Retailcrm_Customers();
$customer_class->updateCustomer($customer_id);
}
function register_icml_generation() {
// Make sure this event hasn't been scheduled
if( !wp_next_scheduled( 'retailcrm_icml' ) ) {
// Schedule the event
wp_schedule_event( time(), 'three_hours', 'retailcrm_icml' );
}
}
function register_retailcrm_history() {
// Make sure this event hasn't been scheduled
if( !wp_next_scheduled( 'retailcrm_history' ) ) {
// Schedule the event
wp_schedule_event( time(), 'five_minutes', 'retailcrm_history' );
}
}
function check_inventories() {
if( !wp_next_scheduled( 'retailcrm_inventories' ) ) {
// Schedule the event
wp_schedule_event( time(), 'fiveteen_minutes', 'retailcrm_inventories' );
}
}
function filter_cron_schedules($param) {
return array(
'five_minutes' => array(
'interval' => 300, // seconds
'display' => __('Every 5 minutes')
),
'three_hours' => array(
'interval' => 10800, // seconds
'display' => __('Every 3 hours')
),
'fiveteen_minutes' => array(
'interval' => 900, // seconds
'display' => __('Every 15 minutes')
)
);
}
function upload_to_crm() {
if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) {
include_once( check_custom_orders() );
}
if ( ! class_exists( 'WC_Retailcrm_Customers' ) ) {
include_once( check_custom_customers() );
}
$options = array_filter(get_option( 'woocommerce_integration-retailcrm_settings' ));
$orders = new WC_Retailcrm_Orders();
$customers = new WC_Retailcrm_Customers();
$customers->customersUpload();
$orders->ordersUpload();
$options['uploads'] = 'yes';
update_option('woocommerce_integration-retailcrm_settings', $options);
}
function ajax_upload() {
$ajax_url = admin_url('admin-ajax.php');
?>
<script type="text/javascript" >
jQuery('#uploads-retailcrm').bind('click', function() {
jQuery.ajax({
type: "POST",
url: '<?php echo $ajax_url; ?>?action=do_upload',
success: function (response) {
alert('<?php echo __('Customers and orders were unloaded', 'retailcrm'); ?>');
console.log('AJAX response : ',response);
}
});
});
</script>
<?php
}
function ajax_generate_icml() {
$ajax_url = admin_url('admin-ajax.php');
?>
<script type="text/javascript" >
jQuery('#icml-retailcrm').bind('click', function() {
jQuery.ajax({
type: "POST",
url: '<?php echo $ajax_url; ?>?action=generate_icml',
success: function (response) {
alert('<?php echo __('Catalog were generated', 'retailcrm'); ?>');
console.log('AJAX response : ',response);
}
});
});
</script>
<?php
}
function update_order($order_id) {
if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) {
include_once( check_custom_orders() );
}
$order_class = new WC_Retailcrm_Orders();
$order_class->updateOrder($order_id);
}
function initialize_analytics() {
$options = get_option('woocommerce_integration-retailcrm_settings');
if ($options && is_array($options)) {
$options = array_filter($options);
if (isset($options['ua']) && $options['ua'] == 'yes') {
?>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '<?php echo $options['ua_code']; ?>', 'auto');
function getRetailCrmCookie(name) {
var matches = document.cookie.match(new RegExp(
'(?:^|; )' + name + '=([^;]*)'
));
return matches ? decodeURIComponent(matches[1]) : '';
}
ga('set', 'dimension<?php echo $options['ua_custom']; ?>', getRetailCrmCookie('_ga'));
ga('send', 'pageview');
</script>
<?php
}
}
}
function send_analytics() {
$options = get_option('woocommerce_integration-retailcrm_settings');
if ($options && is_array($options)) {
$options = array_filter($options);
if (isset($_GET['key']) && isset($options['ua']) && $options['ua'] == 'yes') {
$orderid = wc_get_order_id_by_order_key($_GET['key']);
$order = new WC_Order($orderid);
foreach ($order->get_items() as $item) {
$uid = ($item['variation_id'] > 0) ? $item['variation_id'] : $item['product_id'] ;
$_product = wc_get_product($uid);
if ($_product) {
$order_item = array(
'id' => $uid,
'name' => $item['name'],
'price' => (float)$_product->get_price(),
'quantity' => $item['qty'],
);
$order_items[] = $order_item;
}
}
$url = parse_url(get_site_url());
$domain = $url['host'];
?>
<script type="text/javascript">
ga('require', 'ecommerce', 'ecommerce.js');
ga('ecommerce:addTransaction', {
'id': <?php echo $order->get_id(); ?>,
'affiliation': '<?php echo $domain; ?>',
'revenue': <?php echo $order->get_total(); ?>,
'shipping': <?php echo $order->get_total_tax(); ?>,
'tax': <?php echo $order->get_shipping_total(); ?>
});
<?php
foreach ($order_items as $item) {?>
ga('ecommerce:addItem', {
'id': <?php echo $order->get_id(); ?>,
'sku': <?php echo $item['id']; ?>,
'name': '<?php echo $item['name']; ?>',
'price': <?php echo $item['price']; ?>,
'quantity': <?php echo $item['quantity']; ?>
});
<?php
}?>
ga('ecommerce:send');
</script>
<?php
}
}
}
function retailcrm_load_plugin_textdomain() {
load_plugin_textdomain('retailcrm', FALSE, basename( dirname( __FILE__ ) ) . '/languages/');
}
register_activation_hook( __FILE__, 'retailcrm_install' );
register_deactivation_hook( __FILE__, 'retailcrm_deactivation' );
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option( 'active_plugins')))) {
add_action('plugins_loaded', 'retailcrm_load_plugin_textdomain');
add_filter('cron_schedules', 'filter_cron_schedules', 10, 1);
add_action('woocommerce_checkout_order_processed', 'retailcrm_process_order', 10, 1);
add_action('retailcrm_history', 'retailcrm_history_get');
add_action('retailcrm_icml', 'generate_icml');
add_action('retailcrm_inventories', 'load_stocks');
add_action('init', 'check_inventories');
add_action('init', 'register_icml_generation');
add_action('init', 'register_retailcrm_history');
add_action('wp_ajax_do_upload', 'upload_to_crm');
add_action('wp_ajax_generate_icml', 'generate_icml');
add_action('admin_print_footer_scripts', 'ajax_upload', 99);
add_action('admin_print_footer_scripts', 'ajax_generate_icml', 99);
add_action('woocommerce_created_customer', 'create_customer', 10, 1);
add_action('woocommerce_update_customer', 'update_customer', 10, 1);
add_action('woocommerce_update_order', 'update_order', 11, 1);
add_action('wp_print_scripts', 'initialize_analytics', 98);
add_action('wp_print_footer_scripts', 'send_analytics', 99);
}