Допиливаем заказ без регистрации в VirtueMart 1.1.9. Выбор варианта доставки и оплаты.

Начало положено тут, но, как выяснилось, этого оказалось недостаточно. Письмо-то приходит, а вот как запилить выбор доставки и оплаты в Virtuemart при заказе без регистрации — загадка. Ничего, сейчас исправим…

Итак, судя по всему, хак с джумлафорума у нас уже есть, осталось самая малость — прикрутить к нему всякие выборы.

Открываем файл checkout.without_register_form.php и начинаем. По ходу дела будут пояснения.

Туда, где собирается форма, втыкаем этот код, я воткнул между выпадающим списком «Отправить вам копию?» и комментарием к заказу. Важно, чтобы код был в пределах тега <form>.

<?php

	$theme = new $GLOBALS['VM_THEMECLASS']();
	echo $theme->fetch( 'checkout/get_shipping_method.tpl.php'); //методы доставки
	echo $theme->fetch( 'checkout/get_payment_method.tpl.php'); //методы оплаты

?>

В первой строке мы делаем доступным $theme, чтобы нормально подключить шаблоны с методами доставки и оплаты. Если первую строчку упустить — $theme будет NULL при пустой форме (или если пользователь неправильно заполнит форму).

Что у нас произойдет. При загрузке формы, тут же подгрузятся шаблоны с доступными вариантами доставки и оплаты. Элементы, которые появятся — будут передаваться методом POST (что логично), поэтому возьмем и используем их, но только тогда, когда форма заполнена верно. Для этого в районе комментария /* sets _shipping */ (я дописал после него) пишем этот код:

	$strPOSTShippingMethod = $_POST['shipping_rate_id'];
	$arrShipping_method = explode ('%7C', $strPOSTShippingMethod);
	$order_shipping = round( $arrShipping_method[3], 2 );

Что тут происходит. В первой строке мы берем из POST содержимое (value) поля radio с именем shipping_rate_id. Здесь содержится строка типа такой:

standard_shipping%7C%D0%9A%D1%83%D1%80%D1%8C%D0%B5%D1%80%D0%BE%D0%BC+%D0%BF%D0%BE+%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B5%7C%D0%92+%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B0%D1%85+%D0%9C%D0%9A%D0%90%D0%94%7C300.00%7C1

Затем мы делаем из этой строки массив, разделяя элементы с помощью ‘%7C’ — это символ ‘|’. Для тех, кто пока в танке — так надо, дальше будет понятно, почему именно так. Ну, к слову, декодированная строка будет такая: standard_shipping|Курьером по Москве|В пределах МКАД|300.00|1

Теперь у нас есть массив, состоящий, вроде бы, из абракадабры, но нам отсюда надо только тариф доставки, поэтому декодировать мы не будем сейчас — об этом дальше. Конечно, если нужно получить внятные красивые названия вариантов доставки, можно декодировать и применить. Третью строку поясню подробнее — $order_shipping будет использоваться чуть ниже для вычисления итоговой суммы, a round округлит значение до целого. Значение в данном случае — это $arrShipping_method[3] (это четвертый по счету элемент массива, мы же помним, что элементы в массиве начинаются с нуля, да?).

Так, цена у нас есть, строка с вариантом доставки у нас есть, теперь можно все это применить в наших корыстных целях.

Кстати, вычисление итоговой суммы происходит как раз чуть-чуть ниже, тут:

// Вычисление итоговой суммы превращается в вычитание из предположительной суммы скидки по купону
$d['order_total'] = $order_total = 	$tmp_subtotal 
					/*+ $order_tax */
					+ $order_shipping
					/*+ $order_shipping_tax*/
					- $coupon_discount;
					/*- $payment_discount;*/

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

Вот этот момент, где добавляется запись в базу, которая потом показывается в админке:

	/* Добавляем в базу основную информацию о заказе */
	$q  = "INSERT INTO #__{vm}_orders ";
	$q .= "(user_id, vendor_id, order_number, user_info_id, ship_method_id, order_total, order_subtotal, order_tax, order_shipping, order_shipping_tax, order_discount, coupon_discount, order_currency, order_status, cdate, mdate, customer_note, ip_address) ";
	$q .= "VALUES ( 0, ".$ps_vendor_id.", '".$order_number."', '".$d["ship_to_info_id"]."', '', '".$order_total."', '".$order_subtotal."', '".$order_tax."', '".$order_shipping."', '".$order_shipping_tax."', '".$payment_discount."', '".$coupon_discount."', '".$_SESSION['vendor_currency']."', 'P', '".$timestamp."', '".$timestamp."', '".addslashes(htmlspecialchars(strip_tags($checkout['comment'])))."', '".$ip."');";

