/ Плагины / Добавление полей при оформлении заказа

Добавление полей при оформлении заказа

HIT

27.01.2017

20580

14

Добавляем поля для шаблона Оформление заказа Woocommerce. Стандартные поля Woocommerce делятся на 3 группы:

  1. поля оплаты (billing)
  2. поля доставки (shipping)
  3. поля аккаунта (account)

Тезисно о важных моментах добавления поля:

Добавляем текстовое поле в стандартные группы WC

// Добавляем поле в группу Детали доставки

add_filter( 'woocommerce_checkout_fields' , 'custom_checkout_fields' );

function custom_checkout_fields( $fields ) {
	$fields['shipping']['shipping_apartment'] = array(
		'type' => 'text', 
		'label' => __('Квартира', 'woocommerce'),
		'placeholder' => _x('Квартира', 'placeholder', 'woocommerce'),
		'required' => false,
		'class' => array('form-row-wide'),
		'clear' => true
	);

	return $fields;
}

Далее создаем функцию сохранения значения метаполя. При необходимости, можно сделать функцию единой для нескольких полей.

// Сохраняем метаданные заказа со значением поля
add_action( 'woocommerce_checkout_update_order_meta', 'shipping_apartment_update_order_meta' );

function shipping_apartment_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['shipping_apartment'] ) ) {
        update_post_meta( $order_id, 'shipping_apartment', sanitize_text_field( $_POST['shipping_apartment'] ) );
    }
}

Чтобы поле было обязательным, меняем параметр required на true и добавляем функцию верификации

// Проверка поля при отправке заказа (обязательное)

add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');

function my_custom_checkout_field_process() {
    // Проверяем, заполнено ли поле, если же нет, добавляем ошибку.
    if ( ! $_POST['shipping_apartment'] )
        wc_add_notice( __( 'Пожалуйста, введите требуемый текст в наше новое замечательное поле.' ), 'error' );
}

Для чего-нибудь возможно пригодится в будущем: функция полного отключения валидации полей

add_filter('woocommerce_after_checkout_validation', 'additional_validation');
function additional_validation($fields) {
	wc_clear_notices();
}

Еще один пример, добавление поля Отчество (в группу полей Плательщик):

add_filter('woocommerce_checkout_fields', 'custom_woocommerce_billing_fields');
function custom_woocommerce_billing_fields( $fields ) {
    $fields['billing']['billing_patronymic'] = array(
        'label'       => __('Отчество', 'woocommerce'), // Add custom field label
        'placeholder' => __('Отчество', 'woocommerce'), // Add custom field placeholder
        'required'    => true, // if field is required or not
        'clear'       => false, // add clear or not
        'type'        => 'text', // add field type
        'class'       => array('billing_patronymic'),   // add class name
        'priority'    => 10, // Priority sorting option
    );

    return $fields;
}

Как сохранять поле описано выше.

Места вывода полей

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

woocommerce_before_checkout_billing_form — перед полями Детали оплаты

woocommerce_after_checkout_billing_form — после полей Детали оплаты

woocommerce_checkout_fields — после всех полей, но перед комментарием к заказу

Значения полей в админке и в шаблоне письма

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

Выводим значения полей на странице редактирования заказа (в админке). Если у нас несколько произвольных полей можно их все вносить в данную функцию.

add_action( 'woocommerce_admin_order_data_after_shipping_address', 'custom_field_display_admin_order_meta', 10, 1 );

function custom_field_display_admin_order_meta($order){
    echo '<p><strong>'.__('Квартира').':</strong> ' . get_post_meta( $order->id, 'shipping_apartment', true ) . '</p>';
    echo '<p><strong>'.__('Период доставки').':</strong> ' . get_post_meta( $order->id, 'shipping_date', true ) . '</p>';
}

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

// Выводим значения полей в шаблоне письма с заказом
add_filter('woocommerce_email_order_meta_keys', 'email_checkout_field_order_meta_keys');

function email_checkout_field_order_meta_keys( $keys ) {

$keys['Квартира'] = 'shipping_apartment';
$keys['Период доставки'] = 'shipping_date';
$keys['Разгрузка'] = 'unloading';

return $keys;
}

Вывод поля Отчество в конце колонки Плательщик

add_action( 'woocommerce_admin_order_data_after_billing_address', 'custom_field_display_admin_order_meta', 10, 1 );
function custom_field_display_admin_order_meta($order){
    echo '<p><strong>'.__('Отчество').':</strong> ' . get_user_meta( $order->user_id, 'billing_patronymic', true ) . '</p>';
}

