$qorder = wc_create_order();
if ( 0 === $params['type'] ) { /* simple */
$product = wc_get_product( $params['id'] );
$item_id = $qorder->add_product( $product, $params['qty'] );
} elseif ( 1 === $params['type'] ) { /* variable */
$variations_array = array();
$var_product = new WC_Product_Variation( $params['var_id'] );
$variations_array['variation'] = array(
$params['attr_name'] => $params['attr_value'],
);
$item_id = $qorder->add_product( $var_product, $params['qty'], $variations_array );
}
$qorder->set_address( $address, 'billing' );
$qorder->set_address( $address, 'shipping' );
$qorder->calculate_totals();
wc_reduce_stock_levels( $qorder->get_id() );
$qorder->update_status( 'processing' );
echo 'Спасибо за заказ';
/**
* Checks the product type.
*
* Backwards compatibility with downloadable/virtual.
*
* @param string|array $type Array or string of types.
* @return bool
*/
public function is_type( $type ) {
return ( $this->get_type() === $type || ( is_array( $type ) && in_array( $this->get_type(), $type, true ) ) );
}
/**
* Get internal type.
*
* @return string
*/
public function get_type() {
return 'variation';
}
if ( $product->is_type( 'variation' ))
/woocommerce/templates/emails
email-order-items.php
// allow other plugins to add additional product information here.
do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order, $plain_text );
WC_Product
. Да, долго, тяжело, надо разбивать но блоки если много товаров. Зато надежно.$product = wc_get_product($id);
... делаем что то
$product->save();
stock_status
и в таблицу ..._wc_product_meta_lookup
trigger
/**
* AJAX полная очитска корзины
* Функция WC_AJAX::get_refreshed_fragments() сама возвращает код возврата
* todo: Сделать возврат данных для кнопки в корзине.
* todo: Сейчас кнопка в корзине принудительно перезагружает страницу
*/
function ajax_clear_cart() {
WC()->cart->empty_cart( $clear_persistent_cart = true );
WC_AJAX::get_refreshed_fragments();
}
add_action( 'wp_ajax_qop_clear_cart', 'ajax_clear_cart' );
add_action( 'wp_ajax_nopriv_qop_clear_cart', 'ajax_clear_cart' );
/**
* Запуск очистки корзины
* todo: Для страницы корзины сделать обновление без перезагрузки
*/
$(document.body).on('click', '.qop-clear-cart', function (e) {
var $thisbutton = $(e.target),
location = '',
confirmed = confirm("Внимание!!! Все товары из корзины будут удалены. Продолжить?");
if (!confirmed) {
return;
}
// т.к. кнопка очитски есть и в миникорзине, то нужно знать кто вызвал событие.
if ($thisbutton.closest('div.widget_shopping_cart_content').length) {
location = 'widget_mini_cart';
} else if ($thisbutton.closest('form.woocommerce-cart-form').length) {
location = 'page_cart';
}
let productsData = {
action: 'qop_clear_cart',
location: location
};
$.ajax({
url: qopParams.ajax_url,
type: 'POST',
data: productsData,
success: function (response) {
console.log(response);
if (!response || !response.fragments) {
return;
}
if ('widget_mini_cart' === location) {
// Trigger event so themes can refresh other areas.
$(document.body).trigger('removed_from_cart', [response.fragments, response.cart_hash, $thisbutton]);
} else if ('page_cart' === location) {
window.location.reload();
}
},
beforeSend: function () {
$($thisbutton).addClass('loading');
},
complete: function () {
$($thisbutton).removeClass('loading');
}
});
});
/**
* Добавляем уведомление о том, что товар участвует в акции.
* Проверяем участие товара в акции на момент добавления товара в заказ.
*
* @param WC_Order_Item_Product $item Элемент заказа.
* @param array $cart_item_key Уникальный ключ.
* @param array $values
* @param array $order Экземпляр класса заказа.
*/
function pcwoo_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
// проверить участвует ли этот товар в акции и если да, то добавить метаполе с сообщением.
$product = $values['data'];
$parent_id = $product->get_id();
if ( 'variation' === $product->get_type() ) {
$parent_id = $product->get_parent_id();
}
// для предложения "Осеннее предложение -10% в корзине".
$tax = 'promotion';
$term_id = 1390;
if ( has_term( $term_id, $tax, $parent_id ) ) {
$item->add_meta_data( 'promotion_' . $term_id, 'Скидка в корзине: -10%', true );
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'pcwoo_checkout_create_order_line_item', 10, 4 );
// -------------------------------------------------------------------------- /
/**
* Форматируем вывод надписи в письме и в админке в карточке заказа.
*/
function pcwoo_order_item_display_meta_key( $display_key, $meta, $order_item ) {
if ( 'promotion_' === substr( $display_key, 0, 10 ) ) {
$display_key = __( 'Участие в акции' );
}
return $display_key;
}
add_filter( 'woocommerce_order_item_display_meta_key', 'pcwoo_order_item_display_meta_key', 10, 3 );
has_term
и исключите этот товар из применения скидки. /**
* Множественное добавление в корзину
* Вызывается по Ajax
*
* @hook-handle qop_add_to_cart
*/
public function ajax_add_to_cart() {
$product_items = isset( $_POST['products'] ) && is_array( $_POST['products'] ) ? $_POST['products'] : false;
$errors = array();
$added_products_count = 0;
foreach ( $product_items as $item ) {
$product_id = $item['product_id'];
$quantity = $item['quantity'];
$variation_id = $item['variation_id'];
$title = $item['product_title'];
$sku = $item['sku']; // для простого товара здесь тоже его sku
$passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity );
$product_status = get_post_status( $product_id );
if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity, $variation_id ) && 'publish' === $product_status ) {
do_action( 'woocommerce_ajax_added_to_cart', $product_id );
$added_products_count ++;
} else {
$notices = WC()->session->get( 'wc_notices', array() );
if ( isset( $notices['error'] ) ) {
$error = array_pop( $notices['error'] );
$err_msg = preg_replace( '/<a.*?href.*?=(.*)>(.*?)<\/a>/', '', $error );
$errors[] = array(
'variationId' => $variation_id,
'title' => $title,
'sku' => $sku,
'msg' => $err_msg,
);
}
wc_clear_notices();
}
}
$response = array(
'added' => $added_products_count,
'errors' => $errors,
'popup' => $this->template_errors_formating( $errors ), // Формирование собственного popup-a для пользователя
'cart' => $this->get_refreshed_fragments(), // необходимо для обновления миникорзины в шапке.
);
wp_send_json( $response );
}
woocommerce_quantity_input_step
выводить это значение. Тогда для каждой вариации у Вас будут разные значения шага. wp_postmeta
в поле с ключом attribute_pa_xxx
, где ххх - это слаг Вашего атрибута, индивидуально для каждой разновидности(вариации). Проверьте содержимое этих записей на соответсвие.