【问题标题】:Woocommerce: Store incremental order number, per variationWoocommerce:存储增量订单号,每个变体
【发布时间】:2017-11-04 08:15:53
【问题描述】:

我们正在建立一个商店,其中每种产品都有三种变体(小型、中型和大型)。每个产品的每个变体都有有限的库存 - 100 小号,35 中号,15 大号。因为产品是限量版,我们希望能够存储客户的订单号——即original quantity - new quantity。例如,如果某人是第一个购买产品 A 的小型变体的人,他们的号码将是 1。下一个购买产品 A 小型变体的人将是编号 2,依此类推,一直到100,之后小型变体将不再出售。

这是我目前所拥有的,与woocommerce_checkout_update_order_meta 挂钩:

// Generate order number
    $order = wc_get_order( $order_id );
    // Getting the items in the order
    $order_items = $order->get_items();
    // Iterating through each item in the order
    foreach ($order_items as $item_id => $item_data) {
        $product = wc_get_product($item_data['product_id']);
        $total = get_post_meta($product->id, 'total_sales', true);
        $quantity = $product->get_stock_quantity();
        $max = $total + $quantity;
        $number = $max - $quantity;
        $name = $item_data['name'];

        update_post_meta( $order_id, $name.' - Print Number', $number);
    }

但是,这不能正常工作,因为total_sales 字段不跟踪变化;相反,它指的是给定产品的任何变体的总销售额。

所以我需要做的是想出一种方法来跟踪每个变体的原始库存,然后在订单完成时从原始库存中减去当前的变体数量。有人对实现这一点有任何建议吗?我希望自动计算这个,这样我们就不必为每个订单花费额外的时间来手动计算。

