Собстно, задача в том, что есть две категории клиентов. Для каждой категории установлена (вручную) своя цена.
Сделал так:
1. Добавил в продукт поле price2 типа price
2. Создал "правило":
Event: Calculating the sell price of a product
Condition: Entity has field Parameter: Entity: [commerce-line-item], Field: commerce_product
Condition: Entity has field Parameter: Entity: [commerce-line-item:commerce-product Field: field_price2
Condition: User: [site:current-user], Roles: выбираем роли, для которых цена.
Action: Commerce Line Item: Set the unit price to a specific amount: Parameter: Line item: [commerce_line_item], Value: [commerce-line-item:commerce-product:field-price2:amount]
Всё.
Комментарии
Спасибо!
У меня есть вопрос:
Использую на сайте Drupal Commerce.
У сущности товар есть 2 поля цены:
1-розничная цена.
2-оптовая цена.
Оптовая цена должна срабатывать, когда покупатель добавил в корзину товаров на сумму больше 1000грн.
Как можно решить данную задачу?
Знаю что можно сделать это с помощью Rules.
Только у меня никак не получается в Rules проверить текущую сумму заказа в корзине.
2 milkovsky:
Примерно такое правило нужно создать:
Event: Calculating the sell price of a product
Condition: Order is a shopping cart (не уверен нужно ли)
Condition: Data comparison: commerce-line-item:order:commerce-order-total:amount (Operator: is greater than, Data value: 100000)
Action:Set the unit price to a specific amount
Спасибо, 5n00py .
Я это правило сделал. Правило сработало, цена стала оптовой.
Но тут возникла такая загвоздка:
После того, как срабатывает оптовая цена в корзине сумма становится меньше 1000грн. И после перезагрузки страницы срабатывает снова старая розничная цена.
Тут скорее нужно подсчитывать сумму оптовых цен всех товаров в корзине.
Да вы правы
Это тоже можно реализовать с помощью ruleset, общий принцип такой:
Структура ruleset:
actions:
итоговое значение должно включать потовую цену товара, для которого считаем цену
set_price
Этот рулсет добавляете в действия основного правила.
Немного сложно но должно работать У меня намечается 5 колонок цен, буду делать с помощью рулзов.
У меня тут тоже намечается не менее 5 колонок цен. Расскажи плз поподробнее как это удалось реализовать (если удалось ;о) )?
Для основной цены планирую оставить стандартное поле commerce_price. Для ещё 4 штук - лучше сделать у товара ещё одно поле field_prices_wholesale с несколькими значениями или удобнее будут отдельные field_price2 - field_price5 поля?
И стоит ли делать поля именно типа Price или может (чтобы быстрее работало) лучше обойтись обычными полями типа int?
Будут ли нужные мне цены отображаться на страницах товара тоже (если юзер с нужными ролями залогинился) или только в корзине?
Для каждого уровня цен пользователю (в зависимости от суммы продаж) нужно будет заводить ещё 4 роли или лучше как-то без зоопарка ролей обойтись?
Какие ещё меня ожидают проблемы и подводные кирпичи?
Заранее благодарю за помощь!
спасибо большое за помощь! буду пробовать, напишу что получится.
Да, 5 цен - нехило)
удалил
удалил
Не могу достучатся до поля "line_item:wholesale_price", в списке не показывается wholesale_price
Похоже, в этом месте не возможно узнать wholesale_price у line_item
Да, что-то я проглядел. Похоже интеграция line_items с rules не полная
В таблице commerce_line_items есть поле data, в котором и есть product_id но похоже в правилах это поле не доступно
Попробую на след неделе создать ussue и решить проблему.
Плохо конечно что есть такие недоработки, но commerce еще молодой и думаю решение таких проблем - вопрос времени.
Самым быстрым решением проблемы будет наверное написание собственного плагина по rules, всего пара хуков и немножко кода.
ЗЫ: Странно почему в основном правиле [commerce-line-item:commerce-product:field-price2:amount] такая штука работает а в компоненте нет, посмотрю когда будет немного времени.
Спасибо за ответ.
Я смотрел код коммерца. Поля, которые поля которые появляются в rules у "commerce-line-item:" создаются в коде как токены.
Похоже прийдется написать собственный токен для рулсов под свое поле.
Пока не знаю как, буду учить rules api)
А что делать если для отображения товара используется нода, а сущность создается через rules при создании ноды. (описано здесь). Вопрос в следующем - я создаю цену как поле для сущности и также для ноды. Но теперь при создании или редактировании ноды я не могу передать значение поля оптовой цены в сущность(Rules почему то не позволяет передавать значения в кастомные поля сущностей). Как быть?
тогда программно.
создать hook на node presave
в нем изменять значение поля.
1. сделать commerce_product_load
2. изменить значение поля
3. commerce_product_save
можно было бы и сделать рулесом, только для этого нужно в рулесах создать компонент. Проверять поле ноды в основном Rule, а поле entity в компоненте
Event: Calculating the sell price of a product
Condition: Entity has field Parameter: Entity: [commerce-line-item], Field: commerce_product
у меня почему-то Entity has field без "Parameter"
Это одно и тоже или у меня что-то не включено какой-нибудь модуль например ?
Все разобрался
Супер!!! работает если у меня 4 таких цены делать нужно четыре правила или нужно какое-то мега одно городить?
и еще можно чтобы человек с ролью видел две цены ту которая для всех и свою ?
Давно искал такой faq. Но вопрос. У меня на сайте работает модуль Commerce price table и для него поставлено не ограничено число значении. Как настроить в таком случае?
Решило свою проблему.
В общем я дописал PHP в rules для подсчета суммы в корзине. по другому не получилось.
global $user;
$order = commerce_cart_order_load($user->uid);
if ($order) {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$total = 0;
// Loop through the line items
foreach ($order_wrapper->commerce_line_items as $line_item_wrapper) {
// Розничная цена
//$field_product_price_retail = $line_item_wrapper->commerce_product->field_product_price_retail->value();
// Оптовая цена
$field_product_price_small_scale = $line_item_wrapper->commerce_product->field_product_price_small_scale->value();
$product_total = $line_item_wrapper->quantity->value() * $field_product_price_small_scale['amount'];
$total += $product_total;
}
return $total;
}
Привет, мне нужно сделать такую же задачу как у тебя, ты просто создал Action PHP в рулсах? или это где-то в компонентах ты писал?
Привет.
Я создал собственный action с помощью hook_rules_action_info(), где подсчитал все как мне нужно.
Вызвал the action в рулсах для пересчета цен для commerce line items. Что-то типа shop -> settings -> pricing rules
Да, все удалось!
Поля у меня все разные, отдельные.
У меня ценя для обычных гостей лежит в commerce_price, остальные отдельно.
На счет типа поля не думал, поставил поле цены, но можно действительно и int, разница лишь в том что я могу хранить инфу о валюте с каждой ценой.
«Будут ли нужные мне цены отображаться на страницах товара тоже (если юзер с нужными ролями залогинился) или только в корзине?»
Я через препроцес вроди делал кастомным модулем.
«Для каждого уровня цен пользователю (в зависимости от суммы продаж) нужно будет заводить ещё 4 роли или лучше как-то без зоопарка ролей обойтись?»
Ну тут уж в зависимости от логики, можно например сделать поле в юзер-профайле и закрыть ему доступ на это поле.
«Какие ещё меня ожидают проблемы и подводные кирпичи? ;)»
В общем все прозрачно и работает.
Ах вот, вспомнил эту штуку - експосед фильтры вьювсов. Тебе нужно или ставить 5 фильтров и делать что-то свое для фильтра по цене. У меня никак руки до этого не дойдут, но я хочу найти общее решение и если его нет в контрибе то выложить в паблик.
Согласен c 5n00py с exposed filters может возникнуть проблема
Спасибо за информацию!
Меня что-то беспокоит проблема с тем, что в процессе донастроек развёлся целый зоопарк полей у товара, каждое из которых в итоге тормозит работу всего сайта в целом. Например если я добавлю ещё 5 цен в отдельных полях, то будет ещё 5 join-ов при каждой загрузке товара, а если эти поля типа commerce_price, то ещё и функция обработки вывода будет запускаться на каждом из них.
Поэтому и хочется минимизировать количество полей, сделать например одно поле commerce_price_wholesale типа int (чтобы не запускались обработчики поля price с валютами) с 5 значениями сразу, но боюсь что потом натолкнусь на какие-нибудь проблемы с выводом и другой обработкой...
Есть конечно идея завести для дополнительной информации отдельный entity type, например commerce_product_additional_info, и хранить все редко используемые поля там, но пока ещё не решился на такой серьёзный шаг.
Либо ещё как вариант - хранить всю доп. инфу в массиве data, он через serialize хранится в одном поле в базе, так что кол-во данных в этом массиве не сильно затормозит загрузку объекта.
Вобщем раз всё удалось - буду тоже пробовать, о найденных проблемах и решениях тогда буду отписывать тут, другому народу чай тоже пригодится. И у тебя - как руки дойдут до экспозед - отпиши плз тут тоже.
а как можно получить в рулсах поля товара?
Rules по умолчанию не видят все поля сущностей. Для того чтобы работать с каким либо полем(картинкой, описанием и т.п.) нужно сделать проверку что у товара есть это поле.
Conditions->Entity has field->Выбираешь твое поле.
Так работают Rules.
Вот видео от Randy Fay как работать с ценами в Drupal Commerce используя Rules.
http://vimeo.com/22625018
спасиюо большое! я думаю теперь разберусь!)
я сделал все как в показано в видео, и уже было обрадовался, что вот-вот все выйдет и достигну желаемого результата, но в конце, после выбора созданного мною с помощью workflow компонента нужно выбрать селектор данных и в видео выбирают "line-item:commerce-product", а у меня нет такого...
при создании компонента в workflow был выбран Data Type -> Commerce Product.
пришли экспорт своего rules
Это рулс из правил ценообразования:
{ "rules_addition_to_the_price" : {
"LABEL" : "addition to the price",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "rules", "php", "commerce_line_item", "commerce_product_reference" ],
"ON" : [ "commerce_product_calculate_sell_price" ],
"IF" : [
{ "entity_has_field" : { "entity" : [ "commerce-line-item" ], "field" : "field_creator" } }
],
"DO" : [
{ "commerce_line_item_unit_price_amount" : {
"commerce_line_item" : [ "commerce_line_item" ],
"amount" : {
"select" : "commerce-line-item:commerce-unit-price:amount",
"php" : { "code" : "global $user;\r\n$discount = 1;\r\nif(in_array(\u0027Discount 5%\u0027, $user-\u003Eroles)){\r\n\t$discount = 0.95;\r\n}\r\nelseif(in_array(\u0027Discount 10%\u0027, $user-\u003Eroles)){\r\n\t$discount = 0.90;\r\n}\r\nelseif(in_array(\u0027Discount 15%\u0027, $user-\u003Eroles)){\r\n\t$discount = 0.85;\r\n}\r\nelseif(in_array(\u0027Discount 20%\u0027, $user-\u003Eroles)){\r\n\t$discount = 0.8;\r\n}\r\n\r\n$value=$value * $discount;\r\nreturn $value;" }
},
"component_name" : "base_price",
"round_mode" : "1"
}
}
]
}
}
А это компонент, который я создал при помощи workflow и добавляю в условие:
{ "rules_bosch_discount" : {
"LABEL" : "BOSCH discount",
"PLUGIN" : "and",
"REQUIRES" : [ "rules" ],
"USES VARIABLES" : { "product" : { "label" : "Product", "type" : "commerce_product" } },
"AND" : [
{ "entity_has_field" : { "entity" : [ "product" ], "field" : "field_creator" } },
{ "NOT data_is_empty" : { "data" : [ "product:field-creator" ] } },
{ "NOT data_is_empty" : { "data" : [ "product:field-creator:tid" ] } },
{ "data_is" : { "data" : [ "product:field-creator:tid" ], "value" : "42" } }
]
}
}
писать php код в relus не есть хорошо ведь это хранится в базе.
ты не сделал condition "Entity has field Field: commerce_product в твоем компоненте. по-этому его и не видно.
В общем можешь написать в личку если не получится чтобы тут не флудить. Потом решение напишем сюда
А можно в модуле как-то перехватить событие расчета цены и посчитать всё что надо в php-функции?
Мне кажется это будет работать в разы быстрее и тратить меньше памяти, чем куча правил и проверок в Rules.
можно, тут нужно работать с триггерами и событиями. я такого еще не делал, для этого нужно немного поизучать модуль cpmmerce_price.
Если тебе нужно выполнить пхп в рулсах - это допускается. Там же есть пхп поле. Категорически никто не запрещает там чтото писать. Можешь написать функцию расчета цены в своем модуле а в рулсах просто вызвать эту ф-ю проверив if function exists.
Подскажте плз как в Rules можно получить кастомное поле пользователя?
У меня у пользователей будет 6 типов:
Розничный
Скидка 5%
Скидка 10%
Мелкий опт (цена из поля 2)
Крупный пт (цена из поля 3)
Партнер (цена из поля 4)
Соотвественно хотелось бы для каждого отображать свою цену.
Для каждого делать отдельную роль как-то не хочется, т.к. таблица настройки ролей станет огромных размеров, да и на производительность это не очень хорошо повлияет скорее всего, поэтому решил просто сделать у пользователя поле selectlist с id-значение.
Но сейчас стоит задача выяснить значение этого поля и относительно него пересчитать отображаемую цену.
Как это можно сделать через Rules?
Или может лучше сделать через hook прямо в php? Правда не нашёл пока подходящего хука, отвечающего за расчет цены для пользователя.
можно в рулсах
1. нужно сделать проверку что у поле "account" есть это поле
2. проверить значение поля. Data comparison
3. profit
Товарищи, я смотрю вы уже шарите в этом
Помогите советом пожалуйста:
У меня следующая задача. Имеется продукт, в котором есть стандартное поле PRICE и есть моё поле PRICE2
в одном для примера 100руб в другом 120руб
Покупателю выводится везде цифра поля PRICE2, и заказ считается по полю PRICE2 (т.е. с учётом от кол-ва товара заказанного например)
нужно сделать так, чтобы при оформлении заказа допустим 2 штук одного продукта, сумма посчиталась для от обоих полей, т.е. покупателю на чекауте вывелось по второму полю,
т.е. ЗАКАЗАН ТОВАР ЦЕНОЙ В 120РУБ В КОЛ-ВЕ 2 ШТУК. ИТОГО С ВАС 240РУБ
а у продавца во вьюхе было эта итоговая сумма как от первого поля (стандартного) так и от второго. Т.е. 200 и 240руб
как вариант, сделать кастомный код в модуле.
нужно загрузить $line_item товара, а в нем есть поле quantity к-во товаров в корзине.
ну а дальше нужно просто умножить твое поле на к-во и вывести гдето результат в ноде.
во views можно добавить свое поле через views api, или если нужно быстро то ставь модуль views php и все считаешь в поле(лучше написать свою ф-ю и ее вызывать)
Я во вьюхе сделал небольшой дурдом, просто выводил поле ЦЕНА 2 и рядом кол-во товара, за excludе-ил их, а потом далече добавил поле Math expression, помножил в итоге - т.о. правда пропали понятия как RUB,но дописал их как СУФФИКСЫ, в общем, факт в том - что вроде как бы выводится (через пень как то ) но выводится
Спасибо!
Ребят, помогите найти решение,я тут голову уже сломал.
есть база товаров(около 8000 артиклей) и покупателей (около 3000 человек).
настроены импорты через Feeds. для незарегистрированного пользователя показывается "Стандартная цена". Это все работает так сказать из коробки.
Проблема следущая:
каждый покупатель может иметь скидку на тот или иной товар. причем для скидки нет никаких правил (цена назначается с потолка, "чъёрт её побьери")
все это выглядит так:
Покупатель 1
товар 1 = 100 руб.
товар 2 = 30 руб.
.......
товар 8000 = 37,4 руб.
Покупатель 2
товар 1 = 110 руб.
товар 2 = 15 руб.
.......
товар 8000 = 40,3 руб.
и так далее...
я так думаю что через Rules сделать это неимоверно сложно.
есть ли какое нибудь решение?
Предлагаю такой вариант:
Можно через Rules. Но прийдется и написать кастомный функционал.
Если нужно для каждого клиента задавать скидку на каждый товар, то можно так:
1) Создать кастомную таблицу с полями: uid, product_id, price. И сделать старицу, где визуально можно будет ее заполнять. Можно отдельно, можно привязать таблицу в вьюхам, можно сделать новую вкладку на странице товара и т.п. (это уже не входит в данную тему)
2) Создать новый action в Rules кастомно, который принимает uid и product_id, а выдает цену с таблицы.
3) Использовать кастомный action в Pricing Rules
Спасибо за предложенный вариант!
а можно поподробней с этого момента:
Я бы не стал выдумавать такой велосипет с потенциальным нарзмером таблицы в 24.000.000 записей...
Заполнять ее вручную не очень интересно...
Должна быть где-то логика ....
Если нет то менеджер должен в корзине вручную вытсавлять sell-price. После статуса checkout complete, ценообразующие правила не срабатыват, так что цена фиксируеться.
Но это ИМХО.
все данные берутся из уже существующих таблиц. настроен импорт через feed. логики присвоения цены нет. встал менеджер сегодня с левой ноги, то первый позвонивший получит скидку на артикль 3 рубля, второй - 2 рубля, третий дозвонившийся получит 1 рубль. если позвонила девушка, скидка 10 рублей, если ее голос приятный - еще 5 рублей и тд и тп...
да это не вопрос. таблица допустим есть. как
Вот как можно создать собственный action:
http://internetdevels.ru/blog/creating-custom-events-and-actions-using-r...
http://www.joetsuihk.com/node/349
сори, сейчас не могу развернутю ответить
Я согласен с 5n00py, если можно отыскать логику, или дать возможность менеджеру менять цены, то все станет проще на много
Ребят, спасибо за советы, я создал свой экшн, цена в корзине меняется на ту что нужно (подставляется из своей таблицы)...
но на странице товара так и стоит старая цена
экпорт выглядит так:
{ "rules_set_customer_price" : {
"LABEL" : "Set Customer Price",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "customer_price", "commerce_line_item", "commerce_product_reference" ],
"ON" : [ "commerce_product_calculate_sell_price" ],
"DO" : [
{ "customer_price_get_price" : {
"USING" : { "commerce_line_item" : [ "commerce_line_item" ] },
"PROVIDE" : { "customer_price" : { "customer_price" : "Customer price" } }
}
},
{ "commerce_line_item_unit_price_amount" : {
"commerce_line_item" : [ "commerce_line_item" ],
"amount" : [ "customer-price:amount" ],
"component_name" : "base_price",
"round_mode" : "1"
}
}
]
}
}
как можно заменить цену на странице товара?
Все настроил, работает, но теперь ндс неправильно считается ((
Не получается это сделать - нет маркера с моим полем...
Любые идеи...
Ребят, подскажите: делаю как здесь: http://jamestombs.co.uk/2012-09-14/drupal-commerce-different-prices-diff... или как у вас в посте, но на последнем шаге не вижу селектора своего нового поля!
разобрался: нужно обязательно добавлять проверку на тип товара
Теперь почему то в общей сумме заказа 0 - как победить?
разобрался
спасибо помогло,отпишусь тут что бы попало в трекер и не потерялось