【问题标题】:How to calculate Custom order total in WooCommerce edit order?如何在 WooCommerce 编辑订单中计算自定义订单总额?
【发布时间】:2021-07-24 09:56:48
【问题描述】:

目前,我正在开发一个 WooCommerce (5.2.2) 项目。我的客户希望在后端(不是为客户)中为预付款创建一个自定义输入字段,以便当我的客户收到客户的预付款(交付目的)时,他们可以手动添加并从后端自动调整订单总额。因此,我编写了一个代码并在发布元表中创建了一个自定义字段,并使用该元表值来计算总订单,它可以工作,但我必须刷新两次才能获得订单的总新值。这是我的代码,告诉我如何修复它-

add_action( 'manage_shop_order_posts_custom_column' ,  array(&$this,'add_custom_column_content'), 11, 2 );

add_action( 'woocommerce_admin_order_totals_after_discount', array(&$this, 'vp_add_sub_total'), 10, 1);

add_action( 'woocommerce_process_shop_order_meta', array(&$this, 'save_order_custom_field_meta_data'), 12, 2 );


// Output a custom editable field in backend edit order pages under general section
         function editable_order_custom_field( $order ){            
        
            // Get "Delivery Type" from meta data (not item meta data)
            $updated_advance_payment = $order->get_meta('_advance_payment');
        
            // Replace "Delivery Type" value by the meta data if it exist
            $advancePayment = $updated_advance_payment ? $updated_advance_payment : ( isset($item_value) ? $item_value : '');
        
            // Display the custom editable field
            woocommerce_wp_text_input( 
                array(
                    'id'            => 'advance_payment',
                    'label'         => __("Advance Payment:", "woocommerce"),
                    'value'         => $advancePayment,
                    'wrapper_class' => 'form-field-wide',
                )
            );
        }

// Save the custom editable field value as order meta data and update order item meta data  
        function save_order_custom_field_meta_data( $post_id, $post ){
            if( isset( $_POST[ 'advance_payment' ] )){
                update_post_meta( $post_id, '_advance_payment', sanitize_text_field( $_POST[ 'advance_payment' ] ) );

                // Update the existing item meta data
                if( isset( $_POST[ 'item_id_ref' ] ) ){
                    wc_update_order_item_meta( $_POST[ 'item_id_ref' ], 'Advance Payment', $_POST[ 'advance_payment' ] );
                }
            }
        }

//Display Advance Payment and calculate
        function vp_add_sub_total( $the_order ) {
            global $post, $the_order;
            if ( empty( $the_order ) || $the_order->get_id() !== $post->ID ) {
                $the_order = wc_get_order( $post->ID );
            }
            ?>
            
            <tr>
            <td class="label">Advance Payment:</td>
            <td width="1%"></td>
            <td class="total"><?php echo wc_price(get_post_meta($post->ID, "_advance_payment", true));?></td>
            </tr>
            
            <?php

            $getTotal = $the_order->get_total();

            $updateTotal = $getTotal - get_post_meta($post->ID, "_advance_payment", true);

            $the_order->set_total($updateTotal);

            $the_order->save();

        }

注意:我为此预付款创建了一个小插件。

参考视频链接:https://www.awesomescreenshot.com/video/3589010?key=b26b5951753bfdc8a969b53f526a36d1

【问题讨论】:

    标签: wordpress woocommerce


    【解决方案1】:

    你需要在显示之前计算Advance Payment。你可以使用woocommerce_admin_order_item_headers 动作钩子。

    add_action( 'woocommerce_admin_order_item_headers', 'calculate_advance_payment', 10, 1);
    add_action( 'woocommerce_admin_order_totals_after_discount', 'vp_add_sub_total', 10, 1);
    add_action( 'woocommerce_process_shop_order_meta', 'save_order_custom_field_meta_data', 12, 2 );
    add_action( 'woocommerce_admin_order_data_after_order_details', 'editable_order_custom_field' );
    
    // Output a custom editable field in backend edit order pages under general section
    function editable_order_custom_field( $order ){            
    
        // Get "Delivery Type" from meta data (not item meta data)
        $updated_advance_payment = $order->get_meta('_advance_payment');
    
        // Replace "Delivery Type" value by the meta data if it exist
        $advancePayment = $updated_advance_payment ? $updated_advance_payment : ( isset($item_value) ? $item_value : '');
    
        // Display the custom editable field
        woocommerce_wp_text_input( 
            array(
                'id'            => 'advance_payment',
                'label'         => __("Advance Payment:", "woocommerce"),
                'value'         => $advancePayment,
                'wrapper_class' => 'form-field-wide',
            )
        );
    }
    
    // Save the custom editable field value as order meta data and update order item meta data  
    function save_order_custom_field_meta_data( $post_id, $post ){
        if( isset( $_POST[ 'advance_payment' ] )){
            update_post_meta( $post_id, '_advance_payment', sanitize_text_field( $_POST[ 'advance_payment' ] ) );
    
            // Update the existing item meta data
            if( isset( $_POST[ 'item_id_ref' ] ) ){
                wc_update_order_item_meta( $_POST[ 'item_id_ref' ], 'Advance Payment', $_POST[ 'advance_payment' ] );
            }
        }
    }
    
    function calculate_advance_payment( $the_order ) {
        $getTotal = $the_order->get_total();
        $updateTotal = $getTotal - get_post_meta($the_order->get_id(), "_advance_payment", true);
        $the_order->set_total($updateTotal);
        $the_order->save();
    }
    
    function vp_add_sub_total( $the_order ) {
        global $post, $the_order; ?>
        <tr>
        <td class="label">Advance Payment:</td>
        <td width="1%"></td>
        <td class="total"><?php echo wc_price(get_post_meta($post->ID, "_advance_payment", true));?></td>
        </tr><?php
    }
    

    【讨论】:

      【解决方案2】:

      我一直在寻找这个解决方案。不幸的是,上面发布的解决方案给出了这个错误“不支持的操作数类型:字符串 - 字符串”。我使用var_dump($getTotal); var_dump( $advanced_payment); 来分析数据。由于它在字符串中添加 + 2 个数字,因此在变量 $variable 之前添加 (int)(float)。当数字包含小数时使用float。对整数使用(int)。示例:(int)$variable(float)$variable。这是一个帮助我的article。这是修改后的解决方案,没有出现错误并更新了订单总数。

      add_action( 'woocommerce_admin_order_item_headers', 'calculate_advance_payment', 10, 1);
      add_action( 'woocommerce_admin_order_totals_after_discount', 'vp_add_sub_total', 10, 1);
      add_action( 'woocommerce_process_shop_order_meta', 'save_order_custom_field_meta_data', 12, 2 );
      add_action( 'woocommerce_admin_order_data_after_order_details', 'editable_order_custom_field' );
      
      // Output a custom editable field in backend edit order pages under general section
      function editable_order_custom_field( $order ){            
          
          // Get "Delivery Type" from meta data (not item meta data)
          $updated_advance_payment = $order->get_meta('advance_payment');
      
          // Replace "Delivery Type" value by the meta data if it exist
          $advanced_payment = $updated_advance_payment ? $updated_advance_payment : ( isset($item_value) ? $item_value : '');
      
          // Display the custom editable field
          woocommerce_wp_text_input( 
              array(
                  'id'            => 'advance_payment',
                  'label'         => __("Advance Payment:", "woocommerce"),
                  'value'         => $advanced_payment,
                  'wrapper_class' => 'form-field-wide',
              )
          );
      }
      
      // Save the custom editable field value as order meta data and update order item meta data  
      function save_order_custom_field_meta_data( $post_id, $post ){
          //global $order;
          if( isset( $_POST[ 'advance_payment' ] )){
              update_post_meta( $post_id, 'advance_payment', sanitize_text_field( $_POST[ 'advance_payment' ] ) );
              
              // Update the existing item meta data
              if( isset( $_POST[ 'item_id_ref' ] ) ){
                  wc_update_order_item_meta( $_POST[ 'item_id_ref' ], 'Advance Payment', $_POST[ 'advance_payment' ] );
              }
          }
      }
      
      function calculate_advance_payment( $order ) {
          $order_id = $order->get_id();
          $getTotal = $order->get_total();
          $advanced_payment = get_post_meta($order_id, 'advance_payment', true);
          $order_total = (float)$getTotal - (float)$advanced_payment;
          $order->set_total( $order_total );
          $order->save();
      }
      
      function vp_add_sub_total( $order ) {
          global $post, $order; 
      ?>
          <tr>
          <td class="label">Advance Payment:</td>
          <td width="1%"></td>
          <td class="total"><?php echo wc_price(get_post_meta($post->ID, "advance_payment", true));?></td>
          </tr><?php
      }
      

      【讨论】:

        猜你喜欢
        • 2021-11-23
        • 2017-03-14
        • 2020-09-01
        • 2016-02-18
        • 2021-04-11
        • 1970-01-01
        • 1970-01-01
        • 2021-04-03
        • 1970-01-01
        相关资源
        最近更新 更多