Add product description to ICML
This commit is contained in:
parent
01e3ad71ee
commit
e1e7331f89
@ -1,4 +1,12 @@
|
||||
### Настройки каталога *(статусы товаров)*
|
||||
### Настройки каталога
|
||||
|
||||
В версии 4.4.4 добавлен функционал передачи описания товара в каталог. В настройках каталога необходимо выбрать, какое описание передавать краткое или полное. По умолчанию передается полное описание товара.
|
||||
|
||||
Поле description(описание) выводится в карточке товара, так же его можно использовать в twig-шаблонах. Например, для вывода в печатных формах.
|
||||
Пример получения описание торгового предложения:
|
||||
```twig
|
||||
{% for availableOrderProduct in order.availableOrderProducts %} {{ availableOrderProduct.getOffer().getDescription() }} {% endfor %}
|
||||
```
|
||||
|
||||
В настройке представлены статусы товаров в WooCommerce *(Товары -> карточка товара -> блок Опубликовано)*. Из товаров, чей статус будет соответствовать выбранному, будет сгенерирован ICML-файл каталога. Для выбора необходимо поставить галочку напротив нужного статуса и сохранить настройки.
|
||||
|
@ -317,4 +317,16 @@ msgid "Attention!"
|
||||
msgstr "¡Atención!"
|
||||
|
||||
msgid "If payment type linked to the CRM integration module choosed, payment must be proceed in the CRM"
|
||||
msgstr "Al seleccionar en el enlace de tipos de pago un método de pago de integración en CRM, el pago se debe realizar por parte del CRM"
|
||||
msgstr "Al seleccionar en el enlace de tipos de pago un método de pago de integración en CRM, el pago se debe realizar por parte del CRM"
|
||||
|
||||
msgid "Product description"
|
||||
msgstr "Descripción del Producto"
|
||||
|
||||
msgid "Full description"
|
||||
msgstr "Descripción completa"
|
||||
|
||||
msgid "Short description"
|
||||
msgstr "Descripción corta"
|
||||
|
||||
msgid "In the catalog, you can use a full or short description of the product"
|
||||
msgstr "En el catálogo, puedes utilizar una descripción del producto corta o completa"
|
@ -328,5 +328,15 @@ msgstr "Внимание!"
|
||||
msgid "If payment type linked to the CRM integration module choosed, payment must be proceed in the CRM"
|
||||
msgstr "При указании в соответствии типа оплаты, привязанного к интеграционному модулю в CRM, оплата должна происходить на стороне CRM"
|
||||
|
||||
msgid "Product description"
|
||||
msgstr "Описание товара"
|
||||
|
||||
msgid "Full description"
|
||||
msgstr "Полное описание"
|
||||
|
||||
msgid "Short description"
|
||||
msgstr "Краткое описание"
|
||||
|
||||
msgid "In the catalog, you can use a full or short description of the product"
|
||||
msgstr "В каталоге можно использовать полное или краткое описание товара"
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
.whatsapp-icon {
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
left: 0;
|
||||
bottom: 55px;
|
||||
width: 60px;
|
||||
|
2
src/assets/css/whatsapp-icon.min.css
vendored
2
src/assets/css/whatsapp-icon.min.css
vendored
@ -1 +1 @@
|
||||
.whatsapp-icon{position:fixed;left:0;bottom:55px;width:60px;height:60px;box-sizing:border-box}.whatsapp-icon_left{left:32px;right:auto}.whatsapp-icon_right{right:32px;left:auto}.whatsapp-icon__icon{width:100%;height:100%}.chat-btn__text{color:#8A96A6;font-weight:600;font-size:12px;line-height:14px;text-align:center;margin:8px 0 0}
|
||||
.whatsapp-icon{position:fixed;z-index: 999;left:0;bottom:55px;width:60px;height:60px;box-sizing:border-box}.whatsapp-icon_left{left:32px;right:auto}.whatsapp-icon_right{right:32px;left:auto}.whatsapp-icon__icon{width:100%;height:100%}.chat-btn__text{color:#8A96A6;font-weight:600;font-size:12px;line-height:14px;text-align:center;margin:8px 0 0}
|
@ -127,6 +127,21 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
|
||||
'id' => 'catalog_options'
|
||||
);
|
||||
|
||||
$this->form_fields['product_description'] = [
|
||||
'type' => 'select',
|
||||
'class' => 'select',
|
||||
'title' => __('Product description', 'retailcrm'),
|
||||
'options' => [
|
||||
'full' => __('Full description', 'retailcrm'),
|
||||
'short' => __('Short description', 'retailcrm'),
|
||||
],
|
||||
'desc_tip' => true,
|
||||
'description' => __(
|
||||
'In the catalog, you can use a full or short description of the product',
|
||||
'retailcrm'
|
||||
),
|
||||
];
|
||||
|
||||
foreach (get_post_statuses() as $status_key => $status_value) {
|
||||
$this->form_fields['p_' . $status_key] = array(
|
||||
'title' => $status_value,
|
||||
@ -134,7 +149,7 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
|
||||
'description' => '',
|
||||
'class' => 'checkbox',
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
'desc_tip' => true,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 5.6
|
||||
*
|
||||
@ -18,7 +19,7 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
protected $file;
|
||||
protected $tmpFile;
|
||||
|
||||
protected $properties = array(
|
||||
protected $properties = [
|
||||
'name',
|
||||
'productName',
|
||||
'price',
|
||||
@ -28,7 +29,7 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
'url',
|
||||
'xmlId',
|
||||
'productActivity'
|
||||
);
|
||||
];
|
||||
|
||||
protected $xml;
|
||||
|
||||
@ -51,7 +52,7 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
public function __construct()
|
||||
{
|
||||
$this->settings = get_option(WC_Retailcrm_Base::$option_key);
|
||||
$this->shop = get_bloginfo( 'name' );
|
||||
$this->shop = get_bloginfo('name');
|
||||
$this->file = ABSPATH . 'simla.xml';
|
||||
$this->tmpFile = sprintf('%s.tmp', $this->file);
|
||||
}
|
||||
@ -80,8 +81,11 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
|
||||
$status_args = $this->checkPostStatuses();
|
||||
$this->get_wc_products_taxonomies($status_args);
|
||||
|
||||
$dom = dom_import_simplexml(simplexml_load_file($this->tmpFile))->ownerDocument;
|
||||
|
||||
$dom->formatOutput = true;
|
||||
|
||||
$formatted = $dom->saveXML();
|
||||
|
||||
unset($dom, $this->xml);
|
||||
@ -170,7 +174,7 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
{
|
||||
$categories = self::filterRecursive($categories);
|
||||
|
||||
foreach($categories as $category) {
|
||||
foreach ($categories as $category) {
|
||||
if (!array_key_exists('name', $category) || !array_key_exists('id', $category)) {
|
||||
continue;
|
||||
}
|
||||
@ -278,7 +282,8 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
* @param $key
|
||||
* @param $e
|
||||
*/
|
||||
private function setOffersProperties($value, $key, &$e) {
|
||||
private function setOffersProperties($value, $key, &$e)
|
||||
{
|
||||
if (in_array($key, $this->properties) && $key != 'params') {
|
||||
/** @var SimpleXMLElement $e */
|
||||
$e->addChild($key, htmlspecialchars($value));
|
||||
@ -292,7 +297,8 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
* @param $key
|
||||
* @param $e
|
||||
*/
|
||||
private function setOffersParams($value, $key, &$e) {
|
||||
private function setOffersParams($value, $key, &$e)
|
||||
{
|
||||
if (
|
||||
array_key_exists('code', $value) &&
|
||||
array_key_exists('name', $value) &&
|
||||
@ -323,7 +329,8 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
$haystack[$key] = self::filterRecursive($haystack[$key]);
|
||||
}
|
||||
|
||||
if (is_null($haystack[$key])
|
||||
if (
|
||||
is_null($haystack[$key])
|
||||
|| $haystack[$key] === ''
|
||||
|| (is_array($haystack[$key]) && count($haystack[$key]) == 0)
|
||||
) {
|
||||
@ -341,26 +348,27 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function get_wc_products_taxonomies($status_args) {
|
||||
private function get_wc_products_taxonomies($status_args)
|
||||
{
|
||||
if (!$status_args) {
|
||||
$status_args = array('publish');
|
||||
$status_args = ['publish'];
|
||||
}
|
||||
|
||||
$attribute_taxonomies = wc_get_attribute_taxonomies();
|
||||
$product_attributes = array();
|
||||
$product_attributes = [];
|
||||
|
||||
foreach ($attribute_taxonomies as $product_attribute) {
|
||||
$attribute_id = wc_attribute_taxonomy_name_by_id(intval($product_attribute->attribute_id));
|
||||
$product_attributes[$attribute_id] = $product_attribute->attribute_label;
|
||||
}
|
||||
|
||||
$full_product_list = array();
|
||||
$full_product_list = [];
|
||||
|
||||
$products = wc_get_products(
|
||||
array(
|
||||
[
|
||||
'limit' => -1,
|
||||
'status' => $status_args
|
||||
)
|
||||
]
|
||||
);
|
||||
|
||||
foreach ($products as $offer) {
|
||||
@ -391,8 +399,9 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_wc_categories_taxonomies() {
|
||||
$categories = array();
|
||||
private function get_wc_categories_taxonomies()
|
||||
{
|
||||
$categories = [];
|
||||
$taxonomy = 'product_cat';
|
||||
$orderby = 'parent';
|
||||
$show_count = 0; // 1 for yes, 0 for no
|
||||
@ -401,7 +410,7 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
$title = '';
|
||||
$empty = 0;
|
||||
|
||||
$args = array(
|
||||
$args = [
|
||||
'taxonomy' => $taxonomy,
|
||||
'orderby' => $orderby,
|
||||
'show_count' => $show_count,
|
||||
@ -409,16 +418,16 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
'hierarchical' => $hierarchical,
|
||||
'title_li' => $title,
|
||||
'hide_empty' => $empty
|
||||
);
|
||||
];
|
||||
|
||||
$wcatTerms = get_categories($args);
|
||||
|
||||
foreach ($wcatTerms as $term) {
|
||||
$category = array(
|
||||
$category = [
|
||||
'id' => $term->term_id,
|
||||
'parentId' => $term->parent,
|
||||
'name' => $term->name
|
||||
);
|
||||
];
|
||||
|
||||
$thumbnail_id = function_exists('get_term_meta')
|
||||
? get_term_meta($term->term_id, 'thumbnail_id', true)
|
||||
@ -533,13 +542,25 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
];
|
||||
|
||||
if ($product->get_sku() != '') {
|
||||
$params[] = array('code' => 'article', 'name' => 'Артикул', 'value' => $product->get_sku());
|
||||
$params[] = ['code' => 'article', 'name' => 'Article', 'value' => $product->get_sku()];
|
||||
|
||||
if (isset($this->settings['bind_by_sku']) && $this->settings['bind_by_sku'] == WC_Retailcrm_Base::YES) {
|
||||
$product_data['xmlId'] = $product->get_sku();
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->settings['product_description'])) {
|
||||
$productDescription = $this->getDescription($product);
|
||||
|
||||
if (empty($productDescription) && $parent instanceof WC_Product_Variable) {
|
||||
$this->getDescription($parent);
|
||||
}
|
||||
|
||||
if ($productDescription != '') {
|
||||
$params[] = ['code' => 'description', 'name' => 'Description', 'value' => $productDescription];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($params)) {
|
||||
$product_data['params'] = $params;
|
||||
}
|
||||
@ -556,8 +577,9 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function checkPostStatuses() {
|
||||
$status_args = array();
|
||||
private function checkPostStatuses()
|
||||
{
|
||||
$status_args = [];
|
||||
|
||||
foreach (get_post_statuses() as $key => $value) {
|
||||
if (isset($this->settings['p_' . $key]) && $this->settings['p_' . $key] == WC_Retailcrm_Base::YES) {
|
||||
@ -567,6 +589,20 @@ if (!class_exists('WC_Retailcrm_Icml')) :
|
||||
|
||||
return $status_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product description
|
||||
*
|
||||
* @param WC_Product | WC_Product_Variable $product WC product.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getDescription($product)
|
||||
{
|
||||
return $this->settings['product_description'] == 'full'
|
||||
? $product->get_description()
|
||||
: $product->get_short_description();
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 5.6
|
||||
*
|
||||
@ -61,6 +62,7 @@ class WC_Retailcrm_Test_Case_Helper extends WC_Unit_Test_Case
|
||||
'debug-info' => '',
|
||||
'order-meta-data-retailcrm' => json_encode(['woo_order' => 'crm_order']),
|
||||
'customer-meta-data-retailcrm' => json_encode(['woo_customer' => 'crm_customer']),
|
||||
'product_description' => 'full',
|
||||
];
|
||||
|
||||
update_option(WC_Retailcrm_Base::$option_key, $options);
|
||||
@ -78,16 +80,18 @@ class WC_Retailcrm_Test_Case_Helper extends WC_Unit_Test_Case
|
||||
} else {
|
||||
global $wpdb;
|
||||
|
||||
foreach ([
|
||||
$wpdb->posts,
|
||||
$wpdb->postmeta,
|
||||
$wpdb->comments,
|
||||
$wpdb->commentmeta,
|
||||
$wpdb->term_relationships,
|
||||
$wpdb->termmeta,
|
||||
] as $table ) {
|
||||
foreach (
|
||||
[
|
||||
$wpdb->posts,
|
||||
$wpdb->postmeta,
|
||||
$wpdb->comments,
|
||||
$wpdb->commentmeta,
|
||||
$wpdb->term_relationships,
|
||||
$wpdb->termmeta,
|
||||
] as $table
|
||||
) {
|
||||
//phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$wpdb->query( "DELETE FROM {$table}" );
|
||||
$wpdb->query("DELETE FROM {$table}");
|
||||
}
|
||||
|
||||
foreach ([$wpdb->terms, $wpdb->term_taxonomy] as $table) {
|
||||
|
@ -119,6 +119,7 @@ class WC_Retailcrm_Base_Test extends WC_Retailcrm_Test_Case_Helper
|
||||
$this->assertArrayHasKey('deactivate_update_order', $this->baseRetailcrm->form_fields);
|
||||
$this->assertArrayHasKey('bind_by_sku', $this->baseRetailcrm->form_fields);
|
||||
$this->assertArrayHasKey('update_number', $this->baseRetailcrm->form_fields);
|
||||
$this->assertArrayHasKey('product_description', $this->baseRetailcrm->form_fields);
|
||||
}
|
||||
|
||||
public function test_retailcrm_form_fields_value()
|
||||
|
@ -14,33 +14,39 @@ class WC_Retailcrm_Icml_Test extends WC_Retailcrm_Test_Case_Helper
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
WC_Helper_Product::create_simple_product();
|
||||
}
|
||||
|
||||
wp_insert_term(
|
||||
'Test', // the term
|
||||
'product_cat', // the taxonomy
|
||||
array(
|
||||
'description'=> 'Test',
|
||||
'slug' => 'test'
|
||||
)
|
||||
);
|
||||
WC_Helper_Product::create_simple_product();
|
||||
WC_Helper_Product::create_variation_product();
|
||||
}
|
||||
|
||||
public function testGenerate()
|
||||
{
|
||||
$icml = new WC_Retailcrm_Icml();
|
||||
|
||||
$icml->generate();
|
||||
|
||||
$this->assertFileExists(ABSPATH . 'simla.xml');
|
||||
|
||||
$xml = simplexml_load_file(ABSPATH . 'simla.xml');
|
||||
$res = $xml->xpath('/yml_catalog/shop/categories/category[@id]');
|
||||
|
||||
$this->assertNotEmpty($res);
|
||||
$this->assertNotEmpty($xml);
|
||||
|
||||
foreach ($res as $node) {
|
||||
$this->assertEquals('category', $node->getName());
|
||||
$xmlArray = json_decode(json_encode($xml), true);
|
||||
|
||||
$this->assertNotEmpty($xmlArray['shop']['categories']['category']);
|
||||
$this->assertCount(2, $xmlArray['shop']['categories']['category']);
|
||||
$this->assertNotEmpty($xmlArray['shop']['offers']['offer']);
|
||||
$this->assertCount(7, $xmlArray['shop']['offers']['offer']);
|
||||
$this->assertNotEmpty($xmlArray['shop']['offers']['offer'][0]);
|
||||
$this->assertNotEmpty($xmlArray['shop']['offers']['offer'][1]);
|
||||
|
||||
foreach ($xmlArray['shop']['offers']['offer'] as $product) {
|
||||
$this->assertNotEmpty($product['name']);
|
||||
$this->assertNotEmpty($product['productName']);
|
||||
$this->assertNotEmpty($product['price']);
|
||||
$this->assertNotEmpty($product['url']);
|
||||
$this->assertNotEmpty($product['param']);
|
||||
$this->assertNotEmpty($product['vatRate']);
|
||||
$this->assertEquals('none', $product['vatRate']);
|
||||
$this->assertContains('Dummy', $product['productName']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user