[РЕШЕНО] Как массово увеличить или уменьшить цены для всех товаров на процент

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

Аватар пользователя maksbaks maksbaks 13 октября 2014 в 18:15

Доброго времени суток!
Прошу помощи в вопросе:
Как в друпал комерц 7, сделать массовое редактирование цен товаров задав только процент или дробь на которую должны умножиться все цены и сохраниться в товарах.

пробовал через VBO и RULES
1)создал views с vbo
2)создал правило(компонент)
вышло создать переменную с ценой и сделать просчет, но вот как это значение занести в товар, не понимаю...(для проверки выводил просчеты в окне справки)

3)включил этот компонент в views поле vbo

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

прошу подсказки...

Комментарии

Аватар пользователя yurasandul@gmail.com yurasandul@gmail.com 13 октября 2014 в 19:23

Вставишь в свой модуль.
Обрати внимание что это делалось для комерца и вьюха должна быть построена по "commerce_product". Ну а если надо, так переделаешь.

<?php

function MYMODULE_action_info(){
  return array(
    
'calc_price' => array(  
      
'type' => 'commerce_product',
      
'label' => t('Пересчитать цену'),       
      
'configurable' => TRUE,       
    ),
  );
}
 
 
// функция отвечающая за пересчет, дополнительные параметры из формы передаются в $context
function calc_price($node$context = array()) {
  
$op='return '.$node->commerce_price['und'][0]['amount'].($context['oper']).';';
  
$res=eval($op);
  
$node->commerce_price['und'][0]['amount']=round($res);
  
commerce_product_save($node);
}
 
// форма ввода дополнительных данных ( к имени функции добавлен префикс '_form' )
function calc_price_form($context) {
  
$form = array();
  
$form['oper'] = array(
    
'#type' => 'textfield',
    
'#title' => 'Введите опреацию',
    
'#description' => 'Допустимы арифметические операции с числами. Пример записи "+10", "-11.5", "*0.95", "/2"',    
  );
  return 
$form;
}
 
// сабмит формы дополнительных данных ( к имени функции добавлен префикс '_submit' )
function calc_price_submit($form$form_state) {
  return array(
'oper' => $form_state['values']['oper']);  
}
 
// также возможна валидация формы ( к имени функции добавлен префикс '_validate' )
function calc_price_validate($form$form_state) {
$op='return 1'.($form_state['values']['oper']).';';
$res=eval($op);
}
?>
Аватар пользователя Dorian76453 Dorian76453 14 октября 2014 в 13:30

а вариант с node_import? выгрузить прайс с полями NID и цена. в excel или openoffice все ячейки цены изменить по формуле и загрузить обратно обновив записи.

ну или в базу полезть

Аватар пользователя yurasandul@gmail.com yurasandul@gmail.com 14 октября 2014 в 16:35

"Dorian76453" wrote:
выгрузить прайс с полями NID и цена. в excel или openoffice все ячейки цены изменить по формуле и загрузить обратно обновив записи

"Барон любит чтоб потруднее" (к/ф "Барон Мюнхаузен")

Аватар пользователя maksbaks maksbaks 21 октября 2014 в 2:30

"sandul" wrote:
Вставишь в свой модуль.

Вставил в свой модуль, отвел отдельную страницу для формы.
Включил модуль, очистил кэш, перешел на страничку, вбил +10, нажал субмит и ничего не поменялось, абсолютно...
подсказки будут? сейчас сам смотрю код, мудрую, но помощи всегда рад!
и еще вопрос как сделать что бы можно было проделывать эти действия только с товарами относящимися к отдельным категориям которые тоже можно было бы выбрать?

Аватар пользователя maksbaks maksbaks 21 октября 2014 в 3:04

вот что получилось


<?php

/**
 * @file
 * A light-weight, customizable lightbox plugin for jQuery 1.3
 */

/**
 * Implements hook_menu().
 */

function my_percentage_menu() {
  
$items = array();

  

$items['admin/config/media/my_percentage'] = array(
    
'title' => t('my percentage'),
    
'description' => t('Массовая манипуляция над ценами'),
    
'page callback' => 'drupal_get_form',
    
'page arguments' => array('calc_price_form'),
    
'access arguments' => array('administer site configuration'),
  );

  return 

$items;
}

function 

my_percentage_action_info(){
  return array(
    
'calc_price' => array(  
      
'type' => 'commerce_product',
      
'label' => t('Пересчитать цену'),       
      
'configurable' => TRUE,       
    ),
  );
}
 
 
// функция отвечающая за пересчет, дополнительные параметры из формы передаются в $context
function calc_price($node$context = array()) {
  
$op='return '.$node->commerce_price['und'][0]['amount'].($context['oper']).';';
  
$res=eval($op);
  
$node->commerce_price['und'][0]['amount']=round($res);
  
commerce_product_save($node);
}
 
