如果在WooCommerce中自动添加包装,则在选择产品重量时不计算最终成本 [英] The final cost is not calculated when choosing the weight of the product if the packaging is automatically added in WooCommerce

查看:32
本文介绍了如果在WooCommerce中自动添加包装,则在选择产品重量时不计算最终成本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 WooCommerce 中,我使用的代码显示牛排重量选择表、保存选择数据并在购物车、结账页面、编辑订单和电子邮件通知中显示此数据.

//显示自定义复选框字段add_action('woocommerce_product_options_general_product_data', 'steak_custom_field_add');函数牛排_custom_field_add(){全球 $post;//复选框woocommerce_wp_checkbox(大批('id' =>'_steak_checkbox','标签' =>__('牛排重量', 'woocommerce'),'说明' =>__( '如有必要,启用牛排重量选择', 'woocommerce' )));}//保存自定义复选框字段add_action('woocommerce_process_product_meta', 'steak_custom_field_save');功能牛排_custom_field_save($post_id){//自定义产品复选框字段$steak_checkbox = isset( $_POST['_steak_checkbox'] ) ?是":否";update_post_meta($post_id, '_steak_checkbox', esc_attr( $steak_checkbox ));}//显示自定义选择框add_action( 'woocommerce_before_add_to_cart_button', 'display_steak_custom_field', 0 );函数 display_steak_custom_field() {全球$产品;//如果是单个产品页面并且启用了steak_checkbox",我们将显示该字段if ( $product->get_meta( '_steak_checkbox' ) === 'yes' ) {echo '

';$select = woocommerce_form_field( 'steak_custom_options', array('类型' =>'选择','类' =>数组('我的牛排选择框表单行宽'),'标签' =>__('牛排重量'),'必需' =>错误的,'返回' =>错误的,'选项' =>大批('' =>'选择...','300g' =>'300克','400g' =>'400g','500g' =>'500g','600g' =>'600g','700g' =>'700g','800g' =>'800g','900g' =>'900g','1000g' =>'1000g')), '' );回声 $select;回声'</div>';}}//添加为自定义购物车项目数据add_filter('woocommerce_add_cart_item_data', 'add_custom_steak_cart_item_data', 10, 21);函数 add_custom_steak_cart_item_data($cart_item_data, $product_id, $variation_id ){if( isset( $_POST['steak_custom_options'] ) ) {$cart_item_data['steak_option'] = wc_clean( $_POST['steak_custom_options'] );}返回 $cart_item_data;}//在购物车中的购物车项目名称下添加自定义字段值add_filter( 'woocommerce_cart_item_name', 'steak_custom_field_add_cart', 10, 21 );函数牛排_custom_field_add_cart( $item_name, $cart_item, $cart_item_key ) {如果(!is_cart())返回 $item_name;if( isset($cart_item['steak_option']) ) {$item_name .= '<div class="my-steak-class"><strong>'.__("牛排重量", "woocommerce") .':' .$cart_item['steak_option'] .'</div>';}返回 $item_name;}//在结帐时显示项目名称下的自定义字段值add_filter('woocommerce_checkout_cart_item_quantity', 'steak_custom_checkout_cart_item_name', 10, 21);函数牛排_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {if( isset($cart_item['steak_option']) ) {$item_qty .= '<div class="my-steak-class"><strong>'.__("牛排重量", "woocommerce") .':' .$cart_item['steak_option'] .'гр.</div>';}返回 $item_qty;}//将选择的选择字段值保存到每个订单项作为自定义元数据并在任何地方显示add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_steak_field', 10, 21 );函数 save_order_item_steak_field( $item, $cart_item_key, $values, $order ) {if( isset($values['steak_option']) ) {$key = __('牛排重量', 'woocommerce');$value = $values['steak_option'];$item->update_meta_data( $key, $value ,$item->get_id());}}add_action('wp_footer','add_footer_steak_script');函数 add_footer_steak_script(){?><脚本>( 函数( $ ) {$( 文档 ).ready( 函数() {$(document).on('change', '#steak_custom_options' ,function() {$('.add_to_cart_button').data('steak_custom_options', this.value)});});}( jQuery ) );<?php}add_action( 'woocommerce_before_calculate_totals', 'my_before_calculate_totals', 10, 1 );函数 my_before_calculate_totals( $cart ) {if ( is_admin() && !defined( 'DOING_AJAX' ) )返回;if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )返回;//遍历购物车项目foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {if( isset( $cart_item['steak_option'] ) ) {//删除最后 2 个零(100g 变成 1,300g 变成 3,1000g 变成 10,等等...)//从克中删除 'g'//将字符串转换为整数$chosen_weight = (int) str_replace('00', '', str_replace('g', '', $cart_item['steak_option']));//获取当前价格$current_price = $cart_item['data']->get_price();//设置新的价格,每 100g 的价格是已知的$cart_item['data']->set_price( $current_price * $chosen_weight );}}}add_action('wp_footer','add_footer_steak_script');函数 add_footer_steak_script() {全球 $woocommerce, $product;?><script type="text/javascript">jQuery(document).ready(function ($) {console.log('JS 有效!');var price = get_price();?>,currency = '<?php echo get_woocommerce_currency_symbol();?>';$( '[name=steak_custom_options]' ).change(function(){如果 (!(this.value <1)) {var dropdown_val = this.value;var remove_g = dropdown_val.replace('g', '');var remove_double_zero = remove_g.replace('00', '');var product_total = parseFloat( price * remove_double_zero );$( '.woocommerce-Price-amount' ).html(货币 + product_total.toFixed(2));}});});<?php}