【问题讨论】:

    标签: php wordpress woocommerce


    【解决方案1】:

    您可以为每个产品变体添加两个自定义字段: 1.原始产品数量:您将减去的数量 2. 总销量:当前销量

    这些将允许您跟踪每个变体的数量和销售额。

    将数字添加到订单或订单项元数据: 1. 例如,您可以通过在元字段前加上产品 ID 来将数量作为一个整体添加到订单中。使用woocommerce_checkout_update_order_meta:

    add_action( 'woocommerce_checkout_update_order_meta', 'prefix_add_order_meta', 10, 2 );
    function prefix_add_order_meta( $order_id, $data ) {
        // Generate order number
        $order = wc_get_order( $order_id );
    
        // Getting the items in the order
        $order_items = $order->get_items();
    
        /**
         * @var WC_Order_Item_Product $item_data
         */
        foreach ( $order_items as $item_id => $item_data ) {
            $product     = $item_data->get_product();
            $total_sales = (int) get_post_meta( $product->get_id(), 'custom_total_sales', true );
    
            $item_number = $total_sales + 1;
    
            // Add to order meta
            $order->add_meta_data( $product->get_id() . '_print_number', wc_clean( $item_number ), true );
            $order->save();
    
            // Add to order item meta. You can set this here or use the 'woocommerce_checkout_create_order_line_item'
            $item_data->add_meta_data( 'print_number', wc_clean( $item_number ), true );
            $item_data->save();
    
            // Save total to product
            $product->add_meta_data( 'custom_total_sales', wc_clean( $item_number ), true );
            $product->save();
        }
    }
    
    1. 您可以使用'woocommerce_checkout_create_order_line_item' 将元数据添加到订单项。无需前缀,因为商品本身就是商品

    这是一个例子:

        add_action( 'woocommerce_checkout_create_order_line_item', 'prefix_add_order_item_meta', 10, 4 );
    function prefix_add_order_item_meta( $item, $cart_item_key, $values, $order ) {
        $product     = $item->get_product();
        $total_sales = (int) get_post_meta( $product->get_id(), 'custom_total_sales', true );
    
        $item_number = $total_sales + 1;
    
        // Add to order item meta. No need to save here
        $item->add_meta_data( 'print_number', wc_clean( $item_number ), true );
    }
    

    【讨论】:

    • 谢谢!这看起来很棒,我终于有时间测试它了。在完成一个新产品的订单后,订单元数据和订单项目元数据都被正确设置,打印编号为“1”。但是,当我转到产品页面时,自定义字段中没有“custom_total_sales” - 这是按变体处理的,如果是,是否有不同的区域来检查它是否正在设置?
    • 尝试使用 product->get_meta() 获取自定义字段。如果您销售的产品是变体,那么是的,元数据会保存到变体中。
    • 酷...所以在我完成测试并准备上线后,有没有办法通过 WordPress 管理员将变体的 custom_total_sales 重置为 0?
    • 您很可能需要自己编写一个脚本来重置它们。此外,与设置数字的方式相同,我们可以重置它们,编写一个函数并执行它。
    • 我最终对每个变体都有一个自定义字段,但没有您的回答我无法做到这一点,所以我将您的回答标记为解决方案。干杯
    【解决方案2】:

    VanboDevelops 的回答非常有帮助,因此我继续将其标记为已接受的答案。然而,我最终如何做到这一点有点不同。我希望能够轻松地编辑限量版号码,不仅是为了测试,而且在订单被取消并且我们需要回滚打印号码的情况下也是如此。所以对我来说,解决方案是为所有变体创建一个自定义字段,可以在价格、尺寸等旁边轻松编辑。这是我添加到functions.php 的内容:

    add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
    function variation_settings_fields( $loop, $variation_data, $variation ) {
        woocommerce_wp_text_input( 
            array( 
                'id'          => '_print_number[' . $variation->ID . ']', 
                'label'       => __( 'Print number (most recently sold)', 'woocommerce' ), 
                'desc_tip'    => 'true',
                'description' => __( 'The most recently-sold Print Number for this size and print. WARNING: This value plus 1 is used to show the user which print number they will be purchasing. Only update this value manually in specific situations, such as if an order is canceled and the print number needs to be offset.', 'woocommerce' ),
                'value'       => get_post_meta( $variation->ID, '_print_number', true ),
                'custom_attributes' => array(
                                'step'  => '1',
                                'min'   => '1'
                            ) 
            )
        );
    }
    add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
    function save_variation_settings_fields( $post_id ) {
        $number_field = $_POST['_print_number'][ $post_id ];
        if( !empty( $number_field ) || $number_field == 0 ) {
            update_post_meta( $post_id, '_print_number', esc_attr( $number_field ) );
        }
    }
    add_filter( 'woocommerce_available_variation', 'load_variation_settings_fields' );
    function load_variation_settings_fields( $variations ) {
        $variations['print_number'] = get_post_meta( $variations[ 'variation_id' ], '_print_number', true );
    
        return $variations;
    }
    add_action( 'woocommerce_checkout_update_order_meta', 'prefix_add_order_meta', 10, 2 );
    function prefix_add_order_meta( $order_id, $data ) {
        // Generate order number
        $order = wc_get_order( $order_id );
    
        // Getting the items in the order
        $order_items = $order->get_items();
    
        foreach ( $order_items as $item_id => $item_data ) {
            $product = $item_data->get_product();
            $product_id = $product->get_id();
    
            // Update print number
            $print_number = (int) get_post_meta( $product_id, '_print_number', true );
            $print_number += wc_clean( $item_data['qty'] );
            update_post_meta( $product_id, '_print_number', wc_clean( $print_number ) );
    
            // Add to order meta
            $order->add_meta_data( $product_id . '_print_number', wc_clean( $print_number ), true );
            $order->save();
        }
    }
    

    此解决方案还会考虑订单中是否包含多个选定的变体 - 例如,如果有人选择了同一张照片的 2 个小照片,则该变体的打印数量将相应增加 2。在这种情况下,订单元信息将仅显示最新的印刷编号,但通过查看数量和最终印刷编号,我们可以推断出要发货的编号。理想情况下,更强大的解决方案会在订单元数据中列出所有印刷编号,但我认为这将满足我们的需求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-05
      • 1970-01-01
      • 2018-01-27
      • 2017-07-20
      • 2018-03-17
      • 2014-02-03
      • 2021-11-03
      • 1970-01-01
      相关资源
      最近更新 更多