Добавляем другие типы полей

Радио кнопка

// Добавление поля Покупатель
add_action( 'woocommerce_before_checkout_billing_form', 'organisation_checkout_field' );

function organisation_checkout_field( $checkout ) {

    echo '<div id="organisation_checkout_field">';

    woocommerce_form_field( 'organisation', array(
        'type'          => 'radio',
        'class'         => array('form-row-wide'),
        'label'         =>  '',
	    'options' => array(
  							'Частное лицо' => 'Частное лицо',
  							'Организация' => 'Организация'
							)
	  
        ), $checkout->get_value( 'organisation' ));

    echo '</div>';
}

Вывести поле

<?php echo get_post_meta($order->id, 'organisation', true); ?>

Сделать один из вариантов изначально активным

$(function() {
    var $radios = $('input:radio[name=organisation]');
    if($radios.is(':checked') === false) {
        $radios.filter('[value="Частное лицо"]').prop('checked', true);
    }
});

Ещё один пример. Добавление поля Выбор даты доставки

// Поля выбора даты доставки
add_filter( 'woocommerce_checkout_fields' , 'shipping_date_checkout_fields' );

function shipping_date_checkout_fields( $fields ) {
	$today = date("d.m.Y");

	$d = strtotime("+1 day");
	$tomorrow = date("d.m.Y", $d); 

	$dd = strtotime("+2 day");
	$aftertomorrow = date("d.m.Y", $dd);

	$ddd = strtotime("+3 day");
	$afteraftertomorrow = date("d.m.Y", $ddd);  	

	$fields['shipping']['shipping_date'] = array(
		'type' => 'radio',   
		'required' => false,
		'class' => array('form-row-wide'),
		'clear' => true,
		'label' => 'Период доставки: ',
		'options' => array(
			$today => 'Сегодня',
			$tomorrow => 'Завтра',
			$aftertomorrow => $aftertomorrow,
			$afteraftertomorrow => $afteraftertomorrow
		)

	);

	return $fields;
}

Можно сделать упрощенное включение по-умолчанию (1 — второй элемент #shipping_date_field input, отсчет начинается с 0)

$('#shipping_date_field input').eq( 1 ).attr('checked',true);

Checkbox

// Добавляем поле Разгрузка доставки в группу Детали доставки
add_filter( 'woocommerce_checkout_fields' , 'unloading_checkout_fields' );

function unloading_checkout_fields( $fields ) { 	
	
     $fields['shipping']['unloading'] = array(
	'type'        => 'checkbox',   
        'required'    => false,
        'class'       => array('form-row-wide'),
	'clear'       => true,
	'label'       => 'Разгрузка'

     );

     return $fields;
}

Значение поля будет либо 0 — не отмечено, либо 1 — отмечено. Выводим значение checkbox проверкой

<?php if (get_post_meta($order->id, 'unloading', true)): ?>Разгрузка<?php endif; ?>

и также при добавлении значения checkbox в админку можно вывод также сделать в виде условия

if(get_post_meta( $order->id, 'unloading', true )) { echo '<p><strong>'.__('Нужна разгрузка').'</strong></p>'; }

Добавляем поле НЕ в стандартные группы WC

// Добавление своего поля для страницы Оформление товара

add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );

function my_custom_checkout_field( $checkout ) {

	echo '<div id="my_custom_checkout_field"><h2>' . __('Мое поле') . '</h2>';

	woocommerce_form_field( 'my_field_name', array(
		'type' => 'radio',
		'class' => array('my-field-class form-row-wide'),
		'label' => 'organization-form',
		'placeholder' => __('Введите здесь требуемый текст'),
		'options' => array(
			'option_1' => 'urface',
			'option_2' => 'fizface'
		)
	), $checkout->get_value( 'my_field_name' ));

	echo '</div>';

}

Включение полей в шаблон письма WC

Пользовательские поля или любую другую информацию можно добавить в шаблон письма в 3 области:

Примеры добавления полей:

// Добавить поля Доставка
function cloudways_show_email_order_meta( $order, $sent_to_admin, $plain_text ) {
    $shipping_safe = get_post_meta( $order->id, 'shipping_safe', true );
    if( $shipping_safe ){
        echo '<p style="margin: 0 0 16px;"><strong>Страхование груза:</strong> '.$shipping_safe.'</p>';
    }
	
	$shipping_pack = get_post_meta( $order->id, 'shipping_pack', true );
    if( $shipping_pack ){
        echo '<p style="margin: 0 0 16px;"><strong>Упаковка груза:</strong> '.$shipping_pack.'</p>';
    }

	//if ( $sent_to_admin ) {} // Отправлять только в шаблонах администратору

}
add_action('woocommerce_email_order_meta', 'cloudways_show_email_order_meta', 20, 3 );



// Добавить поле Отчество ниже информации о плательщике
function cloudways_show_email_order_meta_customer( $order, $sent_to_admin, $plain_text ) {
    $patronymic = get_post_meta( $order->id, 'billing_patronymic', true );
    if( $patronymic ){
        if ( $sent_to_admin ) { echo 'Отчество: ' . $patronymic; }
    }

}
add_action('woocommerce_email_customer_details', 'cloudways_show_email_order_meta_customer', 30, 3 );

if ( $sent_to_admin ) {} — то что в этом условии будет выводится только в шаблонах для администратора.

Все же для того чтобы добавить отчество между именем и фамилией пришлось изменять локальный шаблон woocommerce/email/email-addresses.php

<?php //echo wp_kses_post( $address ? $address : esc_html__( 'N/A', 'woocommerce' ) ); ?>

<?php echo wp_kses_post( $order->get_billing_first_name() );
$patronymic = get_post_meta( $order->id, 'billing_patronymic', true );
if( $patronymic ){ echo ' '.$patronymic; } 
echo ' '.wp_kses_post( $order->get_billing_last_name() ); ?>

Добавление необязательного checkbox

// Добавляем поле Детали оплаты
add_filter( 'woocommerce_checkout_fields' , 'billing_safe_checkout_fields' );

function billing_safe_checkout_fields( $fields ) {
	
    $fields['billing']['billing_whatsapp'] = array(
		'type'          => 'checkbox',   
		'required'    => false,
		'class'       => array('form-row-wide'),
		'clear'       => true,
		'label'       => 'Сообщить о заказе на whatsapp',
		'options' => array(
			'1' => 'whatsapp',
		)
     );

     return $fields;
}



// Сохраняем метаданные заказа со значениями полей
add_action( 'woocommerce_checkout_update_order_meta', 'custom_field_checkout_update_order_meta' );
function custom_field_checkout_update_order_meta( $order_id ) {

	if ( ! empty( $_POST['billing_whatsapp'] ) ) { 
		update_post_meta( $order_id, 'billing_whatsapp', 'yes' );
	}

}


// Добавляем полей в админку
add_action( 'woocommerce_admin_order_data_after_billing_address', 'custom_field_display_admin_order_meta', 10, 1 );
function custom_field_display_admin_order_meta($order){
	
	if(get_post_meta( $order->get_id(), 'billing_whatsapp', true )) { 
	echo '<p><strong>Отправить заказ на Whatsapp</strong></p>';
	}

}


// Вывод полей на странице заказа
add_action( 'woocommerce_order_details_after_order_table', 'custom_field_display_order_page', 10, 1 );
function custom_field_display_order_page($order){
	
	if(get_post_meta( $order->get_id(), 'billing_whatsapp', true )) { 
		echo '<p><strong>Отправить заказ на Whatsapp</strong></p><br>';
	}	

}



// Добавить поля в шаблон письма
function cloudways_show_email_order_meta( $order, $sent_to_admin, $plain_text ) {
    if(get_post_meta( $order->get_id(), 'billing_whatsapp', true )) { 
        echo '<p style="margin: 0 0 16px;"><strong>Отправить заказ на Whatsapp</strong></p>';
    }

}
add_action('woocommerce_email_order_meta', 'cloudways_show_email_order_meta', 20, 3 );

Поле Зарегистрирован ли пользователь

Если прямо из письма о заказе нужно понимать зарегистрирован ли клиент.

Сохраняем при формировании заказа его статус:

add_action( 'woocommerce_checkout_update_order_meta', 'custom_field_checkout_update_order_meta' );
function custom_field_checkout_update_order_meta( $order_id ) {
	
if ( !is_user_logged_in() ) { update_post_meta( $order_id, 'login', 'no' );}
	
}

Вставляем в письмо администратору данный статус при проверке сохраненного поля:

