Compare commits
7 commits
Author | SHA1 | Date | |
---|---|---|---|
|
4363cccc40 | ||
|
3610cec728 | ||
|
bce545979c | ||
|
cd57de01e6 | ||
|
b2cc25e716 | ||
|
63ca5015c9 | ||
|
dee71bf631 |
16 changed files with 561 additions and 387 deletions
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -1,3 +1,24 @@
|
|||
## 2025-02-19 4.8.21
|
||||
* Fix version of module
|
||||
|
||||
## 2025-02-18 4.8.20
|
||||
* Add returned types for methods offsetExists, offsetSet, offsetUnset in WC_Retailcrm_Response
|
||||
|
||||
## 2025-02-04 4.8.19
|
||||
* Optimization of order unloading
|
||||
|
||||
## 2025-02-03 4.8.18
|
||||
* Added additional parameters to GET requests
|
||||
|
||||
## 2025-01-21 4.8.17
|
||||
* Fix deploy
|
||||
|
||||
## 2025-01-13 4.8.16
|
||||
* Fix tests svn error
|
||||
|
||||
## 2024-12-19 4.8.15
|
||||
* Fix uploading archive in CRM using console script
|
||||
|
||||
## 2024-11-07 4.8.14
|
||||
* The method for determining the stock quantity has been optimized
|
||||
|
||||
|
|
6
Makefile
6
Makefile
|
@ -5,7 +5,8 @@ ARCHIVE_NAME = '/tmp/retailcrm-'$(VERSION)'.zip'
|
|||
.PHONY: test
|
||||
|
||||
svn_clone:
|
||||
mkdir /tmp/svn_plugin_dir
|
||||
sudo apt install subversion
|
||||
mkdir -p /tmp/svn_plugin_dir
|
||||
svn co $(SVNREPOURL) /tmp/svn_plugin_dir --no-auth-cache
|
||||
|
||||
svn_push: /tmp/svn_plugin_dir
|
||||
|
@ -27,7 +28,8 @@ compile_pot:
|
|||
msgfmt resources/pot/retailcrm-es_ES.pot -o src/languages/retailcrm-es_ES.mo
|
||||
|
||||
install:
|
||||
mkdir coverage
|
||||
sudo apt install subversion
|
||||
mkdir -p coverage
|
||||
bash tests/bin/install.sh $(DB_NAME) $(DB_USER) $(DB_HOST) $(DB_PASS) $(WP_VERSION) $(WC_VERSION)
|
||||
|
||||
test:
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
4.8.14
|
||||
4.8.21
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"require-dev": {
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"phpunit/phpunit": "6.*",
|
||||
"phpunit/phpunit": "7.*",
|
||||
"yoast/phpunit-polyfills": "1.x-dev"
|
||||
}
|
||||
}
|
||||
|
|
681
composer.lock
generated
681
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -20,23 +20,45 @@
|
|||
В модуле возможно сделать необходимые кастомизация для генерации ICML-файла в желаемом формате <br>
|
||||
|
||||
**Выгрузка архивных данных** <br>
|
||||
Ранее модуль *(до версии 4.3.3)* мог выгружать не более 700-800 архивных заказов *(т.к. выгрузка происходила по web-хиту, работа скрипта была ограничена и не все данные успевали прогрузится в CRM)*, этот момент был доработан *(#70113)* и сейчас модуль загружает из Woo в CRM все присутствующие заказы пачками по 50 шт *(сделано для того, чтобы у слабых серверов не возникало проблем с загрузкой)*.
|
||||
Также заказы архивные данные можно выгрузить с использованием консольного скрипта: нужно скачать этот скрипт, загрузить его в корень сайта на сервере
|
||||
**upload_to_crm.php** *(название файла)*
|
||||
|
||||
<?php
|
||||
/** Load WordPress Bootstrap **/
|
||||
require_once dirname( __FILE__ ) . '/wp-load.php';
|
||||
do_action("wp_ajax_do_upload");
|
||||
После чего в командной строке ввести команду
|
||||
Ранее модуль мог выгружать не более 700-800 архивных заказов *(т.к. выгрузка происходила по web-хиту, работа скрипта была ограничена и не все данные успевали прогрузится в CRM)*.<br>
|
||||
Сейчас архивные данные можно выгрузить в CRM с использованием консольного скрипта. Этот скрипт позволяет выгружать все архивные заказы и данные о клиентах без ограничения на количество записей. Процесс выгрузки выполняется пакетами по 50 заказов или 50 клиентов за раз. <br>
|
||||
После завершения обработки каждой пачки выводится ее порядковый номер, что позволяет отслеживать прогресс работы скрипта. Если во время выгрузки возникает ошибка, скрипт можно перезапустить с той страницы, где произошел сбой, что минимизирует потерю данных и время на повторную выгрузку.<br>
|
||||
|
||||
> php upload_to_crm.php
|
||||
Для запуска выгрузки нужно:<br>
|
||||
|
||||
тем самым запустить выполнение скрипта. Для последнего действия нужно использовать ssh.
|
||||
После выполнения данных действий дожидаемся завершение работы. При этом информация об ошибках при выгрузке заказов будет фиксироваться в разделе WooCommerce "Статус", "Журналы".
|
||||
Как скрипт завершит работу в командной строке появляется возможность ввести новую команду.
|
||||
1. В корневой директории вашего сайта (по умолчанию - */var/www/html*) разместить файл **upload_to_crm.php** и вставить в него код:
|
||||
|
||||
**Работа с зонами доставки** *(WooCommerce - Настройки - Доставка - Зоны доставки)*
|
||||
```
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/wp-load.php';
|
||||
|
||||
$options = getopt('',['entity::','page::']);
|
||||
|
||||
do_action('wp_console_upload', $options['entity'] ?? '', (int) $options['page'] ?? 0);
|
||||
```
|
||||
2. После чего в командной строке ввести команду для запуска скрипта: <br>
|
||||
|
||||
> php upload_to_crm.php --entity=orders/customers/full_upload --page=номер страницы
|
||||
|
||||
Параметры для выгрузки:<br>
|
||||
|
||||
**--entity**: Указывает, какие данные выгружать. Данный параметр **является обязательным**. Возможные значения:
|
||||
|
||||
- **orders**: архивные заказы;
|
||||
- **customers**: архивные клиенты;
|
||||
- **full_upload**: полная выгрузка всех заказов и клиентов (весь архив).
|
||||
|
||||
**--page**: Указывает номер страницы для выгрузки. Каждая страница содержит 50 заказов или клиентов. Нумерация страниц начинается с 0.<br>
|
||||
|
||||
Пример:
|
||||
|
||||
> php upload_to_crm.php --entity=orders --page=3
|
||||
|
||||
В этом примере будет выгружен архив заказов, начиная с 3-й страницы.
|
||||
|
||||
**Работа с зонами доставки** *(WooCommerce - Настройки - Доставка - Зоны доставки)*
|
||||
|
||||
С зонами доставки модуль не работает
|
||||
|
||||
|
|
|
@ -77,9 +77,10 @@ class WC_Retailcrm_Request
|
|||
'cms_version' => function_exists('get_bloginfo') ? get_bloginfo('version') : '',
|
||||
'woo_version' => WC()->version ?? '',
|
||||
'php_version' => function_exists('phpversion') ? phpversion() : '',
|
||||
'module_version' => WC_Integration_Retailcrm::MODULE_VERSION,
|
||||
'module_version' => WC_Integration_Retailcrm::MODULE_VERSION,
|
||||
'ga_option_is_active' => getOptionByCode('ua') === WC_Retailcrm_Abstracts_Settings::YES,
|
||||
])
|
||||
: $parameters = array_merge($this->defaultParameters, $parameters);
|
||||
: array_merge($this->defaultParameters, $parameters);
|
||||
|
||||
$url = $this->url . $path;
|
||||
|
||||
|
|
|
@ -120,9 +120,8 @@ class WC_Retailcrm_Response implements \ArrayAccess
|
|||
* @param mixed $value value
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
public function offsetSet($offset, $value): void
|
||||
{
|
||||
throw new \BadMethodCallException('This activity not allowed');
|
||||
}
|
||||
|
@ -133,9 +132,8 @@ class WC_Retailcrm_Response implements \ArrayAccess
|
|||
* @param mixed $offset offset
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
* @return void
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
public function offsetUnset($offset): void
|
||||
{
|
||||
throw new \BadMethodCallException('This call not allowed');
|
||||
}
|
||||
|
@ -145,9 +143,8 @@ class WC_Retailcrm_Response implements \ArrayAccess
|
|||
*
|
||||
* @param mixed $offset offset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
return isset($this->response[$offset]);
|
||||
}
|
||||
|
@ -156,10 +153,10 @@ class WC_Retailcrm_Response implements \ArrayAccess
|
|||
* Get offset
|
||||
*
|
||||
* @param mixed $offset offset
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return mixed
|
||||
* TODO PHP < 8.0 не поддерживает тип mixed. Оператор | для перечисления типов также не поддерживается.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
|
|
|
@ -111,6 +111,7 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
|||
add_action('admin_enqueue_scripts', [$this, 'include_files_for_admin'], 101);
|
||||
add_action('woocommerce_new_order', [$this, 'fill_array_create_orders'], 11, 1);
|
||||
add_action('shutdown', [$this, 'create_order'], -2);
|
||||
add_action('wp_console_upload', [$this, 'console_upload'], 99, 2);
|
||||
|
||||
if (
|
||||
!$this->get_option('deactivate_update_order')
|
||||
|
@ -174,6 +175,10 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
|||
$this->activateModule();
|
||||
}
|
||||
|
||||
public function console_upload($entity, $page = 0)
|
||||
{
|
||||
$this->uploader->uploadConsole($entity, $page);
|
||||
}
|
||||
/**
|
||||
* Init settings fields
|
||||
*/
|
||||
|
|
|
@ -602,6 +602,32 @@ if (!class_exists('WC_Retailcrm_Orders')) :
|
|||
);
|
||||
}
|
||||
|
||||
public function processOrderForUpload($orderIds)
|
||||
{
|
||||
$ordersForUpload = [];
|
||||
$errorOrders = [];
|
||||
|
||||
foreach ($orderIds as $orderId) {
|
||||
try {
|
||||
$this->order = [];
|
||||
$this->processOrder(wc_get_order($orderId));
|
||||
|
||||
if ($this->order === []) {
|
||||
throw new \RuntimeException(sprintf('Order %s is not uploaded', $orderId));
|
||||
}
|
||||
|
||||
$ordersForUpload[] = $this->order;
|
||||
} catch (Throwable $exception) {
|
||||
$errorOrders[$orderId] = sprintf(
|
||||
'Exception for Order [%s]: %s. Trace: %s',
|
||||
$orderId, $exception->getMessage(), $exception->getTraceAsString()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return [$ordersForUpload, $errorOrders];
|
||||
}
|
||||
|
||||
/**
|
||||
* Send payment in CRM
|
||||
*
|
||||
|
|
|
@ -75,22 +75,19 @@ if (class_exists('WC_Retailcrm_Uploader') === false) {
|
|||
/**
|
||||
* Uploads archive order in CRM
|
||||
*
|
||||
* @param null|int $page Number page uploads.
|
||||
* @param array $ids Ids orders upload.
|
||||
* @param int|null $page Number page uploads.
|
||||
* @param array $ids Ids orders upload.
|
||||
*
|
||||
* @return void|null
|
||||
* @throws Exception Invalid argument exception.
|
||||
*/
|
||||
public function uploadArchiveOrders($page, $ids = [])
|
||||
public function uploadArchiveOrders(?int $page, array $ids = [])
|
||||
{
|
||||
WC_Retailcrm_Logger::info(__METHOD__, 'Archive order IDs: ' . implode(', ', $ids));
|
||||
|
||||
if (!$this->retailcrm instanceof WC_Retailcrm_Proxy) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$orderIds = [];
|
||||
$uploadErrors = [];
|
||||
|
||||
if (null !== $page) {
|
||||
$orderIds = $this->getCmsOrders($page);
|
||||
|
@ -98,12 +95,40 @@ if (class_exists('WC_Retailcrm_Uploader') === false) {
|
|||
$orderIds = $ids;
|
||||
}
|
||||
|
||||
foreach ($orderIds as $orderId) {
|
||||
$errorMessage = $this->orders->orderCreate($orderId);
|
||||
if ($orderIds === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_string($errorMessage)) {
|
||||
$uploadErrors[$orderId] = $errorMessage;
|
||||
WC_Retailcrm_Logger::info(__METHOD__, 'Archive order IDs: ' . implode(', ', $ids));
|
||||
|
||||
[$ordersForUpload, $uploadErrors] = $this->orders->processOrderForUpload($orderIds);
|
||||
|
||||
try {
|
||||
$response = $this->retailcrm->ordersUpload($ordersForUpload);
|
||||
|
||||
if (!$response->isSuccessful()) {
|
||||
throw new RuntimeException(
|
||||
sprintf(
|
||||
'Failure to upload orders: %s. Status code: %s',
|
||||
$response->getErrorString(),
|
||||
$response->getStatusCode()
|
||||
)
|
||||
);
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
WC_Retailcrm_Logger::error(
|
||||
__METHOD__,
|
||||
sprintf("Error while uploading orders: %s", $exception->getMessage())
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** WP version >= 6 */
|
||||
if (function_exists('wp_cache_flush_runtime')) {
|
||||
wp_cache_flush_runtime();
|
||||
} else {
|
||||
wp_cache_flush();
|
||||
}
|
||||
|
||||
$this->logOrdersUploadErrors($uploadErrors);
|
||||
|
@ -125,7 +150,7 @@ if (class_exists('WC_Retailcrm_Uploader') === false) {
|
|||
|
||||
$users = $this->getCmsUsers($page);
|
||||
|
||||
if (false === empty($users)) {
|
||||
if ($users !== []) {
|
||||
$dataCustomers = [];
|
||||
|
||||
foreach ($users as $user) {
|
||||
|
@ -223,7 +248,7 @@ if (class_exists('WC_Retailcrm_Uploader') === false) {
|
|||
*/
|
||||
private function logOrdersUploadErrors($errors)
|
||||
{
|
||||
if (empty($errors) === true) {
|
||||
if ($errors === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -234,5 +259,47 @@ if (class_exists('WC_Retailcrm_Uploader') === false) {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadConsole($entity, $page = 0)
|
||||
{
|
||||
$ordersPages = (int) ceil($this->getCountOrders() / 50);
|
||||
$customerPages = (int) ceil($this->getCountUsers() / 50);
|
||||
|
||||
try {
|
||||
switch ($entity) {
|
||||
case 'orders':
|
||||
$this->archiveUpload('orders', $page, $ordersPages);
|
||||
break;
|
||||
case 'customers':
|
||||
$this->archiveUpload('customers', $page, $customerPages);
|
||||
break;
|
||||
case 'full_upload':
|
||||
$this->archiveUpload('customers', 0, $customerPages);
|
||||
$this->archiveUpload('orders', 0, $ordersPages);
|
||||
break;
|
||||
default:
|
||||
echo 'Unknown entity: ' . $entity;
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
echo $exception->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function archiveUpload($entity, $page, $totalPages)
|
||||
{
|
||||
echo $entity . ' uploading started' . PHP_EOL;
|
||||
|
||||
do {
|
||||
if ($entity === 'orders') {
|
||||
$this->uploadArchiveOrders($page);
|
||||
} elseif ($entity === 'customers') {
|
||||
$this->uploadArchiveCustomers($page);
|
||||
}
|
||||
|
||||
echo $page . ' page uploaded' . PHP_EOL;
|
||||
|
||||
$page++;
|
||||
} while ($page <= $totalPages);
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
}
|
||||
|
|
|
@ -207,3 +207,8 @@ function isCorporateOrder($wcCustomer, $wcOrder)
|
|||
{
|
||||
return !empty($wcCustomer->get_billing_company()) || !empty($wcOrder->get_billing_company());
|
||||
}
|
||||
|
||||
function getOptionByCode($optionName)
|
||||
{
|
||||
return get_option(WC_Retailcrm_Base::$option_key)[$optionName] ?? null;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ Tags: Интеграция, Simla.com, simla
|
|||
Requires PHP: 7.1
|
||||
Requires at least: 5.3
|
||||
Tested up to: 6.5
|
||||
Stable tag: 4.8.14
|
||||
Stable tag: 4.8.21
|
||||
License: GPLv1 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl-1.0.html
|
||||
|
||||
|
@ -82,6 +82,27 @@ Asegúrate de tener una clave API específica para cada tienda. Las siguientes i
|
|||
|
||||
|
||||
== Changelog ==
|
||||
= 4.8.21 =
|
||||
* Fix version of module
|
||||
|
||||
= 4.8.20 =
|
||||
* Add returned types for methods offsetExists, offsetSet, offsetUnset in WC_Retailcrm_Response
|
||||
|
||||
= 4.8.19 =
|
||||
* Optimization of order unloading
|
||||
|
||||
= 4.8.18 =
|
||||
* Added additional parameters to GET requests
|
||||
|
||||
= 4.8.17 =
|
||||
* Fix deploy
|
||||
|
||||
= 4.8.16 =
|
||||
* Fix tests svn error
|
||||
|
||||
= 4.8.15 =
|
||||
* Fix uploading archive in CRM using console script
|
||||
|
||||
= 4.8.14 =
|
||||
* The method for determining the stock quantity has been optimized
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Description: Integration plugin for WooCommerce & Simla.com
|
||||
* Author: RetailDriver LLC
|
||||
* Author URI: http://retailcrm.pro/
|
||||
* Version: 4.8.14
|
||||
* Version: 4.8.21
|
||||
* Tested up to: 6.5
|
||||
* Requires Plugins: woocommerce
|
||||
* WC requires at least: 5.4
|
||||
|
@ -27,7 +27,7 @@ if (!class_exists( 'WC_Integration_Retailcrm')) :
|
|||
class WC_Integration_Retailcrm {
|
||||
const WOOCOMMERCE_SLUG = 'woocommerce';
|
||||
const WOOCOMMERCE_PLUGIN_PATH = 'woocommerce/woocommerce.php';
|
||||
const MODULE_VERSION = '4.8.11';
|
||||
const MODULE_VERSION = '4.8.21';
|
||||
|
||||
private static $instance;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* @link https://wordpress.org/plugins/woo-retailcrm/
|
||||
*
|
||||
* @version 4.8.14
|
||||
* @version 4.8.21
|
||||
*
|
||||
* @package RetailCRM
|
||||
*/
|
||||
|
|
|
@ -36,7 +36,8 @@ class WC_Retailcrm_Uploader_Test extends WC_Retailcrm_Test_Case_Helper
|
|||
'getCountOrders',
|
||||
'customersGet',
|
||||
'customersList',
|
||||
'ordersCreate'
|
||||
'ordersCreate',
|
||||
'ordersUpload',
|
||||
))
|
||||
->getMock();
|
||||
|
||||
|
@ -96,10 +97,10 @@ class WC_Retailcrm_Uploader_Test extends WC_Retailcrm_Test_Case_Helper
|
|||
* @param $retailcrm
|
||||
* @dataProvider dataProviderApiClient
|
||||
*/
|
||||
public function test_upload_selected_orders()
|
||||
public function test_upload_selected_orders($retailcrm)
|
||||
{
|
||||
$_GET['order_ids_retailcrm'] = '123, 345, 456';
|
||||
$retailcrm_uploader = $this->getRetailcrmUploader($this->apiMock);
|
||||
$retailcrm_uploader = $this->getRetailcrmUploader($retailcrm);
|
||||
$uploadSelectedOrders = $retailcrm_uploader->uploadSelectedOrders();
|
||||
|
||||
$this->assertEquals(null, $uploadSelectedOrders);
|
||||
|
@ -123,6 +124,11 @@ class WC_Retailcrm_Uploader_Test extends WC_Retailcrm_Test_Case_Helper
|
|||
public function dataProviderApiClient()
|
||||
{
|
||||
$this->setUp();
|
||||
$this->apiMock
|
||||
->expects($this->any())
|
||||
->method('ordersUpload')
|
||||
->willReturn(new WC_Retailcrm_Response(200, ''))
|
||||
;
|
||||
|
||||
return array(
|
||||
array(
|
||||
|
|
Loading…
Add table
Reference in a new issue