我还使用了一个代码,可以在将任何菜肴添加到购物车时自动添加包装.

/*** 根据购物车中的产品数量计算午餐盒和包装的数量.*/函数 add_delivery_charge_to_cart( $cart ) {if ( is_admin() && !defined( 'DOING_AJAX' ) )返回;if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )返回;/********** 设置 **********/$lunchbox_id = 5737;//午餐盒ID"要添加到购物车$pakket_id = 5738;//要添加到购物车的Pakket ID"$exclude_categories = array('drink', 'bread');//排除这些类别$category_qty_total = 0;//类别数量项目总数,请勿编辑!!/********** 通过购物车项目循环 **********/foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {//获取商品id$product_id = $cart_item['data']->get_id();//获取产品数量$product_qty = $cart_item['数量'];//检查LunchBox"产品是否已经在购物车中如果( $product_id == $lunchbox_id ){$lunchbox_key = $cart_item_key;$lunchbox_qty = $product_qty;}//检查Pakket"产品是否已经在购物车中如果( $product_id == $pakket_id ){$pakket_key = $cart_item_key;$pakket_qty = $product_qty;}//检查产品是否属于某个类别if( has_term( $exclude_categories, 'product_cat', $product_id ) ) {$category_qty_total += $product_qty;}}/********** 计算总数,所以午餐盒"、包"&类别未在总数中使用 **********///获取购物车中的商品总数,计算产品数量 &每个产品的数量$total_items_in_cart = $cart->get_cart_contents_count();//购物车中的商品总数 - 类别数量总计$total_items_in_cart -= $category_qty_total;//午餐盒总数 = total_items_in_cart &包裹总数 = total_items_in_cart$lunchbox_total = $total_items_in_cart;$pakket_total = $total_items_in_cart;//Isset 午餐盒数量 ->午餐盒总数 - 午餐盒数量和一揽子总包 - 午餐盒数量如果 ( isset($lunchbox_qty) ) {$lunchbox_total -= $lunchbox_qty;$pakket_total -= $lunchbox_qty;}//Isset 包数量 ->午餐盒总数 - 包装数量和包裹总数 - 包裹数量如果 ( isset($pakket_qty) ) {$lunchbox_total -= $pakket_qty;$pakket_total = $pakket_total - $pakket_qty;}/********** 将新的总数应用到午餐盒 &包裹************///如果产品LunchBox"在购物车中,我们会检查数量以在需要时更新它如果 ( isset($lunchbox_key) && $lunchbox_qty != $total_items_in_cart ) {//设置数量,饭盒$cart->set_quantity( $lunchbox_key, $lunchbox_total );} elseif ( !isset($lunchbox_key) && $total_items_in_cart > 0 ) {//产品午餐盒"不在购物车中,我们添加它$cart->add_to_cart( $lunchbox_id, $total_items_in_cart );}//购物车中的商品总数大于或等于 3如果($total_items_in_cart >= 3){//Pakket total = pakket_total/3 = floor(result)//Floor = 向下舍入分数,向下舍入结果$pakket_total = floor( $pakket_total/3 );//如果产品Pakket"在购物车中如果 ( isset($pakket_key) ) {//设置数量,包$cart->set_quantity( $pakket_key, $pakket_total );} elseif ( !isset($pakket_key) ) {//产品Pakket"不在购物车中,我们添加它$cart->add_to_cart( $pakket_id, $pakket_total );}}}add_action('woocommerce_before_calculate_totals', 'add_delivery_charge_to_cart', 10, 1);

不幸的是,这两个代码相互冲突,我不明白是什么原因.

  1. 如果添加了包装,选择商品重量时的总量不计算.
  2. 在购物车和结帐页面上,包裹中添加了牛排重量:300g"数据.这些数据不应该存在.

如何解决这个问题?我很乐意为您提供帮助!

解决方案

使用同一个 hook woocommerce_before_calculate_totals 两次确实会出问题,所以是将两个代码合并成一个函数的问题.

现在写的代码有一些条件

  • pakket_id &午餐盒_id 产品不得以任何其他方式使用!这些是自动添加的,因此您网站上的用户/访客无法添加
  • 属于排除类别的产品可能不包含带有下拉菜单的重量选项(包装和午餐盒产品的条件相同)
<小时><块引用>

注意:在这段代码中,我还添加了午餐盒 ID,否则您将收到有关午餐盒下重量的通知产品,在某些情况下.

//添加为自定义购物车项目数据函数 add_custom_steak_cart_item_data( $cart_item_data, $product_id, $variation_id, $quantity ) {if (!empty($_POST['steak_custom_options']) && $product_id != 5737 ) {...

<小时>

然后你得到

//显示自定义复选框字段函数牛排_custom_field_add() {全球 $post;//复选框woocommerce_wp_checkbox(大批('id' =>'_steak_checkbox','标签' =>__('牛排重量', 'woocommerce'),'说明' =>__( '如有必要,启用牛排重量选择', 'woocommerce' )));}add_action('woocommerce_product_options_general_product_data', 'steak_custom_field_add', 10, 0);//保存自定义复选框字段函数牛排_custom_field_save( $post_id ) {$product = wc_get_product( $post_id );//自定义产品复选框字段$steak_checkbox = isset( $_POST['_steak_checkbox'] ) ?是":否";//更新产品元数据$product->update_meta_data('_steak_checkbox', $steak_checkbox);//节省$product->save();}add_action('woocommerce_process_product_meta', 'steak_custom_field_save', 10, 1 );//显示自定义选择框函数 display_steak_custom_field() {全球 $post;//获取产品$product = wc_get_product( $post->ID );//如果是单个产品页面并且启用了steak_checkbox",我们将显示该字段if ( $product->get_meta( '_steak_checkbox' ) === 'yes' ) {echo '

';$select = woocommerce_form_field( 'steak_custom_options', array('类型' =>'选择','类' =>数组('我的牛排选择框表单行宽'),'标签' =>__('牛排重量'),'必需' =>错误的,'返回' =>错误的,'选项' =>大批('' =>'选择...','300g' =>'300克','400g' =>'400g','500g' =>'500g','600g' =>'600g','700g' =>'700g','800g' =>'800g','900g' =>'900g','1000g' =>'1000g')), '' );回声 $select;回声'</div>';}}add_action('woocommerce_before_add_to_cart_button', 'display_steak_custom_field', 10, 0);//将 jQuery 脚本添加到页脚 - 在单个产品页面上更改价格函数 add_footer_steak_script() {//在单个产品页面上返回 true如果 ( is_product() ) {全球 $woocommerce, $product;?><script type="text/javascript">jQuery(document).ready(function ($) {var price = get_price();?>,currency = '<?php echo get_woocommerce_currency_symbol();?>';$( '[name=steak_custom_options]' ).change(function(){如果 (!(this.value <1)) {var dropdown_val = this.value;var remove_g = dropdown_val.replace('g', '');var remove_double_zero = remove_g.replace('00', '');var product_total = parseFloat( price * remove_double_zero );$( '.woocommerce-Price-amount' ).html(货币 + product_total.toFixed(2));}});});<?php}}add_action('wp_footer','add_footer_steak_script', 10, 0 );//添加为自定义购物车项目数据函数 add_custom_steak_cart_item_data( $cart_item_data, $product_id, $variation_id, $quantity ) {if (!empty($_POST['steak_custom_options']) && $product_id != 5737 ) {$cart_item_data['steak_option'] = $_POST['steak_custom_options'];}返回 $cart_item_data;}add_filter( 'woocommerce_add_cart_item_data', 'add_custom_steak_cart_item_data', 10, 4 );//在购物车中的购物车项目名称下添加自定义字段值函数牛排_custom_field_add_cart( $item_name, $cart_item, $cart_item_key ) {如果( is_cart() ) {if( isset( $cart_item['steak_option'] ) ) {$item_name .= '<div class="my-steak-class"><strong>'.__("牛排重量", "woocommerce") .':' .$cart_item['steak_option'] .'</div>';}}返回 $item_name;}add_filter('woocommerce_cart_item_name', 'steak_custom_field_add_cart', 10, 3);/*** 根据购物车中的产品数量计算午餐盒和包装的数量.*/函数 add_delivery_charge_to_cart( $cart ) {if ( is_admin() && !defined( 'DOING_AJAX' ) )返回;if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )返回;/********** 设置 **********/$lunchbox_id = 5737;//午餐盒ID"要添加到购物车$pakket_id = 5738;//要添加到购物车的Pakket ID"$exclude_categories = array('drink', 'bread');//排除这些类别$category_qty_total = 0;//类别数量项目总数,请勿编辑!!/********** 通过购物车项目循环 **********/foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {//获取商品id$product_id = $cart_item['data']->get_id();//获取产品数量$product_qty = $cart_item['数量'];//检查LunchBox"产品是否已经在购物车中如果( $product_id == $lunchbox_id ){$lunchbox_key = $cart_item_key;$lunchbox_qty = $product_qty;}//检查Pakket"产品是否已经在购物车中如果( $product_id == $pakket_id ){$pakket_key = $cart_item_key;$pakket_qty = $product_qty;}//检查产品是否属于某个类别if( has_term( $exclude_categories, 'product_cat', $product_id ) ) {$category_qty_total += $product_qty;}//检查产品是否包含牛排重量if( isset( $cart_item['steak_option'] ) ) {//删除最后 2 个零(100g 变成 1,300g 变成 3,1000g 变成 10,等等...)//从克中删除 'g'//将字符串转换为整数$chosen_weight = (int) str_replace('00', '', str_replace('g', '', $cart_item['steak_option']));//获取当前价格$current_price = $cart_item['data']->get_price();//设置新价格,每 100g 价格已知$cart_item['data']->set_price( $current_price * $chosen_weight );}}/********** 计算总数,所以午餐盒"、包"&类别未在总数中使用 **********///获取购物车中的商品总数,计算产品数量 &每个产品的数量$total_items_in_cart = $cart->get_cart_contents_count();//购物车中的商品总数 - 类别数量总计$total_items_in_cart -= $category_qty_total;//午餐盒总数 = total_items_in_cart &包裹总数 = total_items_in_cart$lunchbox_total = $total_items_in_cart;$pakket_total = $total_items_in_cart;//Isset 午餐盒数量 ->午餐盒总数 - 午餐盒数量和一揽子总包 - 午餐盒数量如果 ( isset($lunchbox_qty) ) {$lunchbox_total -= $lunchbox_qty;$pakket_total -= $lunchbox_qty;}//Isset 包数量 ->午餐盒总数 - 包装数量和包裹总数 - 包裹数量如果 ( isset($pakket_qty) ) {$lunchbox_total -= $pakket_qty;$pakket_total = $pakket_total - $pakket_qty;}/********** 将新的总数应用到午餐盒 &包裹************///如果产品LunchBox"在购物车中,我们会检查数量以在需要时更新它如果 ( isset($lunchbox_key) && $lunchbox_qty != $total_items_in_cart ) {//设置数量,饭盒$cart->set_quantity( $lunchbox_key, $lunchbox_total );} elseif ( !isset($lunchbox_key) && $total_items_in_cart > 0 ) {//产品午餐盒"不在购物车中,我们添加它$cart->add_to_cart( $lunchbox_id, $total_items_in_cart );}//购物车中的商品总数大于或等于 3如果($total_items_in_cart >= 3){//Pakket total = pakket_total/3 = floor(result)//Floor = 向下舍入分数,向下舍入结果$pakket_total = floor( $pakket_total/3 );//如果产品Pakket"在购物车中如果 ( isset($pakket_key) ) {//设置数量,包$cart->set_quantity( $pakket_key, $pakket_total );} elseif ( !isset($pakket_key) ) {//产品Pakket"不在购物车中,我们添加它$cart->add_to_cart( $pakket_id, $pakket_total );}}}add_action('woocommerce_before_calculate_totals', 'add_delivery_charge_to_cart', 10, 1);//在结帐时显示项目名称下的自定义字段值函数牛排_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {if( isset($cart_item['steak_option']) ) {$item_qty .= '<div class="my-steak-class"><strong>'.__("牛排重量", "woocommerce") .':' .$cart_item['steak_option'] .'гр.</div>';}返回 $item_qty;}add_filter('woocommerce_checkout_cart_item_quantity', 'steak_custom_checkout_cart_item_name', 10, 3);//将选择的选择字段值保存到每个订单项作为自定义元数据并在任何地方显示函数 save_order_item_steak_field( $item, $cart_item_key, $values, $order ) {if( isset($values['steak_option']) ) {$key = __('牛排重量', 'woocommerce');$value = $values['steak_option'];$item->update_meta_data( $key, $value ,$item->get_id());}}add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_steak_field', 10, 4 );

In WooCommerce, I use a code that shows the steak weight selection form, saves the selection data and displays this data in the cart, on the checkout page, when editing the order and in email notifications.

// Display Custom Checkbox Field
add_action('woocommerce_product_options_general_product_data', 'steak_custom_field_add');
function steak_custom_field_add(){
    global $post;

    // Checkbox
    woocommerce_wp_checkbox(
        array(
            'id' => '_steak_checkbox',
            'label' => __('Steak Weight', 'woocommerce' ),
            'description' => __( 'If necessary, enable steak weight selection', 'woocommerce' )
        )
    );
}

