简体   繁体   中英

Display a product custom field for variable products in WooCommerce email order items

I've added a Custom SKU in products to use for vendor SKU for order confirmation email. What I've created works only for simple products and not variable products.

Custom SKU,截图图片

I added this to the functions.php

function jk_add_custom_sku() {
    $args = array(
        'label' => __( 'Custom SKU', 'woocommerce' ),
        'placeholder' => __( 'Enter custom SKU here', 'woocommerce' ),
        'id' => 'jk_sku',
        'desc_tip' => true,
        'description' => __( 'This SKU is for internal use only.', 'woocommerce' ),
    );
    woocommerce_wp_text_input( $args );
}
add_action( 'woocommerce_product_options_sku', 'jk_add_custom_sku' );

function jk_save_custom_sku( $post_id ) {
    // grab the custom SKU from $_POST
    $custom_sku = isset( $_POST[ 'jk_sku' ] ) ? sanitize_text_field( $_POST[ 'jk_sku' ] ) : '';
    
    // grab the product
    $product = wc_get_product( $post_id );
    
    // save the custom SKU using WooCommerce built-in functions
    $product->update_meta_data( 'jk_sku', $custom_sku );
    $product->save();
}
add_action( 'woocommerce_process_product_meta', 'jk_save_custom_sku' );

Next I modified the email template email-order-items.php adding to the SKU section to check if Custom SKU exists.

<?php

// Show title/image etc.
if ( $show_image ) {
    echo wp_kses_post( apply_filters( 'woocommerce_order_item_thumbnail', $image, $item ) );
}

// Product name.
echo wp_kses_post( apply_filters( 'woocommerce_order_item_name', $item->get_name(), $item, false ) );

// SKU.
if ( $show_sku && $sku ) {
    echo wp_kses_post( ' (#' . $sku . ')' );
    // load the custom SKU
    $custom_sku = get_post_meta( $product->get_id(), 'jk_sku', true );
    if ( is_string( $custom_sku ) ) { // only show the custom SKU if it's set
        echo "<br>" . wp_kses_post( "Custom SKU: $custom_sku" ); // change this line if needed
    }
}

// allow other plugins to add additional product information here.
do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order, $plain_text );

wc_display_item_meta(
    $item,
    array(
        'label_before' => '<strong class="wc-item-meta-label" style="float: ' . esc_attr( $text_align ) . '; margin-' . esc_attr( $margin_side ) . ': .25em; clear: both">',
    )
);

// allow other plugins to add additional product information here.
do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order, $plain_text );

?>
</td>

The Custom SKU only shows up on the email for Simple products. I need it to work with Variable products. There is only one Custom SKU for each product not for each variable product.

I have revisited a bit your code and changed the meta key to _sku2 just like WooCommerce meta keys starting with an underscore:

add_action( 'woocommerce_product_options_sku', 'add_product_sku2_custom_field' );
function add_product_sku2_custom_field() {
    $field_key = '_sku2';

    woocommerce_wp_text_input( array(
        'id'          => $field_key,
        'label'       => __( 'Custom SKU', 'woocommerce' ),
        'placeholder' => __( 'Enter custom SKU here', 'woocommerce' ),
        'desc_tip'    => true,
        'description' => __( 'This SKU is for internal use only.', 'woocommerce' ),
    ) );
}

add_action( 'woocommerce_admin_process_product_object', 'save_product_sku2_custom_field_value' );
function save_product_sku2_custom_field_value( $product ) {
    $field_key = '_sku2';

    if ( isset($_POST[$field_key]) ) {
        $product->update_meta_data( $field_key, sanitize_text_field($_POST[$field_key]) );
    }
}

For product variations, you need to get the parent variable product to get a "Custom sku" displayed (see at the code at the end)

Now to enable an additional custom SKU to product variations of a variable product too, use the following:

add_action( 'woocommerce_variation_options_pricing', 'add_product_variation_sku2_custom_field', 10, 3 );
function add_product_variation_sku2_custom_field( $loop, $variation_data, $variation ){
    $field_key = '_sku2';

    woocommerce_wp_text_input( array(
        'id'          => $field_key.'['.$loop.']',
        'label'       => __( 'Custom SKU', 'woocommerce' ),
        'placeholder' => __( 'Enter custom SKU here', 'woocommerce' ),
        'desc_tip'    => true,
        'description' => __( 'This SKU is for internal use only.', 'woocommerce' ),
        'value'       => get_post_meta( $variation->ID, $field_key, true )
    ) );
}

add_action( 'woocommerce_save_product_variation', 'save_product_variation_sku2_custom_field_value', 10, 2 );
function save_product_variation_sku2_custom_field_value( $variation_id, $i ){
    $field_key = '_sku2';

    if( isset($_POST[$field_key][$i]) ){
        update_post_meta( $variation_id, $field_key, sanitize_text_field($_POST[$field_key][$i]) );
    }
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

And in your template custom code you will replace:

// SKU.
if ( $show_sku && $sku ) {
    echo wp_kses_post( ' (#' . $sku . ')' );
    // load the custom SKU
    $custom_sku = get_post_meta( $product->get_id(), 'jk_sku', true );
    if ( is_string( $custom_sku ) ) { // only show the custom SKU if it's set
        echo "<br>" . wp_kses_post( "Custom SKU: $custom_sku" ); // change this line if needed
    }
}

by the following (that will work for variable products or product variations) :

// SKU (and SKU2)
if ( $show_sku && $sku ) {
    echo wp_kses_post( ' (#' . $sku . ')' );
    // load the custom SKU
    $sku2 = $product->get_meta('_sku2');
    
    // For product variations with empty SKU (get the parent variable product SKU)
    if ( empty($sku2) && $product->is_type('variation') ) { 
        // Get parent variable product Id
        $parent_product_id = $product->get_parent_id(); 
        $parent_product    = wc_get_product($parent_product_id);
        $sku2              = $parent_product->get_meta('_sku2');
    }
    
    // only show the custom SKU if it's set (and product variation too)
    if ( ! empty($sku2) ) {
        echo "<br>" . wp_kses_post( sprintf( __("Custom SKU: %s", "woocommerce"), $sku2 ) ); // change this line if needed
    }
}

For product variations, if there is not any "custom sku", it will try to get the parent variable product "custom sku".

It should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM