Commerce. Программное создание товаров

Главные вкладки

Аватар пользователя vinny_pooh vinny_pooh 16 января 2013 в 10:49

Здравствуйте, уважаемые друпалеры! Я столкнулся с задачей автоматического наполнения сайта на D7+Commerce товарами. Товары находятся в прайс листе в количестве 52тыс шт.
Но у меня возникла проблема в самом начале... не могу создать сущность. делаю это следующим образом:
Первый вариант, который делал сам:

<?php
function conver_csv_to_entities(){
        echo 
"Creation entities...<br>";
        
$f fopen("Kprice3.csv""r") or die("Error! Can not open file");
        for (
$i=0$data=fgetcsv($f,0,"\t"); $i++) {
            
$num count($data);
            if(
$i != 0){
                
// echo "<h3>String number - $i (fields: $num):</h3>";            
                // echo "SKU: ".$data[0]."<br>";
                // echo "Name: ".$data[1]."<br>";
                // echo "Price: ".$data[2]."<br>";
                // echo "Brand: ".$data[6]."<br>";            

                

$product commerce_product_new('product');
                
$product->product_id $i+1123;
                
$product->uid 1;
                
$product->revision_id $i+1234;
                
$product->title $data[1];
                
$product->sku $data[0];
                
$product->commerce_price[LANGUAGE_NONE][0] = array(
                  
'amount' => $data[2]*100,
                  
'currency_code' => commerce_default_currency(),
                );                
                
commerce_product_save($product);
            }        
        }
        
fclose($f);
    }
?>

и второй вариант исполнения, ссылку на который я нашел здесь на форуме (http://drupal.stackexchange.com/questions/23168/commerce-product-program...):

<?php
function conver_csv_to_entities(){
        echo 
"Creation entities...<br>";
        
$f fopen("Kprice3.csv""r") or die("Error! Can not open file");
        for (
$i=0$data=fgetcsv($f,0,"\t"); $i++) {
            
$num count($data);
            if(
$i != 0){
                
// echo "<h3>String number - $i (fields: $num):</h3>";            
                // echo "SKU: ".$data[0]."<br>";
                // echo "Name: ".$data[1]."<br>";
                // echo "Price: ".$data[2]."<br>";
                // echo "Brand: ".$data[6]."<br>";

                

$product_type 'product';

                

$values = array (
                    
'price' => $data[2]*100 ,
                    
'currency_code' => commerce_default_currency() ,
                );

                

$extras = array(
                    
'status' => 1,
                    
'uid' => 1,
                    
'sku' => $data[0],
                    
'title' => $data[1],
                );

                

commerce_installments_create_product ($product_type,$values,$extras);
            }

        
            if(

$i == 10) break;
        }
        
fclose($f);
    }

    function 

commerce_installments_create_product $product_type $values $extras ) {
        
$form_state = array ();
        
$form_state'values' ] = $values;
        
$form = array ();
        
$form'#parents' ] = array ();

        

// Generate a new product object
        
$new_product commerce_product_new $product_type );

        

$new_product->status $extras'status' ];
        
$new_product->uid $extras'uid' ];

        

$new_product->sku $extras'sku' ];
        
$new_product->title $extras'title' ];
        
$new_product->created $new_product->changed time ();

        if ( ! empty( 

$values'original_order' ] ) ) {
            
// field_original_order[und][0][target_id]
            
$order = array ( LANGUAGE_NONE => array ( => array ( 'target_id' => $values'original_order' ] ) ) );
            
$form_state'values' ][ 'field_original_order' ] = $order;
        }

        if ( ! empty( 

$values'original_line_item' ] ) ) {
            
// field_original_line_item[und][0][target_id]
            
$line_item = array ( LANGUAGE_NONE => array ( => array ( 'target_id' => $values'original_line_item' ] ) ) );
            
$form_state'values' ][ 'field_original_line_item' ] = $line_item;
        }

        if ( ! empty( 

$values'original_product' ] ) ) {
            
$product = array ( LANGUAGE_NONE => array ( => array ( 'target_id' => $values'original_product' ] ) ) );
            
$form_state'values' ][ 'field_original_product' ] = $product;
        }

        

//commerce_price[und][0][amount]
        
$price = array ( LANGUAGE_NONE => array ( => array (
            
'amount' => $values'price' ] ,
            
'currency_code' => $values'currency_code' ],
        ) ) );
        
$form_state'values' ][ 'commerce_price' ] = $price;

        

// Notify field widgets to save their field data
        
field_attach_submit 'commerce_product' $new_product $form $form_state );

        

commerce_product_save $new_product );
        return 
$new_product->product_id;
    }
?>

но в итоге ничего не происходит... выдает только ошибки друпала:
«Notice: Undefined offset: 0 в функции _menu_check_access() (строка 632 в файле /home/kupets/public_html/includes/menu.inc).
Notice: Undefined offset: 1 в функции _menu_check_access() (строка 632 в файле /home/kupets/public_html/includes/menu.inc).
PDOException: в функции drupal_write_record() (строка 7036 в файле /home/kupets/public_html/includes/common.inc).
На сайте произошла непредвиденная ошибка. Пожалуйста, повторите попытку позже.»

Помогите пожалуйста с решением этого вопроса!!!

Комментарии

Аватар пользователя vinny_pooh vinny_pooh 18 января 2013 в 1:40

Ошибку «Notice: Undefined offset: 0 в функции _menu_check_access() (строка 632 в файле /home/kupets/public_html/includes/menu.inc).» решил. Я заменил 'access callback' => 'user_access' на 'access callback' => TRUE

Теперь при попытке создать товар по этому выдает ошибку: «PDOException: в функции drupal_write_record() (строка 7036 в файле /home/kupets/public_html/includes/common.inc).»

а если делаю так:

<?php
function conver_csv_to_entities(){
        echo 
"Creation entities...<br>";
        
$f fopen("Kprice3.csv""r") or die("Error! Can not open file");
        for (
$i=0$data=fgetcsv($f,0,"\t"); $i++) {
            
$num count($data);
            if(
$i != 0){
                
// echo "<h3>String number - $i (fields: $num):</h3>";            
                // echo "SKU: ".$data[0]."<br>";
                // echo "Name: ".$data[1]."<br>";
                // echo "Price: ".$data[2]."<br>";
                // echo "Brand: ".$data[6]."<br>";            

                

$product commerce_product_new('product');
                
$product->product_id $i+1123;
                
$product->uid 1;
                
$product->revision_id $i+1234;
                
$product->title $data[1];
                
$product->sku $data[0];
                
$product->commerce_price[LANGUAGE_NONE][0] = array(
                  
'amount' => $data[2]*100,
                  
'currency_code' => commerce_default_currency(),
                );                
                
commerce_product_save($product);
            }        
        }
        
fclose($f);
    }
?>

то код выполняется, но ничего не добавляет... commerce_product_save($product) - всегда возвращает 2.
помогите плиз!

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 16 января 2013 в 12:25

Из приведённого кода видно, что вы не очень точно понимаете, что делаете.

Такой код неправильный изначально - я имею ввиду простейшее использование fgetcsv и прямое чтение из файла. Если commerce_product_save возвращает 2 (http://drupalcontrib.org/api/drupal/drupal!includes!common.inc/constant/...), то означает, что выполняется обновление существующего товара. У вас ошибки при чтении файла скорее всего или в цикле. Вы бы посмотрели значения внутри цикла сначала без commerce_product_save

Используйте commerce_feeds лучше. Очень долго

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 16 января 2013 в 12:27

И если у вас периодическое обновление этой товарной базы, то нужно писать кастомное решение под себя. Иначе обновлять будет сутками

Аватар пользователя vinny_pooh vinny_pooh 16 января 2013 в 13:25

Дело в том что я хочу создать сразу и представления товара, а с Feeds я этого не сделаю.

Данные в цикле проверял, они коректные.

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 16 января 2013 в 13:36

Да это можно сделать и через feeds. Навскидку - использовать hook_entity_insert чтобы отслеживать создание продукта. Чтобы точно идентифицировать созданный товар таким, что был создан при автоматически, отслеживать его автора

Конечно Feeds - не решение для больших товарных баз и правильно делаете, что пишете под себя, но это не будет решение в 10 строк

Аватар пользователя vinny_pooh vinny_pooh 16 января 2013 в 13:56

Ну это понятное дело, я и не расчитывал на это. Мне нужно будет потом часто обновлять эту базу, поэтому кроме как кастомного решения я не вижу других... по этому вопрос по ошибке остается открытым, т.к. Вы правильно заметили, что я не совсем хорошо понимаю что там происходит... и прошу помощи разобраться с добавлением товаров.

Аватар пользователя vinny_pooh vinny_pooh 16 января 2013 в 14:29

Я попробовал добавить товар точно как в примере... ничего не вышло, все та же ошибка....

Заметил такую штуку: когда я попытался удалить ранее созданный тестовый товар, то я не смог этого сделать... выдало сообщение: «This product is referenced by a line item and therefore cannot be deleted. Disable it instead.» Что это может быть?
Может из-за этого не создаются товары программно?

Аватар пользователя vinny_pooh vinny_pooh 16 января 2013 в 14:50

Что-то ничего не выходит... вот код:

<?php
function conver_csv_to_entities(){
        echo 
"Creation entities...<br>";
            
$product_type 'product';               
                  
$extras = array(
           
'status' => 1,
           
'uid' => 1,
           
'sku' => '777666777',
           
'title' => 'My product',
        );
        
$result create_product ($product_type,123,$extras);        
    }

    function 

create_product($product_type$price$extras) {        
      
$form_state = array();
      
$form_state['values'] = array();
      
$form = array();
      
$form['#parents'] = array();

      

// Generate a new product object
      
$new_product commerce_product_new($product_type);

      

$new_product->status $extras['status'];
      
$new_product->uid $extras['uid'];
      
$new_product->product_id time();
      
$new_product->sku $extras['sku'];
      
$new_product->title $extras['title'];
      
$new_product->created $new_product->changed time();

      

//commerce_price[und][0][amount]
      
$price = array(LANGUAGE_NONE => array(=> array(
        
'amount' => $price 100,
        
'currency_code' => commerce_default_currency(),
      )));
      
$form_state['values']['commerce_price'] = $price;

      

// Notify field widgets to save their field data
      
field_attach_submit('commerce_product'$new_product$form$form_state);     
      
commerce_product_save($new_product);
      return 
$new_product->product_id;
    }
?>

Код выполняется. Ошибок нет. Но и товар не добавляется. Функция возвращает новый id. Функция из примера commerce_example. Я уже в отчаянии... не знаю что делать... помогите, пожалуйста с решением!

Аватар пользователя ser_house ser_house 16 января 2013 в 20:11

"vinny_pooh" wrote:
Заметил такую штуку: когда я попытался удалить ранее созданный тестовый товар, то я не смог этого сделать... выдало сообщение: «This product is referenced by a line item and therefore cannot be deleted. Disable it instead.» Что это может быть?

Почистите заказы на сайте.

Аватар пользователя vinny_pooh vinny_pooh 17 января 2013 в 14:33

Люди, помогите плиз выяснить, почему не создаются товары программно???
Я скачал примеры commerce. Взял оттуда функцию добавления товаров. Сделал небольшой модуль AddGoods. Вот что у меня сейчас есть:

файл addgoods.info:

name = Add Goods
description = "Convert .csv file to product entities and create views"
package = Content
core = 7.x
configure = admin/config/content/addgoods

файл addgoods.module:

<?php
/**
 * Implements hook_menu().
 */
function addgoods_menu(){
    
$items['admin/content/addgoods'] = array(
          
'title' => 'Add Goods',
        
'page callback' => 'conver_csv_to_entities',
        
'access callback' => TRUE,
        
'file' => 'addgoods.inc',
        
'type' => MENU_LOCAL_TASK,
    );

    return 

$items;
}
?>

и файл addgoods.inc с добавлением товаров:

<?php
function conver_csv_to_entities(){
        echo 
"Creation entities...<br>";
        
$product_type 'product';               

                 

$extras = array(
                
'status' => 1,
                
'uid' => 1,
                
'sku' => '777666777',
                
'title' => 'My product',
        );

        

$result create_product ($product_type,123,$extras);
                echo 
'result=>'.$result;
    }

    function 

create_product($product_type$price$extras) {
        echo 
"in function<br>";
      
$form_state = array();
      
$form_state['values'] = array();
      
$form = array();
      
$form['#parents'] = array();

      

// Generate a new product object
      
$new_product commerce_product_new($product_type);

      

$new_product->status $extras['status'];
      
$new_product->uid $extras['uid'];
      
$new_product->product_id time();
      
$new_product->sku $extras['sku'];
      
$new_product->title $extras['title'];
      
$new_product->created $new_product->changed time();

      

//commerce_price[und][0][amount]
      
$price = array(LANGUAGE_NONE => array(=> array(
        
'amount' => $price 100,
        
'currency_code' => commerce_default_currency(),
      )));
      
$form_state['values']['commerce_price'] = $price;

      

// Notify field widgets to save their field data
      
echo "before attach<br>";
      
field_attach_submit('commerce_product'$new_product$form$form_state);
      echo 
"before save<br>";
      echo 
"<pre>";
      
print_r($new_product);
      echo 
"</pre>";
      return 
commerce_product_save($new_product);     
    }
?>

в итоге у меня получается следующее:

Creation entities...
in function
before attach
before save
stdClass Object
(
    [type] => product
    [product_id] => 1358417491
    [is_new] => 1
    [sku] => 777666777
    [revision_id] =>
    [title] => My product
    [uid] => 1
    [status] => 1
    [created] => 1358417491
    [changed] => 1358417491
    [commerce_price] => Array
        (
            [und] => Array
                (
                    [0] => Array
                        (
                            [amount] => 12300
                            [currency_code] => UAH
                        )

                )

        )

)
result=>2

Помогите, пожалуйста, решить данную проблему. Почему может так происходить

Аватар пользователя LeGront@drupal.org LeGront@drupal.org 17 января 2013 в 14:37
<?php
        
// Работа с товаром 
        
$product commerce_product_load_by_sku($sku);
        
$product->type 'product';
        
$product->sku $sku;
        
$product->title trim($data[1]);
        
// Устанавливаем цену с учетом скидки
        
$price = (int)trim($data[3]);
        
$product->commerce_price['und'][0]['amount'] = (int)(($price $price $node->field_sale['und'][0]['value'] * 0.01) * 100); // Цена товара
        
$product->commerce_price['und'][0]['currency_code'] = 'UAH';
        
$product->status 1;
        
$product->commerce_stock['und'][0]['value'] = (int)trim($data[4]);
        
commerce_product_save($product);
        
$node->field_product['und'][0]['product_id'] = $product->product_id;
?>

У меня так работает. Все делать надо в баче, т.к. 52к товаров за один заход явно не войдут.

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 17 января 2013 в 15:15

Так теперь я не понял, commerce_product_load_by_sku($sku) - это загрузить существующий товар по его артиклу.
У вас же проблема, что товары новые не создаются?

$new_product->product_id = time(); - выглядит очень странно. Это в примере такое есть?

<?php
$product 
commerce_product_save($new_product);
$product_id $product->product_id;
?>
Аватар пользователя LeGront@drupal.org LeGront@drupal.org 17 января 2013 в 15:32

У меня такая ситуация:
Ноды может не быть, а товар, с таким артикулом существовать, то есть - если нет ноды, я создаю новую, пытаюсь подгрузить товар - если его нет, создается новый в который вносятся все необходимые поля, если он есть - то просто обновляется.

Аватар пользователя vinny_pooh vinny_pooh 18 января 2013 в 1:37

Люди а подскажите еще пожалуйста, как добавить программно ссылку на товар (при создании ноды для представления товара)???

Аватар пользователя vinny_pooh vinny_pooh 18 января 2013 в 1:47

Саму ноду я создаю таким образом:

<?php
$node 
= new stdClass(); // Создаем объект node
$node->type "_autopart"// Определяем тип создаваемого материала
node_object_prepare($node); // добавляем настройки по-умолчанию

$node->title    $title// Название материала
$node->language 'und'// Или например 'ru', если включен модуль locale

$node->uid 1// UID пользователя

// Заполнение поля body    

$node->body[$node->language][0]['value'] = $title;
$node->body[$node->language][0]['summary'] = text_summary($title);
$node->body[$node->language][0]['format']  = 'filtered_html';
$node->field_creator[$node->language][]['tid'] = $term->tid// здесь добавляю ссылку на темин

// $node->path = array('alias' => 'path_to_this_node'); // путь к материалу, для модуля path

// Дополнительные  свойства ноды

$node->status 1// Опуликовано (1) или нет (0)
$node->promote 1// Размещено на главной  (1) или нет (0)
$node->sticky 1// Закреплено вверху списков  (1) или нет (0)
$node->comment 2// Комментарии включены  (2) или нет (1)

if($node node_submit($node)) { // Подготовка к сохранению
    
node_save($node); // Сохранение ноды, теперь доступен nid новой ноды $node->nid
}

?>

я понимаю, что нужно сделать что-то типа этого:

<?php
$node
->field_product[$node->language][]['id'] = $new_id;
?>

но передавать ID нового товара или его SKU?
и что писать вместо "id"?

Аватар пользователя vinny_pooh vinny_pooh 18 января 2013 в 11:52

О, спасибо! супер, теперь и ноды создаются!)

кто знает с чем связана эта ошибка:

PDOException: SQLSTATE[23000]:
Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1124-0-0-und' for key 'PRIMARY':
INSERT INTO {field_data_commerce_price}
(entity_type, entity_id, revision_id, bundle, delta, language, commerce_price_amount, commerce_price_currency_code, commerce_price_data)
VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8); Array ( [:db_insert_placeholder_0] => commerce_product [:db_insert_placeholder_1] => 1124 [:db_insert_placeholder_2] => 1140 [:db_insert_placeholder_3] => product [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => und [:db_insert_placeholder_6] => 180 [:db_insert_placeholder_7] => UAH [:db_insert_placeholder_8] => ) в функции field_sql_storage_field_storage_write() (строка 448 в файле /home/kupets/public_html/modules/field/modules/field_sql_storage/field_sql_storage.module).

Я так понимаю что-то с ключами не так? и как можно избежать этого?

Аватар пользователя ser_house ser_house 18 января 2013 в 12:54
  $new_product = commerce_product_new($my_type);
  // или из уже существующего продукта
  // $new_product = clone $std_product;

  $new_product->field1[LANGUAGE_NONE][0]['value'] = $my_value;
  $new_product->field2[LANGUAGE_NONE][0]['value'] = $my_value2;

  // Считаем новую цену в своей функции по нужным аргументам.
  $price = _my_module_calculate_price($arg1, $arg2);
  $new_product->commerce_price[LANGUAGE_NONE][0]['amount'] = $price;
  // Если продукт не "clone", в противном случае код валюты уже есть.
  $new_product->commerce_price[LANGUAGE_NONE][0]['currency_code'] = commerce_default_currency();
 
  // Если было clone
  // $new_product->product_id = $new_product->revision_id ='';
  // $new_product->created = '';
  // $new_product->is_new = TRUE;

  // Формируем уникальный sku в своей функции по своему алгоритму из полей продукта, например.
  $new_product->sku = _my_module_make_sku($new_product);

  commerce_product_save($new_product);

  // Если это функция и нам нужно вернуть id созданного продукта.
  // return $new_product->product_id;

Если при создании (уже после некоторых попыток) возникают исключения PDO, надо почистить:
заказы, если есть
корзину, если код должен в неё что-то добавлять (вероятно, что в ней уже что-то есть с прошлых попыток)
товары с прошлых попыток

И вообще, проверить все таблицы в базе, начинающиеся с "commerce_", а также поля, в названии которых есть "_commerce_".

Вроде ничего не забыл.

Аватар пользователя vinny_pooh vinny_pooh 18 января 2013 в 13:10

Дело в том, что товары я заливаю с нуля. Заказов нет. Корзин тоже нет. Товары создаются и эта ошибка происходит где-то на второй тысяче товаров...
Есть ли какая-то возможность проверить существование этого "key", который "Duplicate", чтоб если он есть, то заменить текущий на другой (добавить, например, time() в конец этого key'я)???

Аватар пользователя ser_house ser_house 18 января 2013 в 13:33

"vinny_pooh" wrote:
эта ошибка происходит где-то на второй тысяче товаров...

Наверное, при создании 1124-го товара? Smile

Цена присваивается товару, который уже имеет цену. То есть он уже сущствует. Проверьте источник данных, думаю, там дубликат (всё-таки 52 тысячи).

Аватар пользователя vinny_pooh vinny_pooh 18 января 2013 в 14:00

"ser_house" wrote:
Цена присваивается товару, который уже имеет цену. То есть он уже сущствует

Мне кажется проблема не в этом, так как при создании товара, первым делом что я делаю это:

<?php
$product 
commerce_product_load_by_sku($sku);
?>

То есть если товар уже создан, он будет редактироваться (и это так и происходит). На данный момент функция добавления товаров у меня выглядит так:

<?php
function add_product($sku$title$price$brand){
    
$sku iconv('Windows-1251''utf-8'addslashes(trim($sku)));
    
$title iconv('Windows-1251''utf-8'addslashes(trim($title)));
    
$brand iconv('Windows-1251''utf-8'addslashes(trim($brand)));
    
$price = (double)trim($price);    

    

$terms taxonomy_get_term_by_name($brand'creator');
    if(empty(
$terms)){
        
$vocabulary taxonomy_vocabulary_machine_name_load('creator');
        
$term = (object)array('vid' => $vocabulary->vid'name' => $brand);
        
taxonomy_term_save($term);
    }
    else{
        
$term array_shift($terms);
    }

    

$product commerce_product_load_by_sku($sku);
    
$product->type 'product';
    
$product->sku $sku;
    
$product->title $title;    
    
$product->field_creator['und'][0]['tid'] = $term->tid;
    
// Устанавливаем цену с учетом скидки        
    
$product->commerce_price['und'][0]['amount'] = (int)($price 100); // Цена товара
    
$product->commerce_price['und'][0]['currency_code'] = 'UAH';
    
$product->status 1;
    
$product->commerce_stock['und'][0]['value'] = (int)trim('456789');
    
$new_id commerce_product_save($product);  

    

$node = new stdClass(); // Создаем объект node
    
$node->type "_autopart"// Определяем тип создаваемого материала
    
node_object_prepare($node); // добавляем настройки по-умолчанию

    

$node->title    $title// Название материала
    
$node->language 'und'// Или например 'ru', если включен модуль locale

    

$node->uid 1// UID пользователя

    // Заполнение поля body    
    

$node->body[$node->language][0]['value'] = $title;
    
$node->body[$node->language][0]['summary'] = text_summary($title);
    
$node->body[$node->language][0]['format']  = 'filtered_html';
    
$node->field_creator[$node->language][]['tid'] = $term->tid;
    
$node->field_product[$node->language][0]['product_id'] = $product->product_id;

    

// Дополнительные  свойства ноды
    
$node->status 1// Опуликовано (1) или нет (0)
    
$node->promote 1// Размещено на главной  (1) или нет (0)
    
$node->sticky 1// Закреплено вверху списков  (1) или нет (0)
    
$node->comment 2// Комментарии включены  (2) или нет (1)

    

if($node node_submit($node)) { // Подготовка к сохранению
        
node_save($node); // Сохранение ноды, теперь доступен nid новой ноды $node->nid
    
}

    

// echo "node is:<br><pre>";
    // print_r($product);
    // echo "</pre>";
}    
?>

Насколько я понимаю, мне просто нужно проверить этот ключ, который дублируется, и если он уже есть сдеать его уникальным, но как проверить его существование я не знаю... в этом сейчас и стоит вопрос.

Аватар пользователя vinny_pooh vinny_pooh 18 января 2013 в 15:58

Решил я попробовать импортировать товары в базу через Feeds... Успехом это не увенчалось.
Проявилось сразу несколько проблем

  1. Кодировка. Товары добавляются в виде кракозябров.
  2. Некорректно добавляется цена на товары
  3. Как можно добавить привязать термин таксономии к товару, имя только имя
  4. Импорт товаров закончился на 61% с ошибками
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1124-0-0-und' for key 'PRIMARY'
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1125-0-0-und' for key 'PRIMARY'
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1126-0-0-und' for key 'PRIMARY'
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1127-0-0-und' for key 'PRIMARY'
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1128-0-0-und' for key 'PRIMARY'
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1129-0-0-und' for key 'PRIMARY'
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1130-0-0-und' for key 'PRIMARY'
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1131-0-0-und' for key 'PRIMARY'
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1132-0-0-und' for key 'PRIMARY'
    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'commerce_product-1133-0-0-und' for key 'PRIMARY'

Опять все упирается в этот ключ. Что это за ключ? Как его проверить?

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 18 января 2013 в 17:30

"vinny_pooh" wrote:

Кодировка. Товары добавляются в виде кракозябров.
Некорректно добавляется цена на товары
Как можно добавить привязать термин таксономии к товару, имя только имя
Импорт товаров закончился на 61% с ошибками

1) У вас файл неправильно закодирован либо какие то странности с БД. Вам говорили выше. Друпал корректно работает со всем, что имеет UTF-8
2) В Commerce цены все в минорных единицах хранятся в БД. Т.е в копейках. Написано об этом неоднократно. Используйте Feeds Tamper
3) Можно и по имени и по ID
4) Это потому что вы своим кривым кодом ранее подабовляли товары с кривыми ID