// форма ввода дополнительных данных ( к имени функции добавлен префикс '_form' )
function calc_price_form($context) {
  
$form = array();
  
$form['oper'] = array(
    
'#type' => 'textfield',
    
'#title' => 'Введите опреацию',
    
'#description' => 'Допустимы арифметические операции с числами. Пример записи "+10", "-11.5", "*0.95", "/2"',    
  );
  
$form['submit'] = array(
    
'#type' => 'submit',
    
'#value' => t('Send'),
    );

  return 

$form;
}
 
// сабмит формы дополнительных данных ( к имени функции добавлен префикс '_submit' )
function calc_price_submit($form$form_state) {
  return array(
'oper' => $form_state['values']['oper']);  
}
 
// также возможна валидация формы ( к имени функции добавлен префикс '_validate' )
function calc_price_validate($form$form_state) {
$op='return 1'.($form_state['values']['oper']).';';
$res=eval($op);
}

?>
Аватар пользователя Dorian76453 Dorian76453 21 октября 2014 в 11:35

"Барон любит чтоб потруднее" (к/ф "Барон Мюнхаузен")

Возможно и потруднее - но велосипед выдумывать не нужно. Модуль простой в работе, а с таблицами все, надеюсь, умеют работать.
Это ессесно не лучший вариант, но рабочий. Smile

«как сделать что бы можно было проделывать эти действия только с товарами относящимися к отдельным категориям которые тоже можно было бы выбрать?»
тоже можно с помощью node_import.

Блин, ну люблю я потруднее Smile

Аватар пользователя maksbaks maksbaks 21 октября 2014 в 14:40

"Dorian76453" wrote:
Возможно и потруднее - но велосипед выдумывать не нужно. Модуль простой в работе, а с таблицами все, надеюсь, умеют работать.
Это ессесно не лучший вариант, но рабочий. :)

">https://www.drupal.org/project/node_import][/module]
вы про этот модуль, но он только для друпал 6,
пробовал другими модулями, но уж слишком я "люблю" импорт/экспорт чего либо с сайтов, постоянно путанина у меня...

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

Аватар пользователя Dorian76453 Dorian76453 21 октября 2014 в 16:21

для 7 версии https://www.drupal.org/project/feeds
по написанию модуля, помочь не смогу, сам только junior в этом.

Он интуитивно понятен (как для drupal)
погугли, есть много инструкций и скринкастов как с ним работать

Аватар пользователя Dorian76453 Dorian76453 21 октября 2014 в 16:22

Головняк в нем в том, что в коммерце дисплей и сам товар разные сущности, и импортировать нужно будет 2 таблицы. Хотя если тебе только цену изменить, может получится только таблицу с продуктами импортнуть. не пробовал.

Аватар пользователя maksbaks maksbaks 22 октября 2014 в 3:48

"Dorian76453" wrote:
для 7 версии https://www.drupal.org/project/feeds
по написанию модуля, помочь не смогу, сам только junior в этом.
Он интуитивно понятен (как для drupal)

еще один вопс появился...
скачать файл с uid и ценами получилось (и xml, и csv)
но вот проблема состоит в том что как обновить все товары с этого прайса если товары состоят из разных типов нод, при этом поле цены имеет одно и то же машинное имя...
в feeds можно выбрать только один из всех существующих типов, а мне нужно что бы обновление прошло по всем uid из загруженного и обновленного прайса
ужасно расстроило, опять таки прошу подсказок

Аватар пользователя yurasandul@gmail.com yurasandul@gmail.com 22 октября 2014 в 4:33

Попробую еще раз.

"maksbaks" wrote:
пробовал через VBO и RULES
1)создал views с vbo
2)создал правило(компонент)
вышло создать переменную с ценой и сделать просчет, но вот как это значение занести в товар, не понимаю...(для проверки выводил просчеты в окне справки)
3)включил этот компонент в views поле vbo
все работает, но самое главное не могу могу понять как сделлать, не хватает связей, не могу занести значение в товар...

1. Создаешь вьюху с VBO только по "commerce_product" ( не по витрине, а по товару, если это не понятно - переспроси ).
2. Никакие правила создавать не надо.
3. Из того кода что я привел делаешь модуль (в первой функции вместо "MYMODULE" вставляешь имя своего модуля, и делаешь файл MYMODULE.info. Об этом много написано. Если все стандартно - должно работать ). Получается модуль с дополнительной операцией VBO для пересчета цены. (Во вьюхе при добавлении VBO можно будет включить операцию "Пересчитать цену")
4. Если не ориентируешься в товаре по артикулам, добавляешь во вьюхе связи к витрине, включаешь фильтра (бренд, категории)

И последний вопрос насчет "занести значение в товар". Посмотри в коде и найдешь "commerce_product_save($node)", вот она и сохраняет.

Первый пункт важен.

Может и вправду плохо объясняю.

Аватар пользователя maksbaks maksbaks 22 октября 2014 в 5:00

"sandul" wrote:
Может и вправду плохо объясняю.

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

Аватар пользователя maksbaks maksbaks 10 ноября 2015 в 11:49

"sandul" wrote:
1. Создаешь вьюху с VBO только по "commerce_product" ( не по витрине, а по товару, если это не понятно - переспроси ).
2. Никакие правила создавать не надо.
3. Из того кода что я привел делаешь модуль (в первой функции вместо "MYMODULE" вставляешь имя своего модуля, и делаешь файл MYMODULE.info. Об этом много написано. Если все стандартно - должно работать ). Получается модуль с дополнительной операцией VBO для пересчета цены. (Во вьюхе при добавлении VBO можно будет включить операцию "Пересчитать цену")
4. Если не ориентируешься в товаре по артикулам, добавляешь во вьюхе связи к витрине, включаешь фильтра (бренд, категории)
И последний вопрос насчет "занести значение в товар". Посмотри в коде и найдешь "commerce_product_save($node)", вот она и сохраняет.
Первый пункт важен.
Может и вправду плохо объясняю.

модуль почему то выдает ошибку при умножении на 1.07 (*1.07)

при этом -10, +10, /5 проверял, работали корректно

Аватар пользователя maksbaks maksbaks 22 октября 2014 в 18:10

после этого все цены над которыми проделывались действия, равняются 0-лю
уже 3-й раз восстанавливаю бд

Аватар пользователя maksbaks maksbaks 22 октября 2014 в 21:13

"sandul" wrote:
Получается что операции с целыми числами проходят нормально?

да, с целыми абсолютно нормально и деление, и умножение, и +, и -, а вот попробовал 2 раза с дробовым чилом *1.07 и оба раза ошибку выбило

Аватар пользователя yurasandul@gmail.com yurasandul@gmail.com 22 октября 2014 в 21:30

Ну если можешь, давай доступ. Так я больше тебе ничем не могу помочь. Или заглуши запись и повыводи переменные через devel, чтобы посмотреть что оно там считает и пытается записывать.
скайп: sandulyura

Аватар пользователя Orion76 Orion76 22 октября 2014 в 21:56

В скрине ошибки же написано - Вруг откуда не возмись, появилась запятая-)
В php разделитель дробной части "точка"..

чтоб базу из бэкапа каждый раз не поднимать надо в $context['oper']
заменить запятые на точки

<?php
$context
['oper']=str_replace(',''.'$context['oper']);
?>
Аватар пользователя maksbaks maksbaks 22 октября 2014 в 22:19

"orion76" wrote:
чтоб базу из бэкапа каждый раз не поднимать надо в $context['oper']
заменить запятые на точки

то есть нужно вставить эту часть в начало этой функции:

<?php
function calc_price($node$context = array()) {
  
$context['oper']=str_replace(',''.'$context['oper']);
  
$op='return '.$node->commerce_price['und'][0]['amount'].($context['oper']).';';
  
$res=eval($op);
  
$node->commerce_price['und'][0]['amount']=round($res);
  
commerce_product_save($node);
}
?>

что бы если админ случайно забудет ставить точку вместо запятой, то оно её заменит а точку,
правильно?

Аватар пользователя yurasandul@gmail.com yurasandul@gmail.com 23 октября 2014 в 0:06

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

Аватар пользователя maksbaks maksbaks 23 октября 2014 в 0:11

"sandul" wrote:
Вообще то там задумывалась валидация формы , но видать не доделал ...

ну да, валидацию доделать тоже вариант, спасибо всем за помощь!
у самого бы ушло намного больше времени на написание этого чуда...
Спасибо!

Аватар пользователя maksbaks maksbaks 23 октября 2014 в 0:14

"sandul" wrote:
Ведь могут не только запятую поставить. а например две запятые или слово не хорошее ...

согласен, могут написать что угодно и это повлечет уйму ошибок и проблем, нужно будет за пилить валидацию еще, ну это уже справлюсь, спасибо большое за помощь и подсказки!!!

Аватар пользователя Orion76 Orion76 23 октября 2014 в 2:42

Валидация при данном подходе(ввод мат.выражения) сложная штука,
Если правильно организовать ввод "операции", то все намного упроститься..
В общем, необходимы 3 операции "умножить","сложить","отнять"
Для них добавить на форму селект..
А в поле вводить только цифры..
Можно даже для целой и дробной части по полю..

Тогда валидация простенькой регуляркой (проверка на "цифры")
и еще помните, что на НОЛЬ делить нельзя-))

При таком подходе можно и даже нужно избавиться от eval..
Опасная это штука..-)

Да.. хорошобы еще настройку округления добавить