Вопрос или проблема
У меня есть пользовательский код, который разделяет каждый продукт на отдельный заказ. Я добавил пользовательские поля в страницу оформления заказа, которые представляют собой номер регистрации компании и номер НДС компании. Теперь, когда продукты разделены на отдельные заказы, я хотел бы, чтобы эти пользовательские поля также были связаны с новыми разделенными заказами. По какой-то причине в данный момент они разделены правильно, но пользовательские поля не связаны с заказами.
Текущий код выглядит следующим образом:
// Добавить пользовательские поля на страницу оформления заказа
add_filter('woocommerce_checkout_fields', 'add_billing_custom_fields');
function add_billing_custom_fields($fields) {
// Добавить поле номера регистрации компании
$fields['billing']['billing_company_register_number'] = array(
'type' => 'text',
'label' => __('Номер регистрации компании', 'text-domain'),
'placeholder' => __('Введите номер регистрации компании', 'text-domain'),
'required' => true, // Установить в true, если поле обязательно
'class' => array('form-row-wide'),
'priority' => 25,
);
// Добавить поле номера НДС
$fields['billing']['billing_vat_number'] = array(
'type' => 'text',
'label' => __('Номер плательщика НДС', 'text-domain'),
'placeholder' => __('Введите номер плательщика НДС', 'text-domain'),
'required' => false, // Установить в true, если НДС обязателен
'class' => array('form-row-wide'),
'priority' => 26,
);
return $fields;
}
// Сохранить значения пользовательских полей в метаданных заказа
add_action('woocommerce_checkout_update_order_meta', 'save_billing_custom_fields');
function save_billing_custom_fields($order_id) {
// Сохранить номер регистрации компании
if (!empty($_POST['billing_company_register_number'])) {
update_post_meta($order_id, '_billing_company_register_number', sanitize_text_field($_POST['billing_company_register_number']));
}
// Сохранить номер НДС
if (!empty($_POST['billing_vat_number'])) {
update_post_meta($order_id, '_billing_vat_number', sanitize_text_field($_POST['billing_vat_number']));
}
}
// Отобразить поля в панели администратора заказа
add_action('woocommerce_admin_order_data_after_billing_address', 'display_billing_custom_fields_in_admin', 10, 1);
function display_billing_custom_fields_in_admin($order) {
// Отобразить номер регистрации компании
$company_register_number = get_post_meta($order->get_id(), '_billing_company_register_number', true);
if ($company_register_number) {
echo '<p><strong>' . __('Номер регистрации компании', 'text-domain') . ':</strong> ' . esc_html($company_register_number) . '</p>';
}
// Отобразить номер НДС
$vat_number = get_post_meta($order->get_id(), '_billing_vat_number', true);
if ($vat_number) {
echo '<p><strong>' . __('Номер плательщика НДС', 'text-domain') . ':</strong> ' . esc_html($vat_number) . '</p>';
}
}
// Добавить поля в электронные письма заказов
add_filter('woocommerce_email_order_meta_fields', 'add_billing_custom_fields_to_emails', 10, 3);
function add_billing_custom_fields_to_emails($fields, $sent_to_admin, $order) {
// Добавить номер регистрации компании в электронные письма
$fields['billing_company_register_number'] = array(
'label' => __('Номер регистрации компании', 'text-domain'),
'value' => get_post_meta($order->get_id(), '_billing_company_register_number', true),
);
// Добавить номер НДС в электронные письма
$fields['billing_vat_number'] = array(
'label' => __('Номер плательщика НДС', 'text-domain'),
'value' => get_post_meta($order->get_id(), '_billing_vat_number', true),
);
return $fields;
}
/* Логика корректного разделения заказов по месту назначения */
add_action('woocommerce_checkout_create_order_line_item', 'add_cart_meta_to_order_items', 10, 4);
function add_cart_meta_to_order_items($item, $cart_item_key, $values, $order) {
$meta_keys = [
'main_destination' => 'Место назначения',
'package_details' => 'Детали пакета',
'pickup_point' => 'Пункт получения',
'main_client' => 'Клиент',
'main_regnr' => 'РегНомер',
'zone' => 'Зона',
];
foreach ($meta_keys as $cart_key => $order_meta_key) {
if (!empty($values[$cart_key])) {
$item->add_meta_data($order_meta_key, $values[$cart_key], true);
}
}
}
/* Разделение заказов по месту назначения */
add_action('woocommerce_thankyou', 'split_products_into_individual_orders', 10, 1);
function split_products_into_individual_orders($order_id) {
$original_order = wc_get_order($order_id);
if (!$original_order) {
error_log('Оригинальный заказ не найден: ' . $order_id);
return; // Остановить, если заказ недействителен.
}
error_log('Разделение заказа ID: ' . $order_id);
// Получить пользовательские поля счета из оригинального заказа
$billing_company_register_number = $original_order->get_meta('_billing_company_register_number', true);
$billing_vat_number = $original_order->get_meta('_billing_vat_number', true);
// Перебрать каждый продукт в заказе
foreach ($original_order->get_items() as $item_id => $item) {
$product_id = $item->get_product_id();
// Записать обрабатываемый продукт
error_log('Обработка продукта ID: ' . $product_id);
// Создать новый заказ для продукта
$new_order = wc_create_order();
if (!$new_order) {
error_log('Не удалось создать новый заказ для продукта ID: ' . $product_id);
continue; // Пропустить к следующему элементу, если создание заказа не удалось.
}
// Добавить продукт в новый заказ
$new_order->add_product(wc_get_product($product_id), $item->get_quantity(), array(
'subtotal' => $item->get_subtotal(),
'total' => $item->get_total(),
'subtotal_tax' => $item->get_subtotal_tax(),
'total_tax' => $item->get_total_tax(),
));
// Скопировать все метаданные из оригинального элемента
foreach ($item->get_meta_data() as $meta) {
$new_order->add_meta_data($meta->key, $meta->value, true);
}
// Скопировать детали клиента
$new_order->set_address($original_order->get_address('billing'), 'billing');
$new_order->set_address($original_order->get_address('shipping'), 'shipping');
// Добавить пользовательские поля в новый заказ
if ($billing_company_register_number) {
$new_order->update_meta_data('_billing_company_register_number', $billing_company_register_number);
}
if ($billing_vat_number) {
$new_order->update_meta_data('_billing_vat_number', $billing_vat_number);
}
// Скопировать метод оплаты и другие детали
$new_order->set_payment_method($original_order->get_payment_method());
$new_order->set_payment_method_title($original_order->get_payment_method_title());
$new_order->set_currency($original_order->get_currency());
// Установить новый заказ в статус обработки и сохранить
$new_order->calculate_totals();
$new_order->update_status('processing', __('Новый заказ создан в процессе разделения.', 'text-domain'));
$new_order->save();
// Записать создание нового заказа
error_log('Создан новый заказ с ID: ' . $new_order->get_id());
}
// Отменить оригинальный заказ после разделения
$original_order->update_status('cancelled', __('Оригинальный заказ разделен на отдельные заказы.', 'text-domain'));
error_log('Оригинальный заказ отменен: ' . $order_id);
}
Есть идеи, почему поля не добавляются к новым разделенным заказам?
Ответ или решение
Проблема с добавлением пользовательских полей в разделенные заказы: Возможные решения
Введение
Создание пользовательских полей на странице оформления заказа в WooCommerce — это важный шаг для сбора необходимой информации от клиентов. В вашем случае, вы добавили поля для номера регистрации компании и номера НДС. Однако, несмотря на успешное разделение заказов на отдельные продукты, пользовательские поля не копируются в новые заказы. Давайте рассмотрим, как это исправить.
Контекст проблемы
При использовании кастомного кода, созданного для разделения каждого продукта на отдельный заказ, вы уже реализовали создание пользовательских полей и их сохранение в метаданных заказа. Несмотря на это, при разделении первоначального заказа пользовательские поля не добавляются к новым заказам. Это может произойти по нескольким причинам.
Основные аспекты, требующие внимания:
-
Сохранение пользовательских полей:
В вашей функцииsplit_products_into_individual_orders
вы пытаетесь скопировать значения пользовательских полей из оригинального заказа. Однако убедитесь, что вы проверяете наличие пользовательских полей непосредственно перед их использованием в метаданных нового заказа. -
Корректное использование метаданных:
В коде добавления метаданных используются методыget_meta
иupdate_meta_data
. Убедитесь, что ваши ключи метаданных, например,_billing_company_register_number
, соответствуют тем, которые вы использовали при создании метаданных на этапе оформления заказа. Ошибки в ключах могут привести к тому, что данные не будут скопированы. -
Логирование для диагностики:
Добавление операций логирования, как вы уже делаете в коде сerror_log
, может помочь в выявлении ошибок. Проверьте логи на предмет того, что данные для полей не пусты перед их копированием.
План действий
-
Убедитесь, что поля существуют и корректно обрабатываются:
Проверьте, успешно ли сохраняются данные в оригинальном заказе. Например, добавьте дебаг-вывод перед строками, которые копируют значения полей. -
Обновите проверку полей:
Обновите код в функцииsplit_products_into_individual_orders
следующим образом:// Копирование пользовательских полей в новый заказ if (!empty($billing_company_register_number)) { $new_order->update_meta_data('_billing_company_register_number', $billing_company_register_number); } if (!empty($billing_vat_number)) { $new_order->update_meta_data('_billing_vat_number', $billing_vat_number); }
-
Тестируйте функциональность:
После внесения изменений постарайтесь повторить сценарий, в котором происходит разделение заказов, и проверьте, начали ли заполняться поля в новых заказах.
Заключение
Ваш код содержит все необходимые элементы для работы с пользовательскими полями в WooCommerce. Для решения проблемы с их отсутствием в новых заказах требуется тщательно проверить, правильно ли копируются значения метаданных. Завершив все корректировки, вы сможете обеспечить полноценный функционал для разделения заказов и сохранения в них пользовательских данных.
Если проблема сохраняется, рассмотреть возможность взаимодействия с форумами WooCommerce или обратиться к сообществу разработчиков для поиска дополнительной информации или устранения возможных конфликтов с другими плагинами.