Аватар пользователя vinny_pooh vinny_pooh 18 января 2013 в 17:50

"<a href="mailto:volocuga@drupal.org">volocuga@drupal.org</a>" wrote:
Это потому что вы своим кривым кодом ранее подабовляли товары с кривыми ID

в чем его кривость?
вот есть моя функция добавления товаров, принимающая sku, заголовок, цену и термин таксономии (в моем случае это производитель):

<?php
function add_product($sku$title$price$brand){
    
$sku iconv('Windows-1251''utf-8'addslashes(trim($sku)));
    
$title iconv('Windows-1251''utf-8'addslashes(trim($title)));
    
$brand iconv('Windows-1251''utf-8'addslashes(trim($brand)));
    
$price = (double)trim($price);    

    

$terms taxonomy_get_term_by_name($brand'creator');
    if(empty(
$terms)){
        
$vocabulary taxonomy_vocabulary_machine_name_load('creator');
        
$term = (object)array('vid' => $vocabulary->vid'name' => $brand);
        
taxonomy_term_save($term);
    }
    else{
        
$term array_shift($terms);
    }

    

$product commerce_product_load_by_sku($sku);
    
$product->type 'product';
    
$product->sku $sku;
    
$product->title $title;    
    
$product->field_creator['und'][0]['tid'] = $term->tid;
    
// Устанавливаем цену с учетом скидки        
    
$product->commerce_price['und'][0]['amount'] = (int)($price 100); // Цена товара
    
$product->commerce_price['und'][0]['currency_code'] = 'UAH';
    
$product->status 1;
    
$product->commerce_stock['und'][0]['value'] = (int)trim('456789');
    
$new_id commerce_product_save($product);  

    

$node = new stdClass(); // Создаем объект node
    
$node->type "_autopart"// Определяем тип создаваемого материала
    
node_object_prepare($node); // добавляем настройки по-умолчанию

    

$node->title    $title// Название материала
    
$node->language 'und'// Или например 'ru', если включен модуль locale

    

$node->uid 1// UID пользователя

    // Заполнение поля body    
    

$node->body[$node->language][0]['value'] = $title;
    
$node->body[$node->language][0]['summary'] = text_summary($title);
    
$node->body[$node->language][0]['format']  = 'filtered_html';
    
$node->field_creator[$node->language][]['tid'] = $term->tid;
    
$node->field_product[$node->language][0]['product_id'] = $product->product_id;

    

// Дополнительные  свойства ноды
    
$node->status 1// Опуликовано (1) или нет (0)
    
$node->promote 1// Размещено на главной  (1) или нет (0)
    
$node->sticky 1// Закреплено вверху списков  (1) или нет (0)
    
$node->comment 2// Комментарии включены  (2) или нет (1)

    

if($node node_submit($node)) { // Подготовка к сохранению
        
node_save($node); // Сохранение ноды, теперь доступен nid новой ноды $node->nid
    
}    
}    
?>

