Transferring base price of goods for loyalty program (#342)
This commit is contained in:
parent
dac3c9f6f7
commit
a23e96b4d6
@ -1,3 +1,6 @@
|
||||
## 2024-09-13 4.8.4
|
||||
* Updated work with promotional items when loyalty program is enabled
|
||||
|
||||
## 2024-09-11 4.8.3
|
||||
* Added loyalty program coupon entry in the form by click
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
'icml' => 'three_hours',
|
||||
'history' => 'five_minutes',
|
||||
'inventories' => 'fiveteen_minutes',
|
||||
'loyalty_upload_price' => 'four_hours'
|
||||
]
|
||||
```
|
||||
> Важно! При использовании фильтра **retailcrm_cron_schedules**, можно использовать ключи: 'icml', 'history', 'inventories'.
|
||||
@ -49,5 +50,3 @@ function change_cron_tasks($cronTasks)
|
||||
return $cronTasks;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
@ -451,8 +451,11 @@ msgstr "Programa de fidelización"
|
||||
msgid "Activate program loyalty"
|
||||
msgstr "Activar programa de fidelización"
|
||||
|
||||
msgid "Enable this setting for activate program loyalty on site"
|
||||
msgstr "Activa esta configuración para activar programa de fidelización en la página web"
|
||||
msgid "Attention! When activating the loyalty program, the method of ICML catalog generation changes. Details in"
|
||||
msgstr "¡Atención! Al activar el programa de fidelización, cambia el método de generación del catálogo ICML. Detalles en la"
|
||||
|
||||
msgid "<a href='https://docs.simla.com/Users/Integration/SiteModules/WooCommerce/PLWoocommerce'>documentation loyalty program</a>"
|
||||
msgstr "<a href='https://docs.simla.com/es/Users/Integration/SiteModules/WooCommerce/PLWoocommerce'>documentación del programa de fidelización</a>"
|
||||
|
||||
msgid "Terms of loyalty program"
|
||||
msgstr "Condiciones del programa de fidelización"
|
||||
@ -591,3 +594,27 @@ msgstr "Utiliza el cupón:"
|
||||
|
||||
msgid "Points will be awarded upon completion of the order:"
|
||||
msgstr "Los puntos se concederán al finalizar el pedido:"
|
||||
|
||||
msgid "Unloading promotional prices of offers"
|
||||
msgstr "Descarga de precios promocionales de ofertas comerciales"
|
||||
|
||||
msgid "Every 4 hours"
|
||||
msgstr "Cada 4 horas"
|
||||
|
||||
msgid "Upload prices now"
|
||||
msgstr "Descargar precios ahora"
|
||||
|
||||
msgid "Uploaded discount price"
|
||||
msgstr "Descarga de precios promocionales"
|
||||
|
||||
msgid "This functionality loads the promotional prices offers into Simla.com"
|
||||
msgstr "Esta función carga los precios promocionales de las ofertas comerciales en Simla.com"
|
||||
|
||||
msgid "Promotional prices unloaded"
|
||||
msgstr "Se han cargado los precios promocionales"
|
||||
|
||||
msgid "Woocommerce promotional price"
|
||||
msgstr "Precio promocional Woocommerce"
|
||||
|
||||
msgid "Promotional price type for Woocommerce store, generated automatically. Necessary for correct synchronization work when loyalty program is enabled (Do not delete. Do not deactivate)"
|
||||
msgstr "Tipo de precio promocional para la tienda Woocommerce, generado automáticamente. Necesario para el correcto funcionamiento de la sincronización cuando el programa de fidelización está habilitado (No eliminar. No desactivar)"
|
||||
|
@ -460,8 +460,11 @@ msgstr "Программа лояльности"
|
||||
msgid "Activate program loyalty"
|
||||
msgstr "Активировать программу лояльности"
|
||||
|
||||
msgid "Enable this setting for activate program loyalty on site"
|
||||
msgstr "Активируйте эту настройку для активации программы лояльности на сайте"
|
||||
msgid "Attention! When activating the loyalty program, the method of ICML catalog generation changes. Details in"
|
||||
msgstr "Внимание! При активации программы лояльности, изменяется способ генерации ICML каталога. Подробности в"
|
||||
|
||||
msgid "<a href='https://docs.simla.com/Users/Integration/SiteModules/WooCommerce/PLWoocommerce'>documentation loyalty program</a>"
|
||||
msgstr "<a href='https://docs.retailcrm.ru/Users/Integration/SiteModules/WooCommerce/PLWoocommerce#h-2'>документации программы лояльности</a>"
|
||||
|
||||
msgid "Terms of loyalty program"
|
||||
msgstr "Условия программы лояльности"
|
||||
@ -600,3 +603,27 @@ msgstr "Используйте купон:"
|
||||
|
||||
msgid "Points will be awarded upon completion of the order:"
|
||||
msgstr "По завершению заказа будет начислено баллов:"
|
||||
|
||||
msgid "Unloading promotional prices of offers"
|
||||
msgstr "Выгрузка акционных цен торговых предложений"
|
||||
|
||||
msgid "Every 4 hours"
|
||||
msgstr "Каждые 4 часа"
|
||||
|
||||
msgid "Upload prices now"
|
||||
msgstr "Выгрузить цены сейчас"
|
||||
|
||||
msgid "Uploaded discount price"
|
||||
msgstr "Выгрузка акционных цен"
|
||||
|
||||
msgid "This functionality loads the promotional prices offers into Simla.com"
|
||||
msgstr "Эта функция загружает акционные цены торговых предложений в Simla.com"
|
||||
|
||||
msgid "Promotional prices unloaded"
|
||||
msgstr "Акционные цены выгружены"
|
||||
|
||||
msgid "Woocommerce promotional price"
|
||||
msgstr "Акционная цена Woocommerce"
|
||||
|
||||
msgid "Promotional price type for Woocommerce store, generated automatically. Necessary for correct synchronization work when loyalty program is enabled (Do not delete. Do not deactivate)"
|
||||
msgstr "Акционный тип цены для магазина Woocommerce, сгенерированный автоматически. Необходим для корректной работы синхронизации при включенной программы лояльности (Не удалять. Не деактивировать)"
|
||||
|
@ -16,6 +16,7 @@ jQuery(function () {
|
||||
this.history = 0;
|
||||
this.inventories = 0;
|
||||
this.messageSuccessful = '';
|
||||
this.loyaltyUploadPrice = 0;
|
||||
|
||||
this.adminUrl = AdminUrl.url;
|
||||
|
||||
@ -33,12 +34,14 @@ jQuery(function () {
|
||||
_this.icml = response.icml;
|
||||
_this.inventories = response.inventories;
|
||||
_this.messageSuccessful = response.translate.tr_successful;
|
||||
_this.loyaltyUploadPrice = response.loyaltyUploadPrice
|
||||
|
||||
_this.displayInfoAboutCron(
|
||||
response.translate.tr_td_cron,
|
||||
response.translate.tr_td_icml,
|
||||
response.translate.tr_td_history,
|
||||
response.translate.tr_td_inventories,
|
||||
response.translate.tr_td_loyaltyUploadPrice
|
||||
);
|
||||
})
|
||||
|
||||
@ -47,7 +50,7 @@ jQuery(function () {
|
||||
jQuery(this.submitButton).click(this.clearCronTasks);
|
||||
}
|
||||
|
||||
RetailcrmCronInfo.prototype.displayInfoAboutCron = function (cron, icml, history, inventories) {
|
||||
RetailcrmCronInfo.prototype.displayInfoAboutCron = function (cron, icml, history, inventories, loyaltyUploadPrice) {
|
||||
this.table = jQuery(this.title).next();
|
||||
this.table.append('<tbody class="retail-debug-info"></tbody>');
|
||||
this.infoTable = jQuery('tbody[class="retail-debug-info"]').get(0);
|
||||
@ -56,6 +59,7 @@ jQuery(function () {
|
||||
jQuery(this.infoTable).append("<tr><td>" + icml + "</td><td> " + this.icml + "</td></tr>");
|
||||
jQuery(this.infoTable).append("<tr><td>" + history + "</td><td> " + this.history + "</td></tr>");
|
||||
jQuery(this.infoTable).append("<tr><td>" + inventories + "</td><td> " + this.inventories + "</td></tr>");
|
||||
jQuery(this.infoTable).append("<tr><td>" + loyaltyUploadPrice + "</td><td>" + this.loyaltyUploadPrice + "</td></tr>");
|
||||
}
|
||||
|
||||
RetailcrmCronInfo.prototype.clearCronTasks = function () {
|
||||
|
@ -72,6 +72,25 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
|
||||
<?php
|
||||
}
|
||||
|
||||
public function ajax_upload_loyalty_price()
|
||||
{
|
||||
$ajax_url = admin_url('admin-ajax.php');
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
jQuery('#upload-loyalty-price-retailcrm').bind('click', function () {
|
||||
jQuery.ajax({
|
||||
type: "POST",
|
||||
url: '<?php echo $ajax_url; ?>?action=upload_loyalty_price',
|
||||
success: function (response) {
|
||||
alert('<?php echo __('Promotional prices unloaded', 'retailcrm');?>');
|
||||
console.log('AJAX response : ', response);
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize integration settings form fields.
|
||||
*/
|
||||
@ -610,7 +629,9 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
|
||||
'title' => __('Loyalty program', 'retailcrm'),
|
||||
'class' => 'checkbox',
|
||||
'type' => 'checkbox',
|
||||
'description' => __('Enable this setting for activate program loyalty on site', 'retailcrm')
|
||||
'description' => '<b style="color: red">' .
|
||||
__('Attention! When activating the loyalty program, the method of ICML catalog generation changes. Details in', 'retailcrm') .
|
||||
' <\b>' . __("<a href='https://docs.simla.com/Users/Integration/SiteModules/WooCommerce/PLWoocommerce'>documentation loyalty program</a>", "retailcrm")
|
||||
];
|
||||
|
||||
$this->form_fields['loyalty_terms'] = [
|
||||
@ -651,6 +672,18 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
|
||||
),
|
||||
];
|
||||
|
||||
$this->form_fields[] = [
|
||||
'label' => __('Upload prices now', 'retailcrm'),
|
||||
'title' => __('Uploaded discount price', 'retailcrm'),
|
||||
'type' => 'button',
|
||||
'desc_tip' => true,
|
||||
'id' => 'upload-loyalty-price-retailcrm',
|
||||
'description' => __(
|
||||
'This functionality loads the promotional prices offers into Simla.com',
|
||||
'retailcrm'
|
||||
),
|
||||
];
|
||||
|
||||
$this->form_fields['icml'] = [
|
||||
'label' => __('Generating ICML', 'retailcrm'),
|
||||
'title' => __('Generating ICML catalog by wp-cron', 'retailcrm'),
|
||||
|
@ -3037,6 +3037,23 @@ class WC_Retailcrm_Client_V5
|
||||
);
|
||||
}
|
||||
|
||||
public function getPriceTypes()
|
||||
{
|
||||
return $this->client->makeRequest(
|
||||
'/reference/price-types',
|
||||
WC_Retailcrm_Request::METHOD_GET
|
||||
);
|
||||
}
|
||||
|
||||
public function editPriceType($priceType)
|
||||
{
|
||||
return $this->client->makeRequest(
|
||||
sprintf('/reference/price-types/%s/edit', $priceType['code']),
|
||||
WC_Retailcrm_Request::METHOD_POST,
|
||||
['priceType' => json_encode($priceType)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current site
|
||||
*
|
||||
|
@ -127,6 +127,9 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
||||
add_action('woocommerce_applied_coupon', [$this, 'apply_coupon'], 11, 1);
|
||||
add_action('woocommerce_review_order_before_payment', [$this, 'reviewCreditBonus'], 11, 1);
|
||||
add_action('wp_trash_post', [$this, 'trash_order_action'], 10, 1);
|
||||
add_action('retailcrm_loyalty_upload_price', [$this, 'upload_loyalty_price']);
|
||||
add_action('admin_print_footer_scripts', [$this, 'ajax_upload_loyalty_price'], 99);
|
||||
add_action('wp_ajax_upload_loyalty_price', [$this, 'upload_loyalty_price']);
|
||||
|
||||
if (
|
||||
!$this->get_option('deactivate_update_order')
|
||||
@ -190,12 +193,23 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
||||
*/
|
||||
public function api_sanitized($settings)
|
||||
{
|
||||
$isLoyaltyUploadPrice = false;
|
||||
|
||||
if (
|
||||
isset($settings['icml'], $settings['loyalty'])
|
||||
&& $settings['icml'] === static::YES
|
||||
&& $settings['loyalty'] === static::YES
|
||||
) {
|
||||
$isLoyaltyUploadPrice = true;
|
||||
}
|
||||
|
||||
$timeInterval = apply_filters(
|
||||
'retailcrm_cron_schedules',
|
||||
[
|
||||
'icml' => 'three_hours',
|
||||
'history' => 'five_minutes',
|
||||
'inventories' => 'fiveteen_minutes',
|
||||
'loyalty_upload_price' => 'four_hours'
|
||||
]
|
||||
);
|
||||
|
||||
@ -223,6 +237,12 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
||||
wp_clear_scheduled_hook('retailcrm_icml');
|
||||
}
|
||||
|
||||
if ($isLoyaltyUploadPrice && !wp_next_scheduled('retailcrm_loyalty_upload_price')) {
|
||||
wp_schedule_event(time(), $timeInterval['loyalty_upload_price'], 'retailcrm_loyalty_upload_price');
|
||||
} elseif (!$isLoyaltyUploadPrice) {
|
||||
wp_clear_scheduled_hook('retailcrm_loyalty_upload_price');
|
||||
}
|
||||
|
||||
if (!$this->get_errors() && !get_option('retailcrm_active_in_crm')) {
|
||||
$this->activate_integration($settings);
|
||||
}
|
||||
@ -268,6 +288,7 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
||||
wp_clear_scheduled_hook('retailcrm_icml');
|
||||
wp_clear_scheduled_hook('retailcrm_history');
|
||||
wp_clear_scheduled_hook('retailcrm_inventories');
|
||||
wp_clear_scheduled_hook('retailcrm_loyalty_upload_price');
|
||||
|
||||
//Add new cron tasks
|
||||
$this->api_sanitized($this->settings);
|
||||
@ -361,6 +382,16 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
||||
}
|
||||
}
|
||||
|
||||
public function upload_loyalty_price()
|
||||
{
|
||||
if (!$this->apiClient instanceof WC_Retailcrm_Proxy) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$discountPriceUpload = new WC_Retailcrm_Upload_Discount_Price($this->apiClient);
|
||||
$discountPriceUpload->upload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get history
|
||||
*
|
||||
@ -930,12 +961,15 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
||||
$icml = $defaultValue;
|
||||
$history = $defaultValue;
|
||||
$inventories = $defaultValue;
|
||||
$loyaltyUploadPrice = $defaultValue;
|
||||
|
||||
$translate = [
|
||||
'tr_td_cron' => __('Cron launches', 'retailcrm'),
|
||||
'tr_td_icml' => __('Generation ICML', 'retailcrm'),
|
||||
'tr_td_history' => __('Syncing history', 'retailcrm'),
|
||||
'tr_successful' => __('Cron tasks cleared', 'retailcrm'),
|
||||
'tr_td_inventories' => __('Syncing inventories', 'retailcrm'),
|
||||
'tr_td_loyaltyUploadPrice' => __('Unloading promotional prices of offers', 'retailcrm')
|
||||
];
|
||||
|
||||
if (isset($this->settings['history']) && $this->settings['history'] == static::YES) {
|
||||
@ -944,6 +978,10 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
||||
|
||||
if (isset($this->settings['icml']) && $this->settings['icml'] == static::YES) {
|
||||
$icml = date('H:i:s d-m-Y', wp_next_scheduled('retailcrm_icml'));
|
||||
|
||||
if (isset($this->settings['loyalty']) && $this->settings['loyalty'] === static::YES) {
|
||||
$loyaltyUploadPrice = date('H:i:s d-m-Y', wp_next_scheduled('retailcrm_loyalty_upload_price'));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->settings['sync']) && $this->settings['sync'] == static::YES) {
|
||||
@ -956,6 +994,7 @@ if (!class_exists('WC_Retailcrm_Base')) {
|
||||
'icml' => $icml,
|
||||
'inventories' => $inventories,
|
||||
'translate' => $translate,
|
||||
'loyaltyUploadPrice' => $loyaltyUploadPrice
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -38,6 +38,8 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
|
||||
protected $unloadServices = false;
|
||||
|
||||
protected $activeLoyalty = false;
|
||||
|
||||
/**
|
||||
* WC_Retailcrm_Icml constructor.
|
||||
*
|
||||
@ -53,6 +55,10 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
isset($this->settings['icml_unload_services'])
|
||||
&& $this->settings['icml_unload_services'] === WC_Retailcrm_Base::YES
|
||||
);
|
||||
|
||||
if (isset($this->settings['loyalty']) && $this->settings['loyalty'] === WC_Retailcrm_Base::YES) {
|
||||
$this->activeLoyalty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function changeBindBySku($useXmlId)
|
||||
@ -251,7 +257,10 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
'productId' => ($product->get_parent_id() > 0) ? $parent->get_id() : $product->get_id(),
|
||||
'name' => $product->get_name(),
|
||||
'productName' => ($product->get_parent_id() > 0) ? $parent->get_title() : $product->get_title(),
|
||||
'price' => wc_get_price_including_tax($product),
|
||||
'price' => $this->activeLoyalty
|
||||
? wc_get_price_including_tax($product, ["price" => $product->get_regular_price()])
|
||||
: wc_get_price_including_tax($product)
|
||||
,
|
||||
'picture' => $images,
|
||||
'url' => ($product->get_parent_id() > 0) ? $parent->get_permalink() : $product->get_permalink(),
|
||||
'quantity' => $quantity,
|
||||
|
@ -450,11 +450,14 @@ if (!class_exists('WC_Retailcrm_Loyalty')) :
|
||||
foreach ($cartItems as $item) {
|
||||
$product = $item['data'];
|
||||
|
||||
$productRegularPrice = wc_get_price_including_tax($product, ["price" => $product->get_regular_price()]);
|
||||
$discount = $productRegularPrice - ($item['line_total'] / $item['quantity']);
|
||||
|
||||
$order['items'][] = [
|
||||
'offer' => $useXmlId ? ['xmlId' => $product->get_sku()] : ['externalId' => $product->get_id()],
|
||||
'quantity' => $item['quantity'],
|
||||
'initialPrice' => wc_get_price_including_tax($product),
|
||||
'discountManualAmount' => ($item['line_subtotal'] - $item['line_total']) / $item['quantity']
|
||||
'initialPrice' => $productRegularPrice,
|
||||
'discountManualAmount' => $discount
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,10 @@ class WC_Retailcrm_Plugin
|
||||
'fiveteen_minutes' => [
|
||||
'interval' => 900, // seconds
|
||||
'display' => __('Every 15 minutes')
|
||||
],
|
||||
'four_hours' => [
|
||||
'interval' => 14400, //seconds
|
||||
'display' => __('Every 4 hours')
|
||||
]
|
||||
],
|
||||
apply_filters('retailcrm_add_cron_interval', $schedules)
|
||||
@ -116,6 +120,10 @@ class WC_Retailcrm_Plugin
|
||||
if (wp_next_scheduled('retailcrm_inventories')) {
|
||||
wp_clear_scheduled_hook('retailcrm_inventories');
|
||||
}
|
||||
|
||||
if (wp_next_scheduled('retailcrm_loyalty_upload_price')) {
|
||||
wp_clear_scheduled_hook('retailcrm_loyalty_upload_price');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
238
src/include/class-wc-retailcrm-upload-discount-price.php
Normal file
238
src/include/class-wc-retailcrm-upload-discount-price.php
Normal file
@ -0,0 +1,238 @@
|
||||
<?php
|
||||
|
||||
if (!class_exists('WC_Retailcrm_Upload_Discount_Price')):
|
||||
|
||||
class WC_Retailcrm_Upload_Discount_Price
|
||||
{
|
||||
const DISCOUNT_TYPE_PRICE = 'woo-promotion-lp';
|
||||
|
||||
protected $activeLoyalty = false;
|
||||
|
||||
protected $settings;
|
||||
|
||||
protected $site;
|
||||
|
||||
/** @var bool|WC_Retailcrm_Proxy|WC_Retailcrm_Client_V5 */
|
||||
protected $apiClient;
|
||||
|
||||
public function __construct($aplClient = false)
|
||||
{
|
||||
$this->settings = get_option(WC_Retailcrm_Base::$option_key);
|
||||
$this->apiClient = $aplClient;
|
||||
|
||||
if (isset($this->settings['loyalty']) && $this->settings['loyalty'] === WC_Retailcrm_Base::YES) {
|
||||
$this->activeLoyalty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function upload()
|
||||
{
|
||||
if (!$this->activeLoyalty) {
|
||||
return;
|
||||
}
|
||||
|
||||
$error = $this->uploadSettings();
|
||||
|
||||
if ($error !== '') {
|
||||
writeBaseLogs($error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$productStatuses = $this->getProductStatuses();
|
||||
|
||||
if (!$productStatuses) {
|
||||
$productStatuses = ['publish'];
|
||||
}
|
||||
|
||||
$page = 1;
|
||||
$requestData = [];
|
||||
|
||||
do {
|
||||
$products = wc_get_products(
|
||||
[
|
||||
'limit' => 1000,
|
||||
'status' => $productStatuses,
|
||||
'page' => $page,
|
||||
'paginate' => true
|
||||
]
|
||||
);
|
||||
|
||||
/** WP version >= 6 */
|
||||
if (function_exists('wp_cache_flush_runtime')) {
|
||||
wp_cache_flush_runtime();
|
||||
} else {
|
||||
wp_cache_flush();
|
||||
}
|
||||
|
||||
if (empty($products)) {
|
||||
writeBaseLogs('Can`t get products!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ($products->products as $offer) {
|
||||
$type = $offer->get_type();
|
||||
|
||||
if (strpos($type, 'variable') !== false || strpos($type, 'variation') !== false) {
|
||||
foreach ($offer->get_children() as $childId) {
|
||||
$childProduct = wc_get_product($childId);
|
||||
|
||||
if (!$childProduct) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sendOffer = $this->getOfferData($childProduct);
|
||||
|
||||
if ($sendOffer !== []) {
|
||||
$requestData[] = $sendOffer;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$sendOffer = $this->getOfferData($offer);
|
||||
|
||||
if ($sendOffer !== []) {
|
||||
$requestData[] = $sendOffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$chunks = array_chunk($requestData, 250);
|
||||
|
||||
foreach ($chunks as $chunk) {
|
||||
$this->apiClient->storePricesUpload($chunk, $this->site);
|
||||
time_nanosleep(0, 200000000);
|
||||
}
|
||||
|
||||
unset($chunks);
|
||||
} catch (\Throwable $exception) {
|
||||
writeBaseLogs($exception->getMessage() . PHP_EOL . $exception->getTraceAsString());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
++$page;
|
||||
} while ($page <= $products->max_num_pages);
|
||||
}
|
||||
|
||||
private function getOfferData(WC_Product $product)
|
||||
{
|
||||
$currentPrice = wc_get_price_including_tax($product);
|
||||
$defaultPrice = wc_get_price_including_tax($product, ["price" => $product->get_regular_price()]);
|
||||
|
||||
if ($currentPrice === $defaultPrice) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'externalId' => $product->get_id(),
|
||||
'site' => $this->site,
|
||||
'prices' => [
|
||||
[
|
||||
'code' => self::DISCOUNT_TYPE_PRICE,
|
||||
'price' => $currentPrice
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
private function getProductStatuses()
|
||||
{
|
||||
$statuses = [];
|
||||
|
||||
foreach (get_post_statuses() as $key => $value) {
|
||||
if (isset($this->settings['p_' . $key]) && $this->settings['p_' . $key] == WC_Retailcrm_Base::YES) {
|
||||
$statuses[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
return $statuses;
|
||||
}
|
||||
|
||||
private function uploadSettings()
|
||||
{
|
||||
if (!$this->apiClient instanceof WC_Retailcrm_Proxy
|
||||
&& !$this->apiClient instanceof WC_Retailcrm_Client_V5
|
||||
) {
|
||||
return 'API client has not been initialized';
|
||||
}
|
||||
|
||||
$this->site = $this->apiClient->getSingleSiteForKey();
|
||||
|
||||
if (empty($this->site)) {
|
||||
return 'Error with CRM credentials: need an valid apiKey assigned to one certain site';
|
||||
}
|
||||
|
||||
$response = $this->apiClient->getPriceTypes();
|
||||
|
||||
if (
|
||||
!$response instanceof WC_Retailcrm_Response
|
||||
|| !$response->offsetExists('priceTypes')
|
||||
|| empty($response['priceTypes'])
|
||||
) {
|
||||
return 'Error getting price types';
|
||||
}
|
||||
|
||||
$defaultPrice = null;
|
||||
$discountPriceType = null;
|
||||
|
||||
foreach ($response['priceTypes'] as $priceType) {
|
||||
if ($priceType['default'] === true) {
|
||||
$defaultPrice = $priceType;
|
||||
}
|
||||
|
||||
if ($priceType['code'] === self::DISCOUNT_TYPE_PRICE) {
|
||||
$discountPriceType = $priceType;
|
||||
}
|
||||
}
|
||||
|
||||
if ($discountPriceType === null) {
|
||||
$discountPriceType = [
|
||||
'code' => self::DISCOUNT_TYPE_PRICE,
|
||||
'name' => __('Woocommerce promotional price', 'retailcrm'),
|
||||
'active' => true,
|
||||
'description' => __('Promotional price type for Woocommerce store, generated automatically.
|
||||
Necessary for correct synchronization work when loyalty program is enabled
|
||||
(Do not delete. Do not deactivate)', 'retailcrm'),
|
||||
'ordering' => 999,
|
||||
'promo' => true
|
||||
];
|
||||
|
||||
if (isset($defaultPrice['geo'])) {
|
||||
$discountPriceType['geo'] = $defaultPrice['geo'];
|
||||
}
|
||||
|
||||
if (isset($defaultPrice['groups'])) {
|
||||
$discountPriceType['groups'] = $defaultPrice['groups'];
|
||||
}
|
||||
|
||||
if (isset($defaultPrice['currency'])) {
|
||||
$discountPriceType['currency'] = $defaultPrice['currency'];
|
||||
}
|
||||
|
||||
if (isset($defaultPrice['filterExpression'])) {
|
||||
$discountPriceType['filterExpression'] = $defaultPrice['filterExpression'];
|
||||
}
|
||||
|
||||
$response = $this->apiClient->editPriceType($discountPriceType);
|
||||
|
||||
if (!$response instanceof WC_Retailcrm_Response || !$response['success']) {
|
||||
return 'Error creating price type';
|
||||
}
|
||||
} elseif ($discountPriceType['active'] === false || $discountPriceType['promo'] === false) {
|
||||
$discountPriceType['active'] = true;
|
||||
$discountPriceType['promo'] = true;
|
||||
|
||||
$response = $this->apiClient->editPriceType($discountPriceType);
|
||||
|
||||
if (!$response instanceof WC_Retailcrm_Response || !$response['success']) {
|
||||
return 'Error activate price type';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
@ -106,7 +106,12 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data
|
||||
*/
|
||||
private function calculatePrice(WC_Order_Item_Product $item, int $decimalPlaces)
|
||||
{
|
||||
$price = ($item['line_subtotal'] / $item->get_quantity()) + ($item['line_subtotal_tax'] / $item->get_quantity());
|
||||
if (isset($this->settings['loyalty']) && $this->settings['loyalty'] === WC_Retailcrm_Base::YES) {
|
||||
$product = $item->get_product();
|
||||
$price = wc_get_price_including_tax($product, ["price" => $product->get_regular_price()]);
|
||||
} else {
|
||||
$price = ($item['line_subtotal'] / $item->get_quantity()) + ($item['line_subtotal_tax'] / $item->get_quantity());
|
||||
}
|
||||
|
||||
return round($price, $decimalPlaces);
|
||||
}
|
||||
@ -124,7 +129,8 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data
|
||||
int $decimalPlaces,
|
||||
$crmItem = null
|
||||
) {
|
||||
if ($crmItem) {
|
||||
|
||||
if ($crmItem && isset($this->settings['loyalty']) && $this->settings['loyalty'] === WC_Retailcrm_Base::YES) {
|
||||
$loyaltyDiscount = 0;
|
||||
|
||||
foreach ($crmItem['discounts'] as $discount) {
|
||||
|
@ -202,7 +202,8 @@ return [
|
||||
"Los bienes con la opción 'virtual' activada se cargarán en Simla como servicios",
|
||||
"Loyalty program" => "Programa de fidelización",
|
||||
"Activate program loyalty" => "Activar programa de fidelización",
|
||||
"Enable this setting for activate program loyalty on site" => "Activa esta configuración para activar el programa de fidelización en la página web",
|
||||
"Attention! When activating the loyalty program, the method of ICML catalog generation changes. Details in" => "¡Atención! Al activar el programa de fidelización, cambia el método de generación del catálogo ICML. Detalles en la",
|
||||
"<a href='https://docs.simla.com/Users/Integration/SiteModules/WooCommerce/PLWoocommerce'>documentation loyalty program</a>" => "<a href='https://docs.simla.com/es/Users/Integration/SiteModules/WooCommerce/PLWoocommerce'>documentación del programa de fidelización</a>",
|
||||
"Terms of loyalty program" => "Condiciones del programa de fidelización",
|
||||
"Insert the terms and conditions of the loyalty program" => "Inserte las condiciones del programa de fidelización",
|
||||
"Conditions of personal data processing" => "Condiciones de procesamiento de datos personales",
|
||||
@ -248,6 +249,15 @@ return [
|
||||
"bonuses" => "bonificaciones",
|
||||
"Use coupon:" => "Utiliza el cupón:",
|
||||
"Points will be awarded upon completion of the order:" => "Los puntos se concederán al finalizar el pedido:",
|
||||
"Unloading promotional prices of offers" => "Descarga de precios promocionales de ofertas comerciales",
|
||||
"Every 4 hours" => "Cada 4 horas",
|
||||
"Upload prices now" => "Descargar precios ahora",
|
||||
"Uploaded discount price" => "Descarga de precios promocionales",
|
||||
"This functionality loads the promotional prices offers into Simla.com" => "Esta función carga los precios promocionales de las ofertas comerciales en Simla.com",
|
||||
"Promotional prices unloaded" => "Se han cargado los precios promocionales",
|
||||
"Woocommerce promotional price" => "Precio promocional Woocommerce",
|
||||
"Promotional price type for Woocommerce store, generated automatically. Necessary for correct synchronization work when loyalty program is enabled (Do not delete. Do not deactivate)" =>
|
||||
"Tipo de precio promocional para la tienda Woocommerce, generado automáticamente. Necesario para el correcto funcionamiento de la sincronización cuando el programa de fidelización está habilitado (No eliminar. No desactivar)"
|
||||
],
|
||||
"language" => "es",
|
||||
"x-generator" => "GlotPress/2.4.0-alpha",
|
||||
|
Binary file not shown.
@ -201,7 +201,8 @@ return [
|
||||
"Товары с включенной опцией 'виртуальные' будут выгружаться в CRM как услуги",
|
||||
"Loyalty program" => "Программа лояльности",
|
||||
"Activate program loyalty" => "Активировать программу лояльности",
|
||||
"Enable this setting for activate program loyalty on site" => "Активируйте эту настройку для активации программы лояльности на сайте",
|
||||
"Attention! When activating the loyalty program, the method of ICML catalog generation changes. Details in" => "Внимание! При активации программы лояльности, изменяется способ генерации ICML каталога. Подробности в",
|
||||
"<a href='https://docs.simla.com/Users/Integration/SiteModules/WooCommerce/PLWoocommerce'>documentation loyalty program</a>" => "<a href='https://docs.retailcrm.ru/Users/Integration/SiteModules/WooCommerce/PLWoocommerce#h-2'>документации программы лояльности</a>",
|
||||
"Terms of loyalty program" => "Условия программы лояльности",
|
||||
"Insert the terms and conditions of the loyalty program" => "Вставьте условия участия в программе лояльности",
|
||||
"Conditions of personal data processing" => "Условия обработки персональных данных",
|
||||
@ -247,6 +248,15 @@ return [
|
||||
"bonuses" => "бонусов",
|
||||
"Use coupon:" => "Используйте купон:",
|
||||
"Points will be awarded upon completion of the order:" => "По завершению заказа будет начислено баллов:",
|
||||
"Unloading promotional prices of offers" => "Выгрузка акционных цен торговых предложений",
|
||||
"Every 4 hours" => "Каждые 4 часа",
|
||||
"Upload prices now" => "Выгрузить цены сейчас",
|
||||
"Uploaded discount price" => "Выгрузка акционных цен",
|
||||
"This functionality loads the promotional prices offers into Simla.com" => "Эта функция загружает акционные цены торговых предложений в Simla.com",
|
||||
"Promotional prices unloaded" => "Акционные цены выгружены",
|
||||
"Woocommerce promotional price" => "Акционная цена Woocommerce",
|
||||
"Promotional price type for Woocommerce store, generated automatically. Necessary for correct synchronization work when loyalty program is enabled (Do not delete. Do not deactivate)" =>
|
||||
"Акционный тип цены для магазина Woocommerce, сгенерированный автоматически. Необходим для корректной работы синхронизации при включенной программы лояльности (Не удалять. Не деактивировать)"
|
||||
],
|
||||
"language" => "ru",
|
||||
"x-generator" => "GlotPress/2.4.0-alpha",
|
||||
|
Binary file not shown.
@ -5,7 +5,7 @@ Tags: Интеграция, Simla.com, simla
|
||||
Requires PHP: 7.0
|
||||
Requires at least: 5.3
|
||||
Tested up to: 6.5
|
||||
Stable tag: 4.8.3
|
||||
Stable tag: 4.8.4
|
||||
License: GPLv1 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl-1.0.html
|
||||
|
||||
@ -82,6 +82,9 @@ Asegúrate de tener una clave API específica para cada tienda. Las siguientes i
|
||||
|
||||
|
||||
== Changelog ==
|
||||
= 4.8.4 =
|
||||
* Updated work with promotional items when loyalty program is enabled
|
||||
|
||||
= 4.8.3 =
|
||||
* Added loyalty program coupon entry in the form by click
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Description: Integration plugin for WooCommerce & Simla.com
|
||||
* Author: RetailDriver LLC
|
||||
* Author URI: http://retailcrm.pro/
|
||||
* Version: 4.8.3
|
||||
* Version: 4.8.4
|
||||
* Tested up to: 6.5
|
||||
* Requires Plugins: woocommerce
|
||||
* WC requires at least: 5.4
|
||||
@ -136,6 +136,7 @@ if (!class_exists( 'WC_Integration_Retailcrm')) :
|
||||
require_once(self::checkCustomFile('include/components/class-wc-retailcrm-loyalty-form.php'));
|
||||
require_once(self::checkCustomFile('include/validators/loyalty-validator/class-wc-retailcrm-loyalty-constraint.php'));
|
||||
require_once(self::checkCustomFile('include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php'));
|
||||
require_once(self::checkCustomFile('include/class-wc-retailcrm-upload-discount-price.php'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
* @link https://wordpress.org/plugins/woo-retailcrm/
|
||||
*
|
||||
* @version 4.8.3
|
||||
* @version 4.8.4
|
||||
*
|
||||
* @package RetailCRM
|
||||
*/
|
||||
|
56
tests/datasets/data-upload-price-retailcrm.php
Normal file
56
tests/datasets/data-upload-price-retailcrm.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace datasets;
|
||||
|
||||
/**
|
||||
* PHP version 7.0
|
||||
*
|
||||
* Class DataUploadPriceRetailCrm - Data set for WC_Retailcrm_Upload_Discount_Price_Test.
|
||||
*
|
||||
* @category Integration
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license http://retailcrm.ru Proprietary
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
class DataUploadPriceRetailCrm
|
||||
{
|
||||
public static function dataGetPriceTypes() {
|
||||
return [
|
||||
'success' => true,
|
||||
'priceTypes' => [
|
||||
[
|
||||
'code' => 'test',
|
||||
'name' => 'test',
|
||||
'active' => true,
|
||||
'description' => 'test',
|
||||
'ordering' => 999,
|
||||
'promo' => true,
|
||||
'default' => false
|
||||
],
|
||||
[
|
||||
'code' => 'default',
|
||||
'name' => 'default',
|
||||
'active' => true,
|
||||
'description' => 'default',
|
||||
'ordering' => 999,
|
||||
'promo' => true,
|
||||
'default' => true
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function willSendPriceType() {
|
||||
return [
|
||||
'code' => 'woo-promotion-lp',
|
||||
'name' => 'Woocommerce promotional price',
|
||||
'active' => true,
|
||||
'description' => 'Promotional price type for Woocommerce store, generated automatically.
|
||||
Necessary for correct synchronization work when loyalty program is enabled
|
||||
(Do not delete. Do not deactivate)',
|
||||
'ordering' => 999,
|
||||
'promo' => true,
|
||||
];
|
||||
}
|
||||
}
|
74
tests/test-wc-retailcrm-upload-discount-price.php
Normal file
74
tests/test-wc-retailcrm-upload-discount-price.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
use datasets\DataUploadPriceRetailCrm;
|
||||
|
||||
/**
|
||||
* PHP version 7.0
|
||||
*
|
||||
* WC_Retailcrm_Upload_Discount_Price_Test
|
||||
*
|
||||
* @category Integration
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @license http://retailcrm.ru Proprietary
|
||||
* @link http://retailcrm.ru
|
||||
* @see http://help.retailcrm.ru
|
||||
*/
|
||||
class WC_Retailcrm_Upload_Discount_Price_Test extends WC_Retailcrm_Test_Case_Helper
|
||||
{
|
||||
protected $apiMock;
|
||||
protected $responseMock;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
WC_Helper_Product::create_simple_product();
|
||||
WC_Helper_Product::create_variation_product();
|
||||
|
||||
$this->setOptions();
|
||||
|
||||
$this->responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['isSuccessful'])
|
||||
->getMock()
|
||||
;
|
||||
|
||||
$this->apiMock = $this->getMockBuilder('\WC_Retailcrm_Client_V5')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['storePricesUpload', 'getSingleSiteForKey', 'getPriceTypes', 'editPriceType'])
|
||||
->getMock()
|
||||
;
|
||||
|
||||
$this->responseMock->setResponse(['success' => true]);
|
||||
$this->setMockResponse($this->responseMock, 'isSuccessful', true);
|
||||
$this->setMockResponse($this->apiMock, 'getSingleSiteForKey', 'woo');
|
||||
|
||||
$this->responseMock->setResponse(DataUploadPriceRetailCrm::dataGetPriceTypes());
|
||||
$this->setMockResponse($this->apiMock, 'getPriceTypes', $this->responseMock);
|
||||
}
|
||||
|
||||
public function testUpload()
|
||||
{
|
||||
$this->apiMock
|
||||
->expects($this->exactly(1))
|
||||
->method('storePricesUpload')
|
||||
->with($this->callback(
|
||||
function ($parameter) {
|
||||
if (is_array($parameter)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
), $this->equalTo('woo'))
|
||||
;
|
||||
|
||||
$this->apiMock
|
||||
->expects($this->exactly(1))
|
||||
->method('editPriceType')
|
||||
->with($this->identicalTo(DataUploadPriceRetailCrm::willSendPriceType()))
|
||||
->willReturn($this->responseMock)
|
||||
;
|
||||
|
||||
$uploadService = new WC_Retailcrm_Upload_Discount_Price($this->apiMock);
|
||||
$uploadService->upload();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user