add_action( 'woocommerce_email_after_order_table', 'wc_add_customer_status_to_admin_emails', 15, 2 );
function wc_add_customer_status_to_admin_emails( $order, $is_admin_email ) {
	if ( $is_admin_email ) {
		$order_id = $order->get_ID();
		if ($login = get_post_meta( $order_id, 'login', true )) {
			echo '<p><strong>Статус пользователя:</strong> Не зарегистрирован</p>';
		} else {
			echo '<p><strong>Статус пользователя:</strong> Зарегистрирован</p>';
		}
	}
}

Еще один пример вывода информации, выведем таблицу заказанных позиций которая будет содержать код 1С и количество:

// Добавление в шаблон письма администратору инфу о статусе пользователя
add_action( 'woocommerce_email_after_order_table', 'wc_add_customer_status_to_admin_emails', 15, 2 );
function wc_add_customer_status_to_admin_emails( $order, $is_admin_email ) {
	if ( $is_admin_email ) {
	
		// Выводим таблицу с кодом 1С и количеством
		echo '<table style="margin-bottom: 20px; width: 100%;">';
		foreach ( $order->get_items() as $item_id => $item ) {
			$cod_1s = get_post_meta( $item->get_product_id(), 'cod_1s', true );
			echo '<tr>';
			echo '<td style="border: 1px solid #e5e5e5;">'.$cod_1s.'</td>';
			echo '<td style="border: 1px solid #e5e5e5;">'.$item->get_quantity().'</td>';
			echo '</tr>';
		}
		echo '</table>';
		
	}
}

Результаты:

Возможные запросы к заказу

// Get Order ID and Key
$order->get_id();
$order->get_order_key();
 
// Get Order Totals $0.00
$order->get_formatted_order_total();
$order->get_cart_tax();
$order->get_currency();
$order->get_discount_tax();
$order->get_discount_to_display();
$order->get_discount_total();
$order->get_fees();
$order->get_formatted_line_subtotal();
$order->get_shipping_tax();
$order->get_shipping_total();
$order->get_subtotal();
$order->get_subtotal_to_display();
$order->get_tax_location();
$order->get_tax_totals();
$order->get_taxes();
$order->get_total();
$order->get_total_discount();
$order->get_total_tax();
$order->get_total_refunded();
$order->get_total_tax_refunded();
$order->get_total_shipping_refunded();
$order->get_item_count_refunded();
$order->get_total_qty_refunded();
$order->get_qty_refunded_for_item();
$order->get_total_refunded_for_item();
$order->get_tax_refunded_for_item();
$order->get_total_tax_refunded_by_rate_id();
$order->get_remaining_refund_amount();
  
// Get and Loop Over Order Items
foreach ( $order->get_items() as $item_id => $item ) {
   $product_id = $item->get_product_id();
   $variation_id = $item->get_variation_id();
   $product = $item->get_product();
   $product_name = $item->get_name();
   $quantity = $item->get_quantity();
   $subtotal = $item->get_subtotal();
   $total = $item->get_total();
   $tax = $item->get_subtotal_tax();
   $taxclass = $item->get_tax_class();
   $taxstat = $item->get_tax_status();
   $allmeta = $item->get_meta_data();
   $somemeta = $item->get_meta( '_whatever', true );
   $product_type = $item->get_type();
}
 
// Other Secondary Items Stuff
$order->get_items_key();
$order->get_items_tax_classes();
$order->get_item_count();
$order->get_item_total();
$order->get_downloadable_items();
$order->get_coupon_codes();
  
// Get Order Lines
$order->get_line_subtotal();
$order->get_line_tax();
$order->get_line_total();
  
// Get Order Shipping
$order->get_shipping_method();
$order->get_shipping_methods();
$order->get_shipping_to_display();
  
// Get Order Dates
$order->get_date_created();
$order->get_date_modified();
$order->get_date_completed();
$order->get_date_paid();
  
// Get Order User, Billing & Shipping Addresses
$order->get_customer_id();
$order->get_user_id();
$order->get_user();
$order->get_customer_ip_address();
$order->get_customer_user_agent();
$order->get_created_via();
$order->get_customer_note();
$order->get_address_prop();
$order->get_billing_first_name();
$order->get_billing_last_name();
$order->get_billing_company();
$order->get_billing_address_1();
$order->get_billing_address_2();
$order->get_billing_city();
$order->get_billing_state();
$order->get_billing_postcode();
$order->get_billing_country();
$order->get_billing_email();
$order->get_billing_phone();
$order->get_shipping_first_name();
$order->get_shipping_last_name();
$order->get_shipping_company();
$order->get_shipping_address_1();
$order->get_shipping_address_2();
$order->get_shipping_city();
$order->get_shipping_state();
$order->get_shipping_postcode();
$order->get_shipping_country();
$order->get_address();
$order->get_shipping_address_map_url();
$order->get_formatted_billing_full_name();
$order->get_formatted_shipping_full_name();
$order->get_formatted_billing_address();
$order->get_formatted_shipping_address();
  
