Drupal Commerce Shipping — самовывоз

Обновлено, ноябрь 2013: Заметка не особо актуальна с момента появления 9 месяцев назад модуля commerce pickup, реализующего, судя по описанию, необходимую функциональность.

За последние 3-4 недели успел поставить Drupal 7 и Drupal Commerce, поковырять его, отложить в сторону, поставить Ubercart 2 в лице адской сборки Openstore, поковыряться… и снова вернуться к Drupal Commerce. Возможно, это не последняя итерация.

Если коротко — Ubercart хорош для задач, которые он выполняет «из коробки». Если эта коробка называется Openstore, то многим больше ничего не потребуется. Я с неделю занимался обратным процессом — выбрасывал из сборки ненужные мне модули. Закончилось тем, что оставшееся не выглядело сколько-нибудь лучше Drupal Commerce (для моей задачи).

Drupal Commerce — гол, как сокол. Я устанавливал сборку (профиль) Commerce Kickstart. Доставки нет, нужен отдельный модуль. Почти для всего нужен отдельный модуль, которого или вообще не существует, или он находится на dev, alpha, beta стадиях (вялой) разработки.

Ладно, перестаю ныть, начинаю похваляться делиться информацией. Задача была простая — добавить в Drupal Commerce два способа доставки — курьером (за фиксированную сумму) и «самовывоз», который никакая не доставка, но выбор такой клиенту дать нужно. Пока пытаюсь сделать все правильно, используя модуль Commerce Shipping. Половину дела сделал легко — курьерскую доставку можно реализовать на основе модуля Flat Rate, простого и понятного — фиксированная цена доставки. Дальше начались трудности.

Модуль Commerce Shipping добавляет новый профиль (user profile) для пользователя и соответствующую панель (pane) на страницу расчета (checkout). Процедура оформления покупки в Drupal Commerce многостраничная, панели можно передвигать между страницами произвольно. По-умолчанию панель с адресом доставки (shipping profile) помещается на самую первую страницу. Для многих это логично — от адреса доставки могут зависеть доступные способы доставки или способы оплаты. У меня ситуация обратная — город известен заранее, стоимость доставки тоже. Остается реализовать «самовывоз», то есть отключить панель адреса доставки (shipping profile) в случае выбора соответствующего способа доставки.

1. Помещаем панель shipping на первой странице (checkout), панель shipping profile переносим на вторую (review). Так мы принуждаем клиента выбрать способ доставки и меешм шанс не спрашивать адрес в случае самовывоза.

2. Создаем новый модуль (это за пределами заметки) и добавляем в него свой хук для переопределения панелей модуля commerce checkout.

/*
 * Hook hook_commerce_checkout_pane_info_alter($checkout_pane)
 */
function mymodule_commerce_checkout_pane_info_alter(&$checkout_pane) {
	global $user;
	// $checkout_pane на самом деле содержит массив из всех панелей...
	foreach($checkout_pane as $pane_name => &$pane_data) {
		// …нам нужна только она из них — панель с профилем доствки
		if($pane_name == 'customer_profile_shipping' && $pane_data['enabled']) {
			// загружаем текущий заказ
		    $order = commerce_cart_order_load($user->uid);
		    // $order->data был найден с помощью dsm()
		    // в нем не было ничего за исключением 'shipping_method' со строкой
		    // rules_pick_up это ID склонированного способа доставки flat rate
			if($order->data['shipping_method'] == 'flat_rate|rules_pick_up') {
				// панель была изначально включена в админке, отключаем ее
				$pane_data['enabled'] = 0;
			}
		}
	}
}

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

У меня нет никакой уверенности, что это правильный и эффективный способ выполнить задуманное. Глядя на Drupal Commerce вообще, я был уверен, что найду способ сделать подобное с помощью Правил (Rules), но готовых «действий» не нашлось (панели не контролируются правилами), а приделать такое сбоку мне оказалось не по силам.

Если кто-то знает более изящные способы справиться с задачей — намекните. Проблема с Commerce в том и состоит, что документации не очень много, примеры в основном примитивные, знающие люди неохотно делятся информацией (заняты они), а основной шум создают недоучки, вроде меня.

Drupal Commerce Shipping — самовывоз: 9 комментариев

  1. спасибо за инфу ,,,,
    чем все закончилось в итоге, есть на что посмотреть?

  2. А вы не подскажите, как осуществить этот шаг — «$order->data был найден с помощью dsm()»

  3. Спасибо за ответ. Но с функцией dsm я более менее знаком, мне не понятно куда ее пихать =(
    куда бы я не вставил dsm($order); выдает — неизвестная переменная $order

    У вас в итоге реализация описанного получилась? Делал все как у вас поэтапно, что то не пашет =(
    подразумеваю, что могут меняться вот эти моменты —
    $order->data[‘shipping_method’] или
    $pane_name == ‘customer_profile_shipping’

  4. Я не удивлюсь, если там за 2 года что-то значительно изменилось. Сильно помочь не могу, не помню уже ничего толком.

    В старом коде нашел такое:

    /*
    * Hook hook_commerce_checkout_pane_info_alter($checkout_pane)
    */
    function commerce_shipping_tweaks_commerce_checkout_pane_info_alter(&$checkout_pane) {
    global $user;
    foreach($checkout_pane as $pane_name => &$pane_data) {
    if($pane_name == 'customer_profile_shipping' && $pane_data['enabled']) {
    $order = commerce_cart_order_load($user->uid);
    if($order && $order->data['shipping_method'] == 'flat_rate|rules_pick_up') {
    // $checkout_pane['customer_profile_shipping']['enabled'] = 0;
    $pane_data['enabled'] = 0; //enable shipping profile panel
    dsm($order->data);
    dsm($checkout_pane);
    }
    }
    }
    }

  5. блин наверно модуль по какой то причине не работает. ибо все выше вписанное
    dsm($order->data);
    dsm($checkout_pane);
    ни к каким действиям не приводит…. Если вам не сложно, может быть, вы могли бы выслать ваш модуль? Я бы протестил что у моего модуля не работает.

  6. Спасибо, добавил в запись. В 2011 году этого модуля не было. Да и в 2012 тоже, насколько я понимаю.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *