#php #wordpress #woocommerce
Вопрос:
Я реализовал разделение доставки в соответствии с идентификатором доставки товара в корзине. и он отлично работает см. Скриншот и код:
add_filter('woocommerce_cart_shipping_packages', 'woo_cart_shipping_packages');
function woo_cart_shipping_packages($packages)
{
foreach (WC()->cart->get_cart() as $item)
{
if ($item['data']->needs_shipping())
{
$get_shipping_class = $item['data']->get_shipping_class();
$shipping_classes[] = $get_shipping_class;
$regular_items[$get_shipping_class][] = $item;
$check_chrono_shipping = false;
}
}
if ($regular_items)
{
$i = 1;
$shipping_methods = WC()->shipping->get_shipping_methods();
foreach ($shipping_methods as $shipping_method)
{
if (!in_array($shipping_method->id, $chrono_shipping_method_ids))
{
$shipping_method_ids[] = $shipping_method->id;
}
}
if(!$chrono_multi_shipping amp;amp; !$fresh_dry_products amp;amp; !$check_chrono_shipping){
$shipping_method_ids = array_merge($shipping_method_ids, $chrono_not_fresh_not_freeze);
}
foreach ($regular_items as $ship_via => $new_package) {
$shipping_class_name = 'Regular Shipping ' . $i;
$get_shipping_class_name = get_term_by('slug', $ship_via, 'product_shipping_class');
if ($get_shipping_class_name)
{
$shipping_class_name = ucwords($get_shipping_class_name->name);
}
$packages[] = array(
'ship_via' => $shipping_method_ids ?: array('flat_rate', 'local_pickup', 'free_shipping'),
'name' => $shipping_class_name,
'contents' => $new_package,
'contents_cost' => array_sum(wp_list_pluck($new_package, 'line_total')),
'applied_coupons' => WC()->cart->applied_coupons,
'destination' => array(
'country' => WC()->customer->get_shipping_country(),
'state' => WC()->customer->get_shipping_state(),
'postcode' => WC()->customer->get_shipping_postcode(),
'city' => WC()->customer->get_shipping_city(),
'address' => WC()->customer->get_shipping_address(),
'address_2' => WC()->customer->get_shipping_address_2()
)
);
$i ;
}
}
return $packages;
}
Я столкнулся с проблемой по thankyou.php: После размещения заказа нам нужно найти product_id, класс доставки, способ доставки в массиве в соответствии с идентификатором заказа.
Проблема:
//$order = wc_get_order($order_id);
$order_shippings = array();
foreach ($order->get_items() as $item_key => $item ){
$product_id = $item->get_product_id();
$shipping_class_id = $product->get_shipping_class_id();
$shipping_class_term = get_term($shipping_class_id, 'product_shipping_class');
$product_shipping_slug = $shipping_class_term->slug ?: '';
$order_shippings[$product_id] = $shipping_class_id;
$order_shippings[$product_id] = $product_shipping_slug;
}
Таким образом, мы получили идентификатор продукта и класс доставки, но не смогли определить, какой способ доставки применим для этого продукта?
Проблема 2:
foreach ($order->get_items('shipping') as $item_id => $shipping_item_obj){
$shipping_method_id = $shipping_item_obj->get_method_id();
$order_shippings['shipping_method_name'] = $shipping_item_obj->get_name();
$order_shippings['shipping_method_title'] = $shipping_item_obj->get_method_title();
}
Таким образом, мы получили идентификатор shipping_method, но не смогли определить, какой продукт применил этот метод доставки.
Нужно решение: На самом деле я хочу получить отдельно идентификатор продукта, применяемый класс доставки, применяемый метод доставки из любого/заданного идентификатора заказа.
Ответ №1:
Поскольку я проверяю ваш код, все в порядке, вам следует выполнить несколько шагов, таких как
храните свои способы доставки, которые вы хотите разделить по порядку
$woo_freeze_shipping = array('shipping_methods');
$woo_fresh_product = array('shipping_methods')
$woo_not_fresh_not_freeze = array('shipping_methods');
Затем используйте $order->get_items («доставка»), как это:
$records = $order_shippings = $shipping_classess = array();
foreach ($order->get_items('shipping') as $item_id => $shipping_item_obj)
{
$shipping_method_id = $shipping_item_obj->get_method_id();
$order_shippings[$shipping_method_id]['shipping_method_name'] = $shipping_item_obj->get_name();
$order_shippings[$shipping_method_id]['shipping_method_title'] = $shipping_item_obj->get_method_title();
$order_shippings[$shipping_method_id]['shipping_method_instance_id'] = $shipping_item_obj->get_instance_id(); // The instance ID
$order_shippings[$shipping_method_id]['shipping_method_total'] = $shipping_item_obj->get_total();
$order_shippings[$shipping_method_id]['shipping_method_total_tax'] = $shipping_item_obj->get_total_tax();
$order_shippings[$shipping_method_id]['shipping_method_taxes'] = $shipping_item_obj->get_taxes();
if (in_array($shipping_method_id, $woo_freeze_shipping))
{
$order_shippings['freeze-product'] = $shipping_method_id;
}
elseif (in_array($shipping_method_id, $woo_fresh_product))
{
$order_shippings['fresh-product'] = $shipping_method_id;
}
elseif (in_array($shipping_method_id, $woo_not_fresh_not_freeze))
{
$order_shippings['not-fresh-not-freeze'] = $shipping_method_id;
}
else
{
$order_shippings['regular_shipping'] = $shipping_method_id;
}
}
Таким образом, вы можете хранить информацию о способе доставки в $order_shippings в соответствии с вашим разделенным классом доставки(замороженный продукт,замороженный продукт,не свежий, не замороженный).
Теперь, используя foreach ($order->get_items() как $item_id =>> $item), вы можете управлять и создавать новый заказ отдельно
Полный пример:
add_action('woocommerce_thankyou', 'woo_split_order_items', 10, 1);
if (!function_exists('woo_split_order_items'))
{
function woo_split_order_items($order_id)
{
global $order_ids, $woo_freeze_shipping, $woo_fresh_product, $woo_not_fresh_not_freeze;
if (!$order_id) {
return;
}
$order = wc_get_order($order_id);
if (!get_post_meta($order_id, '_thankyou_action_done', true) amp;amp; ( is_checkout() || is_wc_endpoint_url('order-received') ))
{
$records = $order_shippings = $shipping_classess = array();
$variable = false;
foreach ($order->get_items('shipping') as $item_id => $shipping_item_obj)
{
$shipping_method_id = $shipping_item_obj->get_method_id();
$order_shippings[$shipping_method_id]['shipping_method_name'] = $shipping_item_obj->get_name();
$order_shippings[$shipping_method_id]['shipping_method_title'] = $shipping_item_obj->get_method_title();
$order_shippings[$shipping_method_id]['shipping_method_instance_id'] = $shipping_item_obj->get_instance_id(); // The instance ID
$order_shippings[$shipping_method_id]['shipping_method_total'] = $shipping_item_obj->get_total();
$order_shippings[$shipping_method_id]['shipping_method_total_tax'] = $shipping_item_obj->get_total_tax();
$order_shippings[$shipping_method_id]['shipping_method_taxes'] = $shipping_item_obj->get_taxes();
if (in_array($shipping_method_id, $woo_freeze_shipping))
{
$order_shippings['freeze-product'] = $shipping_method_id;
}
elseif (in_array($shipping_method_id, $woo_fresh_product))
{
$order_shippings['fresh-product'] = $shipping_method_id;
}
elseif (in_array($shipping_method_id, $woo_not_fresh_not_freeze))
{
$order_shippings['not-fresh-not-freeze'] = $shipping_method_id;
}
else
{
$order_shippings['regular_shipping'] = $shipping_method_id;
}
}
$records['order'] = array(
'order_id' => $order->get_id(),
'currency' => $order->get_currency(),
'payment_method' => $order->get_payment_method(),
'payment_method_title' => $order->get_payment_method_title(),
'status' => $order->get_status() ?: 'pending',
'shipping_address' => $order->get_address('shipping'),
'billing_address' => $order->get_address('billing'),
'customer_id' => $order->get_customer_id(),
'user_id' => $order->get_user_id(),
'customer_ip_address' => $order->get_customer_ip_address(),
'customer_user_agent' => $order->get_customer_user_agent(),
'created_via' => $order->get_created_via(),
'customer_note' => $order->get_customer_note(),
);
foreach ($order->get_items() as $item_id => $item)
{
if (isset($item['product_id']) amp;amp; $item['product_id']>0)
{
$product = $item->get_product();
$shipping_class_id = $product->get_shipping_class_id();
$shipping_class_term = get_term($shipping_class_id, 'product_shipping_class');
$product_shipping_slug = $shipping_class_term->slug;
if ($product->is_type('variation'))
{
$parent_id = $product->get_parent_id();
$variation_id = $product->get_id();
$variable_prod = $product;
$product = wc_get_product($product->get_parent_id());
$variable = true;
}
else{
$parent_id = $item['parent_id'] ?: 0;
$variation_id = $item->get_variation_id() ?: 0;
$variable_prod = null;
$variable = false;
}
if ($order_shippings[$product_shipping_slug])
{
$product_shipping_class = $product_shipping_slug;
}
else if($product_shipping_slug == 'not-fresh-not-freeze')
{
$product_shipping_class = 'fresh-product';
}
else
{
$product_shipping_class = 'regular_shipping';
}
$shipping_classess[] = $product_shipping_class;
$shipping_method = $order_shippings[$product_shipping_class] ?: '';
$shipping_method_name = $order_shippings[$shipping_method]['shipping_method_name'] ?: '';
$shipping_method_title = $order_shippings[$shipping_method]['shipping_method_title'] ?: '';
$shipping_method_instance_id = $order_shippings[$shipping_method]['shipping_method_instance_id'] ?: '';
$shipping_method_total = $order_shippings[$shipping_method]['shipping_method_total'] ?: 0;
$shipping_method_total_tax = $order_shippings[$shipping_method]['shipping_method_total_tax'] ?: 0;
$shipping_method_taxes = $order_shippings[$shipping_method]['shipping_method_taxes'] ?: array('total' => array());
$product_shippings = array(
'product_id' => $item_id,
'product_shipping_class' => $product_shipping_class,
'shipping_class_id' => $shipping_class_id,
'shipping_method' => $shipping_method,
'shipping_method_name' => $shipping_method_name,
'shipping_method_title' => $shipping_method_title,
'shipping_method_instance_id' => $shipping_method_instance_id,
'shipping_method_total' => $shipping_method_total,
'shipping_method_total_tax' => $shipping_method_total_tax,
'shipping_method_taxes' => $shipping_method_taxes,
);
$ordered_products = array(
'product_id' => $item_id,
'parent_id' => $parent_id,
'variation_id' => $variation_id,
'name' => $item->get_name(),
'quantity' => $item->get_quantity(),
'subtotal' => $item->get_subtotal(),
'tax' => $item->get_subtotal_tax(),
'total' => $item->get_total(),
'taxclass' => $item->get_tax_class(),
'taxstat' => $item->get_tax_status(),
'allmeta' => $item->get_meta_data(),
'somemeta' => $item->get_meta('_whatever', true),
'type' => $item->get_type(),
'taxes' => $item->get_taxes(),
'line_subtotal' => $item->get_subtotal(), // Line subtotal (non discounted)
'line_subtotal_tax' => $item->get_subtotal_tax(), // Line subtotal tax (non discounted)
'line_total' => $item->get_total(), // Line total (discounted)
'line_total_tax' => $item->get_total_tax(), // Line total tax (discounted)
'variable' => $variable,
'variable_prod' => $variable_prod,
'product' => $product,
);
$records['product'][$product_shipping_class]['shipping'] = $product_shippings;
$records['product'][$product_shipping_class]['items'][] = $ordered_products;
}
}
$shipping_classess = array_filter(array_unique($shipping_classess));
if((isset($records['product']) amp;amp; !empty($records['product'])) amp;amp; (isset($shipping_classess) amp;amp; count($shipping_classess)>1) )
{
$ordered_product = $order_ids = array();
foreach ($records['product'] as $product_shipping_class => $items)
{
$order_status = $records['order']['status'];
/*==== SET SHIPPING IN A ORDER ====== */
$shipping_title = $items['shipping']['shipping_method_title'];
$shipping_method_name = $items['shipping']['shipping_method_name'];
$shipping_method_id = $items['shipping']['shipping_method'];
/*=====UPDATE Extra Shipping Label =======*/
// if(empty($ordered_product)){
// // Remove all items - we will re-add them later.
// $order->remove_order_items();
// }else{
// $order = new WC_Order($args);
// }
/*==== NEW ORDER ARGS ====== */
$args = array(
'order_id' => null,
'status' => $order_status
);
/*===== CREATE NEW ORDER FROM ORIGNAL ORDER ============*/
$new_order = new WC_Order($args);
foreach ($items['items'] as $product)
{
if (isset($product['variation_id']) amp;amp; absint($product['variation_id'])>0)
{
$product_id = absint($product['parent_id']);
}
else
{
$product_id = absint($product['product_id']);
}
if ($product_id>0 amp;amp; !in_array($product_id, $ordered_product))
{
$new_product = $product['product'] ?: null;
$variable_prod= $product['variable_prod'] ?: null;
$variation_id = absint($product['variation_id']) ?: 0;
$quantity = absint($product['quantity']) ?: 1;
$variable = $product['variable'] ?: false;
$subtotal = $product['subtotal'] ?: 0;
$total = $product['total'] ?: 0;
$subtotal_tax = $product['tax'] ?: 0;
$total_tax = $product['line_total_tax'] ?: 0;
$taxes = $product['taxes'];
/*==== SET LINE TOTAL ====== */
$new_item = new WC_Order_Item_Product();
$new_item->set_backorder_meta();
$new_item->set_product($new_product);
$new_item->set_props([
'quantity' => $quantity,
'subtotal' => $subtotal,
'total' => $total,
'subtotal_tax' => $subtotal_tax,
'total_tax' => $total_tax,
'taxes' => $taxes,
]);
$new_order->add_item($new_item);
array_push($ordered_product, $product_id);
}
} //# End multi product loop
$shipping_method = new WC_Order_Item_Shipping();
$shipping_rate = new WC_Shipping_Rate();
$shipping_rate->set_method_id($shipping_method_id);
$shipping_rate->set_instance_id($items['shipping']['shipping_method_instance_id']);
$shipping_rate->set_label($shipping_title);
$shipping_rate->set_cost($items['shipping']['shipping_method_total']);
$shipping_method->set_name($shipping_method_name);
$shipping_method->set_method_title($shipping_title);
$shipping_method->set_method_id($shipping_method_id);
$shipping_method->set_instance_id($items['shipping']['shipping_method_instance_id']);
$shipping_method->set_total($items['shipping']['shipping_method_total']);
$shipping_method->set_shipping_rate($shipping_rate);
$new_order->add_item($shipping_method);
/*==== SET ORDER META ====== */
$new_order->set_currency($records['order']['currency'] ?: get_woocommerce_currency());
$new_order->set_customer_id($records['order']['customer_id'] ?: get_current_user_id());
$new_order->set_created_via($records['order']['created_via'] ?: 'checkout');
$new_order->set_customer_ip_address($records['order']['customer_ip_address'] ?: $_SERVER['REMOTE_ADDR']);
$new_order->set_customer_user_agent($records['order']['customer_user_agent'] ?: '');
$new_order->set_customer_note(isset($records['order']['customer_note']) ? $records['order']['customer_note'] : '');
/*==== SET PAYMENT GATWAY ORDER ====== */
if (isset($records['order']['payment_method']) amp;amp; $records['order']['payment_method'])
{
$new_order->set_payment_method($records['order']['payment_method']);
}
/*==== SET COUPONS ORDER ====== */
if (WC()->cart amp;amp; $coupons = WC()->cart->get_coupons())
{
foreach ($coupons as $code => $coupon)
{
$coupon_item = new WC_Order_Item_Coupon(
array(
'code' => $code,
'discount' => WC()->cart->get_coupon_discount_amount($code),
'discount_tax' => WC()->cart->get_coupon_discount_tax_amount($code)
)
);
$new_order->add_item($coupon_item);
}
}
/*==== SET ADDRESS ORDER ====== */
if (isset($records['order']['billing_address']))
{
$new_order->set_address($records['order']['billing_address'], 'billing');
}
if (isset($records['order']['shipping_address']))
{
$new_order->set_address($records['order']['shipping_address'], 'shipping');
}
/*==== CALCULATE TOTALS ====== */
$new_order->calculate_totals();
$new_order->update_status($order_status, '<p>Order created dynamically from chronofood</p>', TRUE);
/*==== SAVE ORDER ====== */
$new_order->update_meta_data('_thankyou_action_done', true);
if($new_order->save()){
array_push($order_ids, $new_order->id);
}
} // # End Create new order loop
/* Change existing /orignal order status */
$order->update_status('split-status', '<p>Orignal Order splited</p>', TRUE);
/* Flag the action as done (to avoid repetitions on reload for example) */
add_post_meta($order_id, '_thankyou_action_done', true, true);
$order->update_meta_data('_thankyou_action_done', true);
}
}
}
}