// Save Custom Checkbox Field
add_action('woocommerce_process_product_meta', 'steak_custom_field_save');
function steak_custom_field_save($post_id){
    // Custom Product Checkbox Field
    $steak_checkbox = isset( $_POST['_steak_checkbox'] ) ? 'yes' : 'no';
    update_post_meta($post_id, '_steak_checkbox', esc_attr( $steak_checkbox ));
}

// Display Custom Select Box
add_action( 'woocommerce_before_add_to_cart_button', 'display_steak_custom_field', 0 );
function display_steak_custom_field() {
    global $product;

    // If is single product page and have the "steak_checkbox" enabled we display the field
    if ( $product->get_meta( '_steak_checkbox' ) === 'yes' ) {

        echo '<div class="steak_select_box">';

        $select = woocommerce_form_field( 'steak_custom_options', array(
            'type'          => 'select',
            'class'         => array('my-steak-select-box form-row-wide'),
            'label'         => __('Steak Weight'),
            'required'      => false,
            'return'       => false,
            'options'   => array(
                ''      => 'Select...',
                '300g'  => '300g',
                '400g'  => '400g',
                '500g'  => '500g',
                '600g'  => '600g',
                '700g'  => '700g',
                '800g'  => '800g',
                '900g'  => '900g',
                '1000g'  => '1000g'
            )
        ), '' );
        echo $select;
        echo '</div>';
    }
}

// Add as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_steak_cart_item_data', 10, 21 );
function add_custom_steak_cart_item_data($cart_item_data, $product_id, $variation_id ){

    if( isset( $_POST['steak_custom_options'] ) ) {
        $cart_item_data['steak_option'] = wc_clean( $_POST['steak_custom_options'] );
    }
    return $cart_item_data;
}

// Add custom fields values under cart item name in cart
add_filter( 'woocommerce_cart_item_name', 'steak_custom_field_add_cart', 10, 21 );
function steak_custom_field_add_cart( $item_name, $cart_item, $cart_item_key ) {
    if( ! is_cart() )
        return $item_name;

    if( isset($cart_item['steak_option']) ) {
        $item_name .= '<div class="my-steak-class"><strong>' . __("Steak Weight", "woocommerce") . ':</strong> ' . $cart_item['steak_option'] . '</div>';
    }
    return $item_name;
}

// Display custom fields values under item name in checkout
add_filter( 'woocommerce_checkout_cart_item_quantity', 'steak_custom_checkout_cart_item_name', 10, 21 );
function steak_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {
    if( isset($cart_item['steak_option']) ) {
        $item_qty .= '<div class="my-steak-class"><strong>' . __("Steak Weight", "woocommerce") . ':</strong> ' . $cart_item['steak_option'] . 'гр.</div>';
    }
    return $item_qty;
}


// Save chosen select field value to each order item as custom meta data and display it everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_steak_field', 10, 21 );
function save_order_item_steak_field( $item, $cart_item_key, $values, $order ) {
    if( isset($values['steak_option']) ) {
        $key = __('Steak Weight', 'woocommerce');
        $value = $values['steak_option'];
        $item->update_meta_data( $key, $value ,$item->get_id());
    }
}

add_action('wp_footer','add_footer_steak_script');
function add_footer_steak_script(){
    ?>
    <script>
       ( function( $ ) {
   $( document ).ready( function() {
       $(document).on('change', '#steak_custom_options' ,function() {
           $('.add_to_cart_button').data('steak_custom_options', this.value)
       });
   });
 }( jQuery ) );
    </script>
    <?php
}

add_action( 'woocommerce_before_calculate_totals', 'my_before_calculate_totals', 10, 1 );
    function my_before_calculate_totals( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {     
        if( isset( $cart_item['steak_option'] ) ) {

            // Remove the last 2 zeros (100g becomes 1, 300g becomes 3, 1000g becomes 10, etc...)
            // Remove 'g' from grams
            // convert string to integer
            $chosen_weight = (int) str_replace( '00', '', str_replace('g', '', $cart_item['steak_option']) );

            // Get current price
            $current_price = $cart_item['data']->get_price();

            // Set new price, price is already known per 100g
            $cart_item['data']->set_price( $current_price * $chosen_weight );
        }
    }
}