Здесь явно не хватает указания на то, что надо бы добавить информацию о выбранном варианте доставки. Вот тут-то мы и вылазим из танка (про танк см. выше) и добавляем раскодированную строку из POST вот так: urldecode($strPOSTShippingMethod). А именно, вставляем это в запрос (здесь это третья строчка):

	/* Добавляем в базу основную информацию о заказе */
	$q  = "INSERT INTO #__{vm}_orders ";
	$q .= "(user_id, vendor_id, order_number, user_info_id, ship_method_id, order_total, order_subtotal, order_tax, order_shipping, order_shipping_tax, order_discount, coupon_discount, order_currency, order_status, cdate, mdate, customer_note, ip_address) ";
	$q .= "VALUES ( 0, ".$ps_vendor_id.", '".$order_number."', '".$d["ship_to_info_id"]."', '".urldecode($strPOSTShippingMethod)."', '".$order_total."', '".$order_subtotal."', '".$order_tax."', '".$order_shipping."', '".$order_shipping_tax."', '".$payment_discount."', '".$coupon_discount."', '".$_SESSION['vendor_currency']."', 'P', '".$timestamp."', '".$timestamp."', '".addslashes(htmlspecialchars(strip_tags($checkout['comment'])))."', '".$ip."');";

Так. Менеджер у нас уже начал пританцовывать от счастья, клиент пока получает письмо, где не указано, за что он заплатил 300 рублей сверху. Меня бы это огорчило. Исправляем.

Ниже (в переменной $message) формируется писуля кленту. Поэтому ищем, где у нас выводится Итого и меняем его с этого:

	$message .= "--------------------------------------------------\n";
	$message .= "Итого: ".$CURRENCY_DISPLAY->getFullValue($order_total)."\n";
	$message .= "--------------------------------------------------\n";

на это:

	$message .= "--------------------------------------------------\n";
	$message .= "Доставка: $order_shipping р.\n";
	$message .= "--------------------------------------------------\n";
	$message .= "Итого: ".$CURRENCY_DISPLAY->getFullValue($order_total)."\n";
	$message .= "--------------------------------------------------\n";

Символа валюты у нас не передается (да оно нам тут особо-то и не нужно), потому — добавляем руками.

Ну, на этом, вроде, все… Вопросы? Предложения?

0

Допиливаем заказ без регистрации в VirtueMart 1.1.9. Выбор варианта доставки и оплаты.: 14 комментариев

  1. Виктор

    Здравствуйте. Меня интересует такой вопрос… Вы можете сделать страницу покупки в VirtueMart под заказ? Оплатить могу через WebMoney или другим удобным для Вас способом) Заранее спасибо! Контакты: macroman@bigmir.net

  2. Евгений

    обновил свой мар 1.1.8 до 2.0 и выяснилось что в новом марте нет возможности в админке редактировать заказ (удалить товар из заказа, добавить новый, изменить количество) — мне это очень нужно! сможете добавить в новый март возможность редактирования? сколько это будет стоить?

    1. merinovkv

      Сам в шоке, жду пофиксенного релиза от разработчиков. Пока не вижу мысла переходить плотно на 2.0 и, тем более, писать под него такие глобальные хаки

  3. anton

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

  4. Юрий

    Здравствуйте. Возможно ли к Вам обратиться за помощью? Никак не удается прикрутить выбор доставки и оплаты за доставку (хотя предполагается всего один вид). Оплата через Вебмани
    Спасибо

      1. Юрий

        Нет, ошибок нет. Я вообще полный чайник в PHP и то, что Вы рекомендуете сделать в этом уроке даже не пытался применить. Даже не уверен, что это мне подходит.
        Просто, я пытаюсь назначить фиксированные расценки в модуль
        Shipping based on order totals. Fixed shipping costs based on values entered in configuration, но на общей страничке заказа оплата за доставку никак не отображается (пишет, что стоимость доставки — 0). Да и в процессе заказа покупателю не предлагается выбрать вариант доставки…

        1. merinovkv Автор записи

          А модуль доставки включен?
          Посмотрите в Настройки — Настройки — Доставка, там включаются модули доставки.
          Включите эти:
          «Фиксированный тариф, на основе введенных данных.»
          «Стандартный модуль доставки с индивидуальными данными о расценках. РЕКОМЕНДУЕТСЯ !»
          А настраиваются они в:
          Магазин — shipvalue (Настроить вариант доставки)
          и
          Магазин — Standard Shipping Module (Настроить вариант доставки)
          В разделе Доставка можно создать тарифы и варианты доставки.
          Поклацайте там, скорее всего, этого будет более чем достаточно. Если что — пишите, будем думать.

          1. Юрий

            Не хочет! Все подключено, но никак….

          2. merinovkv Автор записи

            Скиньте задачу через форму справа, посмотрим, что можно сделать.

  5. Тимур

    Здравствуйте!
    А как быть, если в качестве способа оплаты используется способ «Пластиковой картой», или «Webmoney».
    При заказе авторизованного пользователя, после отправки заказа, происходит переход на систему оплаты.
    При указанных доработках, переход на страницу оплаты не происходит, а просто отправляется заказ.

    Спасибо!

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