I have 500+ simple products in my woocommerce store. I am storing the cost of a "color" option as a custom field in each product (avp-ral-paint-price), and have a color attribute with the 30+ color options. I don't want to create variable products. All colors are the same cost for a specific product.
The following code (hooks and functions) creates a pulldown menu with the color options, gives an error if no option chosen, and puts the color as a line item in the cart, associated with the product added when hitting the add to cart function. It also shows above the add to cart button the cost of the color options.
What I can't figure out is how to give the line item with the color option a price that adds into the cart, changing the cart total. I would prefer to have the base price of the product displayed in the cart followed by the color price, but I could live with the price added to the product price first. I haven't found how to do either.
It seems I just need the right array key for cart_item_data, but nothing I've tried has worked.
// Display Select field before add to cart button
add_action( 'woocommerce_before_add_to_cart_button', 'colors_before_add_to_cart_button', 0 );
function colors_before_add_to_cart_button() {
global $product;
// Only on simple products
if( ! $product->is_type('simple') ) return;
// When product colors are available
if ( $colors = $product->get_attribute( 'color' ) ) :
$colors = explode(", ",$colors);
$required = ' <abbr class="required" title="required">*</abbr></label>';
echo 'Standard Powder Coat: $'. get_post_meta(get_the_ID(), 'avp-ral-paint-price', true) .'.00<br>';
echo '<p class="form-row form-row-wide" id="product-color-field">
<label for="product-color">' . __('Standard Colors:') . $required . '</label>
<select class="product-color" name="product-color" id="product-color">
<option value="">' . __("Choose your color") . '</option>';
foreach( $colors as $color ){
echo '<option value="' . $color . '">' . $color . '</option>';
}
echo '</select>
</p><br>';
endif;
}
add_filter( 'woocommerce_add_to_cart_validation', 'filter_add_to_cart_validation', 10, 4 );
function filter_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = 0 ) {
$product = wc_get_product($product_id);
// Only on simple products and When product colors are available
if( ! $product->is_type('simple') && ! $product->get_attribute( 'color' ) )
return $passed;
if( isset( $_POST['product-color'] ) && empty( $_POST['product-color'] ) ) {
wc_add_notice( __("Choose A Color (Mill for No Paint)", "woocommerce" ), 'error' );
$passed = false;
}
return $passed;
}
add_filter( 'woocommerce_add_cart_item_data', 'add_color_to_cart_item_data', 10, 3 );
function add_color_to_cart_item_data($cart_item_data, $product_id, $variation_id )
{
global $product;
if( isset( $_POST['product-color'] ) )
{
$cart_item_data['product-color'] = esc_attr( $_POST['product-color'] );
}
return $cart_item_data;
}
add_filter( 'woocommerce_get_item_data', 'display_color_on_cart_item', 10, 2 );
function display_color_on_cart_item( $cart_item_data, $cart_item ) {
if ( isset( $cart_item['product-color'] ) ){
$cart_item_data[] = array(
'name' => __('Color'),
'value' => $cart_item['product-color'],
);
}
return $cart_item_data;
}