что в этой функции кривого? подскажите, давайте сделаем не кривой.

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 18 января 2013 в 18:12

Я имел ввиду ваши начальные попытки манипулировать вручную ID товаров.

Далее

<?php   

   $product 

commerce_product_load_by_sku($sku);
    
$product->type 'product';
    
$product->sku $sku;
    
$product->title $title;    
    
$product->field_creator['und'][0]['tid'] = $term->tid;
    
// Устанавливаем цену с учетом скидки        
    
$product->commerce_price['und'][0]['amount'] = (int)($price 100); // Цена товара
    
$product->commerce_price['und'][0]['currency_code'] = 'UAH';
    
$product->status 1;
    
$product->commerce_stock['und'][0]['value'] = (int)trim('456789');

?>

Как я понял вы проверяете наличие данного товара по его артиклю и если нет - создать.
Думаю, логичнее будет делать так

<?php
  $product 
commerce_product_load_by_sku($sku);
  if (!
$product) {
    
$product commerce_product_new();
  }
?>
Аватар пользователя vinny_pooh vinny_pooh 18 января 2013 в 18:16

commerce_product_load_by_sku это и делает. Он проверяет есть ли товар с таким артикулом и если есть, то он его обновляет, а если нет, то создает дефолтный пустой объект товара.

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 18 января 2013 в 18:21