// Get Order Payment Details
$order->get_payment_method();
$order->get_payment_method_title();
$order->get_transaction_id();
  
// Get Order URLs
$order->get_checkout_payment_url();
$order->get_checkout_order_received_url();
$order->get_cancel_order_url();
$order->get_cancel_order_url_raw();
$order->get_cancel_endpoint();
$order->get_view_order_url();
$order->get_edit_order_url();
  
// Get Order Status
$order->get_status();
 
// Get Thank You Page URL
$order->get_checkout_order_received_url();

Поделиться в соц. сетях:

  • Похожие записи
  • Комментарии
  • Вложения
Разный порядок товаров в разных категориях

Разный порядок товаров в разных категориях

Допустим у нас есть товары которые принадлежат нескольким категориям. При этом в разных категориях одни и те же товары должны быть в разном порядке. Например в Категории 1 Товар A Читать далее »

Массовое редактирование свойств товаров

Массовое редактирование свойств товаров

Быстрое изменение товаров Для того чтобы массово отредактировать товары woocommerce нужно установить плагин Woocommerce advanced bulk edit. В репозитории плагинов WordPress его нет, он платный. Если поискать на просторах интернета Читать далее »

/ /
Шорткоды woocommerce

Шорткоды woocommerce

Для вывода (например) на главной странице сайта элементов WC. Последние продуктыПолезно для использования на главной странице. Определяет, сколько товаров показывать на странице и количество сколько столбцов. Код: Рекомендуемые (featured)Работает точно Читать далее »

/

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

14 комментариев

  1. Игорь

    Здравствуйте! А как вставить только ТЕКСТ (h3) МЕЖДУ ПОЛЯМИ в Детали оплаты? Мне собственно перед адресом надо вставить ТОЛЬКО текст — «Доставка только по ….» — и необходимо это как-то отдельным полем на всю ширину… остальные поля у меня в два столбца идут…
    Спасибо!

    1. Alexandr

      Необходимо править шаблон woocommerce (локализованный) cart/cart-shipping.php. !После строки:

      <?php if ( $show_package_details ) : ?>

      Либо делать хук, например к функции woocommerce_review_order_before_shipping

  2. Сергей

    Как вывести результат Радиокнопки в Детали заказа ?

  3. Дмитрий

    Может вы подскажете где искать инфу. Требуется В зависимости от размера Добавлять товар в корзину под разным id и соответственно все это потом в оформление отравить. https://prnt.sc/oz3no2

    1. Alexandr

      Это стандартный функционал вариативного товара. Вы создаете у товара вариации от размера и, при добавлении в корзину и оформлении, у товара с каждым размером будет уникальный ID и общий parrent_ID.

  4. Кирилл

    Здравствуйте ! Можете подсказать как добавлять выпадающий список? 

    1. Alexandr

      Добрый день! Еще не могу, выпадающий список еще не добавлял. Как добавлю, опубликую здесь.

  5. Роман

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

    1. Alexandr

      Добрый день! Не подскажу, т.к. не пользуюсь этим (Loco) плагином.

  6. igor

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

  7. Елена

    Спасибо огромное за статью! ) Никак не могла найти способ вывести кастомные поля в Редактирование заказа. Ваша статья мне помогла в этом вопросе )

    1. Alexandr

      Спасибо за отзыв! Очень рад что информация полезна.

  8. Александр

    Здравствуйте. Спасибо вам за полезные статьи.
    Скажите, как создать дополнительную колонку в списке заказов в админке? У меня есть дополнительное поле billing_new_fild4 на странице оформления заказа, но что бы увидеть данные этого поля в списке админке приходится заходить в каждый заказ, это очень не удобно.

  9. ellabustova

    Чекбоксы ок, а селекты как выводить в шаблон письма?

Добавление полей при оформлении заказа Добавление полей при оформлении заказа Добавление полей при оформлении заказа Добавление полей при оформлении заказа
Вывод документов
Рекомендации для васВывод документовOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.