add_action('wp_footer','add_footer_steak_script');
    function add_footer_steak_script() {
    global $woocommerce, $product;
    ?>
    <script type="text/javascript">
        jQuery(document).ready(function ($) {
            console.log('JS works!');

            var price = <?php echo $product->get_price(); ?>, currency = '<?php echo get_woocommerce_currency_symbol(); ?>';

            $( '[name=steak_custom_options]' ).change(function(){
                if (!(this.value < 1)) {
                    var dropdown_val = this.value;
                    var remove_g = dropdown_val.replace( 'g', '' );
                    var remove_double_zero = remove_g.replace( '00', '' );

                    var product_total = parseFloat( price * remove_double_zero );

                    $( '.woocommerce-Price-amount' ).html( currency + product_total.toFixed(2));

                }
            });
        });
    </script>
    <?php
}

I also use a code that automatically adds packaging when adding any dish to the cart.

 /**
 * Calculate the number of lunchboxes and package, based on the number of products in cart.
 */ 
function add_delivery_charge_to_cart( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    /********** SETTINGS **********/

    $lunchbox_id  = 5737; // "LunchBox ID" to be added to cart
    $pakket_id = 5738; // "Pakket ID" to be added to cart
    $exclude_categories = array( 'drink', 'bread' ); // Exclude these categories

    $category_qty_total = 0; // Total of category quantity items, Don't edit!!

    /********** LOOP THROUGH CART ITEMS **********/

    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // Get product id
        $product_id = $cart_item['data']->get_id();

        // Get product quantity
        $product_qty = $cart_item['quantity'];

        // Check if "LunchBox" product is already in cart
        if( $product_id == $lunchbox_id ) {
            $lunchbox_key = $cart_item_key;
            $lunchbox_qty = $product_qty;
        }

        // Check if "Pakket" product is already in cart
        if( $product_id == $pakket_id ) {
            $pakket_key = $cart_item_key;
            $pakket_qty = $product_qty;
        }

        // Check if product belongs to a certain category
        if( has_term( $exclude_categories, 'product_cat', $product_id ) ) {
            $category_qty_total += $product_qty;
        }
    }

    /********** CALCULATE THE TOTALS, SO "LUNCHBOX", "PAKKET" & CATEGORIES ARE NOT USED IN THE TOTALS **********/

    // Get total items in cart, counts number of products & quantity per product
    $total_items_in_cart = $cart->get_cart_contents_count();

    // Total items in cart - category quantity total
    $total_items_in_cart -= $category_qty_total;

    // Lunchbox total = total_items_in_cart & pakket total = total_items_in_cart 
    $lunchbox_total = $total_items_in_cart;
    $pakket_total = $total_items_in_cart;

    // Isset lunchbox qty -> lunchbox total - lunchbox qty & pakket total - lunchbox qty
    if ( isset($lunchbox_qty) ) {
        $lunchbox_total -= $lunchbox_qty;
        $pakket_total -= $lunchbox_qty;     
    }

    // Isset pakket qty -> lunchbox total - pakket qty & pakket total - pakket qty   
    if ( isset($pakket_qty) ) {
        $lunchbox_total -= $pakket_qty;
        $pakket_total = $pakket_total - $pakket_qty;
    }

    /********** APPLY NEW TOTALS TO LUNCHBOX & PAKKET **********/

    // If product "LunchBox" is in cart, we check the quantity to update it if needed
    if ( isset($lunchbox_key) && $lunchbox_qty != $total_items_in_cart ) {
        // Set quantity, lunchbox
        $cart->set_quantity( $lunchbox_key, $lunchbox_total );

    } elseif ( !isset($lunchbox_key) && $total_items_in_cart > 0 ) {
        // Product "LunchBox" is not in cart, we add it
        $cart->add_to_cart( $lunchbox_id, $total_items_in_cart );
    }

    // Total items in cart greater than or equal to 3
    if ( $total_items_in_cart >= 3 ) {
        // Pakket total = pakket_total / 3 = floor(result)
        // Floor = round fractions down, rounding result down
        $pakket_total = floor( $pakket_total / 3 );

        // If product "Pakket" is in cart
        if ( isset($pakket_key) ) {
            // Set quantity, pakket
            $cart->set_quantity( $pakket_key, $pakket_total );

        } elseif ( !isset($pakket_key) ) {
            // Product "Pakket" is not in cart, we add it
            $cart->add_to_cart( $pakket_id, $pakket_total );
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'add_delivery_charge_to_cart', 10, 1 );

Unfortunately, these two codes conflict with each other and I cannot understand what is the reason.

  1. If the packaging is added, the total amount when choosing the weight of the product is not calculated.
  2. In the cart and on the checkout page, the data "Steak Weight: 300g" is added to the package. And this data should not be there.

How can this be fixed? I will be happy for your help!

解决方案

Using the same hook woocommerce_before_calculate_totals twice will indeed cause problems, so it is a matter of combining both codes into one function.

As the code is written now there are some conditions

  • pakket_id & lunchbox_id products may not be used in any other way! these are added automatically and therefore cannot be added by a user/guest on your website
  • products belonging to the excluded categories may not contain the weight option with dropdown menu (same condition for pakket & lunchbox product)

NOTE: With this piece of code I also added the lunchbox ID, otherwise you will receive a notification of the weight under the lunchbox product, in some cases.

// Add as custom cart item data
function add_custom_steak_cart_item_data( $cart_item_data, $product_id, $variation_id, $quantity ) {  
    if ( !empty( $_POST['steak_custom_options'] ) && $product_id != 5737 ) {
    ...


So then you get

// Display Custom Checkbox Field
function steak_custom_field_add() {
    global $post;

    // Checkbox
    woocommerce_wp_checkbox(
        array(
            'id' => '_steak_checkbox',
            'label' => __('Steak Weight', 'woocommerce' ),
            'description' => __( 'If necessary, enable steak weight selection', 'woocommerce' )
        )
    );
}
add_action('woocommerce_product_options_general_product_data', 'steak_custom_field_add', 10, 0 );

// Save Custom Checkbox Field
function steak_custom_field_save( $post_id ) {
    $product = wc_get_product( $post_id );

    // Custom Product Checkbox Field
    $steak_checkbox = isset( $_POST['_steak_checkbox'] ) ? 'yes' : 'no';

    // Update product meta
    $product->update_meta_data( '_steak_checkbox', $steak_checkbox );

    // Save
    $product->save();
}
add_action('woocommerce_process_product_meta', 'steak_custom_field_save', 10, 1 );

// Display Custom Select Box
function display_steak_custom_field() {
    global $post;

    // Get product
    $product = wc_get_product( $post->ID );

    // If is single product page and have the "steak_checkbox" enabled we display the field
    if ( $product->get_meta( '_steak_checkbox' ) === 'yes' ) {

        echo '<div class="steak_select_box">';

        $select = woocommerce_form_field( 'steak_custom_options', array(
            'type'          => 'select',
            'class'         => array('my-steak-select-box form-row-wide'),
            'label'         => __('Steak Weight'),
            'required'      => false,
            'return'       => false,
            'options'   => array(
                ''      => 'Select...',
                '300g'  => '300g',
                '400g'  => '400g',
                '500g'  => '500g',
                '600g'  => '600g',
                '700g'  => '700g',
                '800g'  => '800g',
                '900g'  => '900g',
                '1000g'  => '1000g'
            )
        ), '' );
        echo $select;
        echo '</div>';
    }
}
add_action( 'woocommerce_before_add_to_cart_button', 'display_steak_custom_field', 10, 0 );

// Add jQuery script to footer - change price on single product page
function add_footer_steak_script() {
    // Returns true on a single product page
    if ( is_product() ) {
        global $woocommerce, $product;
        ?>
        <script type="text/javascript">
            jQuery(document).ready(function ($) {
                var price = <?php echo $product->get_price(); ?>, currency = '<?php echo get_woocommerce_currency_symbol(); ?>';

                $( '[name=steak_custom_options]' ).change(function(){
                    if (!(this.value < 1)) {
                        var dropdown_val = this.value;
                        var remove_g = dropdown_val.replace( 'g', '' );
                        var remove_double_zero = remove_g.replace( '00', '' );

                        var product_total = parseFloat( price * remove_double_zero );

                        $( '.woocommerce-Price-amount' ).html( currency + product_total.toFixed(2));

                    }
                });
            });
        </script>
        <?php
    }
}
add_action('wp_footer','add_footer_steak_script', 10, 0 );

// Add as custom cart item data
function add_custom_steak_cart_item_data( $cart_item_data, $product_id, $variation_id, $quantity ) {    
    if ( !empty( $_POST['steak_custom_options'] ) && $product_id != 5737 ) {
        $cart_item_data['steak_option'] = $_POST['steak_custom_options'];
    }

    return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_steak_cart_item_data', 10, 4 );

// Add custom fields values under cart item name in cart
function steak_custom_field_add_cart( $item_name, $cart_item, $cart_item_key ) {    
    if( is_cart() ) {
        if( isset( $cart_item['steak_option'] ) ) {
            $item_name .= '<div class="my-steak-class"><strong>' . __("Steak Weight", "woocommerce") . ':</strong> ' . $cart_item['steak_option'] . '</div>';
        }
    }

    return $item_name;
}
add_filter( 'woocommerce_cart_item_name', 'steak_custom_field_add_cart', 10, 3 );

/**
 * Calculate the number of lunchboxes and package, based on the number of products in cart.
 */
function add_delivery_charge_to_cart( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    /********** SETTINGS **********/

    $lunchbox_id  = 5737; // "LunchBox ID" to be added to cart
    $pakket_id = 5738; // "Pakket ID" to be added to cart
    $exclude_categories = array( 'drink', 'bread' ); // Exclude these categories

    $category_qty_total = 0; // Total of category quantity items, Don't edit!!

    /********** LOOP THROUGH CART ITEMS **********/

    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {     
        // Get product id
        $product_id = $cart_item['data']->get_id();

        // Get product quantity
        $product_qty = $cart_item['quantity'];

        // Check if "LunchBox" product is already in cart
        if( $product_id == $lunchbox_id ) {
            $lunchbox_key = $cart_item_key;
            $lunchbox_qty = $product_qty;
        }

        // Check if "Pakket" product is already in cart
        if( $product_id == $pakket_id ) {
            $pakket_key = $cart_item_key;
            $pakket_qty = $product_qty;
        }

        // Check if product belongs to a certain category
        if( has_term( $exclude_categories, 'product_cat', $product_id ) ) {
            $category_qty_total += $product_qty;
        }

        // Check if product, contains steak weight
        if( isset( $cart_item['steak_option'] ) ) {
            // Remove the last 2 zeros (100g becomes 1, 300g becomes 3, 1000g becomes 10, etc...)
            // Remove 'g' from grams
            // convert string to integer
            $chosen_weight = (int) str_replace( '00', '', str_replace('g', '', $cart_item['steak_option']) );

            // Get current price
            $current_price = $cart_item['data']->get_price();

            // Set new price, price is already known per 100g
            $cart_item['data']->set_price( $current_price * $chosen_weight );
        }
    }

    /********** CALCULATE THE TOTALS, SO "LUNCHBOX", "PAKKET" & CATEGORIES ARE NOT USED IN THE TOTALS **********/

    // Get total items in cart, counts number of products & quantity per product
    $total_items_in_cart = $cart->get_cart_contents_count();

    // Total items in cart - category quantity total
    $total_items_in_cart -= $category_qty_total;

    // Lunchbox total = total_items_in_cart & pakket total = total_items_in_cart 
    $lunchbox_total = $total_items_in_cart;
    $pakket_total = $total_items_in_cart;

    // Isset lunchbox qty -> lunchbox total - lunchbox qty & pakket total - lunchbox qty
    if ( isset($lunchbox_qty) ) {
        $lunchbox_total -= $lunchbox_qty;
        $pakket_total -= $lunchbox_qty;     
    }

    // Isset pakket qty -> lunchbox total - pakket qty & pakket total - pakket qty   
    if ( isset($pakket_qty) ) {
        $lunchbox_total -= $pakket_qty;
        $pakket_total = $pakket_total - $pakket_qty;
    }

    /********** APPLY NEW TOTALS TO LUNCHBOX & PAKKET **********/

    // If product "LunchBox" is in cart, we check the quantity to update it if needed
    if ( isset($lunchbox_key) && $lunchbox_qty != $total_items_in_cart ) {
        // Set quantity, lunchbox
        $cart->set_quantity( $lunchbox_key, $lunchbox_total );

    } elseif ( !isset($lunchbox_key) && $total_items_in_cart > 0 ) {
        // Product "LunchBox" is not in cart, we add it
        $cart->add_to_cart( $lunchbox_id, $total_items_in_cart );
    }

    // Total items in cart greater than or equal to 3
    if ( $total_items_in_cart >= 3 ) {
        // Pakket total = pakket_total / 3 = floor(result)
        // Floor = round fractions down, rounding result down
        $pakket_total = floor( $pakket_total / 3 );

        // If product "Pakket" is in cart
        if ( isset($pakket_key) ) {
            // Set quantity, pakket
            $cart->set_quantity( $pakket_key, $pakket_total );

        } elseif ( !isset($pakket_key) ) {
            // Product "Pakket" is not in cart, we add it
            $cart->add_to_cart( $pakket_id, $pakket_total );
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'add_delivery_charge_to_cart', 10, 1 );

// Display custom fields values under item name in checkout
function steak_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {    
    if( isset($cart_item['steak_option']) ) {
        $item_qty .= '<div class="my-steak-class"><strong>' . __("Steak Weight", "woocommerce") . ':</strong> ' . $cart_item['steak_option'] . 'гр.</div>';
    }
    return $item_qty;
}
add_filter( 'woocommerce_checkout_cart_item_quantity', 'steak_custom_checkout_cart_item_name', 10, 3 );

// Save chosen select field value to each order item as custom meta data and display it everywhere
function save_order_item_steak_field( $item, $cart_item_key, $values, $order ) {
    if( isset($values['steak_option']) ) {
        $key = __('Steak Weight', 'woocommerce');
        $value = $values['steak_option'];
        $item->update_meta_data( $key, $value ,$item->get_id());
    }
}
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_steak_field', 10, 4 );

这篇关于如果在WooCommerce中自动添加包装,则在选择产品重量时不计算最终成本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