Ну я верю докам

http://api.drupalcommerce.org/api/Drupal%20Commerce/sites!all!modules!co...

entity_load

When no results are found, an empty array is returned.

"vinny_pooh" wrote:
Он проверяет есть ли товар с таким артикулом и если есть, то он его обновляет

С чего бы ему обновлять ваш товар, он просто его загружает

Аватар пользователя vinny_pooh vinny_pooh 20 января 2013 в 16:27

Люди, скажите плиз, как можно перебрать все ноды сайта? Как оказалось в базе товаров (источника), было много дубляжей (около 4тыс.) Товары в комерц создались нормально, без дубляжей, а вот ноды (представления товара) создались с дубляжами...
я сейчас хочу пробежаться по всем нодам и удалить все дубляжи (проверить ссылки на товар).

Аватар пользователя vinny_pooh vinny_pooh 21 января 2013 в 16:22

Для того чтобы не добавлять одинаковые ноды я дописал такую приблуду:

<?php
$row 
db_query(
    
"SELECT node.nid
    FROM node, field_data_field_product
    WHERE field_data_field_product.field_product_product_id = :myid
    AND field_data_field_product.entity_id = node.nid
    AND node.type =  '_autopart';"

    array(
':myid' => $product->product_id))->fetchField();
 if(!isset(
$row['nid'])) {
      
// код добавления ноды
}
?>

делается запрос в БД и получаются товары, которые уже ссылаются на добавляемый. Если таковые есть, то добавление не происходит.

Аватар пользователя vinny_pooh vinny_pooh 21 января 2013 в 16:54

Чтобы почистить уже имеющиеся дублированые ноды я написал такую функцию:

<?php
function delete_duplicates($sku){
    
$sku iconv('Windows-1251''utf-8'trim($sku));
    
$product commerce_product_load_by_sku($sku);        
    
$row db_query(
        
"SELECT node.nid
        FROM node, field_data_field_product
        WHERE field_data_field_product.field_product_product_id = :myid
        AND field_data_field_product.entity_id = node.nid
        AND node.type =  '_autopart';"

        array(
':myid' => $product->product_id))->fetchAll();
    if(
count($row) > 1){
        for(
$i 1$i count($row); $i++){
            
node_delete($row[$i]->nid);            
        }                    
    }
}
?>