1

I'm setting up California Redemption value fees for my site. The code that I have found on here works, however I would like for the different fees to be combined under the same name, which would just be "C.R.V." but still count the appropriate fees based on the different products in the cart. Example: One 5 Cent CRV item and one 10 Cent CRV item in the cart will currently be displayed on two separate lines. I would like an outcome of just "C.R.V. - 0.15c"

Currently Displayed as:

Using code from the answer to this page

Code that I am using:

function action_woocommerce_cart_calculate_fees( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // Settings (multiple settings arrays can be added/removed if desired)
    $settings = array(
        array(
            'product_id'    => array( 11891, 11893 ),
            'amount'        => 0.05,
            'name'          => __( '5 Cent C.R.V.', 'woocommerce' ),
            'total_amount'  => 0,
        ),
        array(
            'product_id'    => array( 11892 ),
            'amount'        => 0.10,
            'name'          => __( '10 Cent C.R.V.', 'woocommerce' ),
            'total_amount'  => 0,
        ),
        array(
            'product_id'    => array( 825 ),
            'amount'        => 0.20,
            'name'          => __( '20 Cent CRV', 'woocommerce' ),
            'total_amount'  => 0,
        ),
    );
    
    // Loop through cart contents
    foreach ( $cart->get_cart_contents() as $cart_item ) {      
        // Get product id
        $product_id = $cart_item['product_id'];
        
        // Get quantity
        $quantity = $cart_item['quantity'];
        
        // Loop trough settings array (determine total amount)
        foreach ( $settings as $key => $setting ) {
            // Search for the product ID
            if ( in_array( $product_id, $settings[$key]['product_id'] ) ) {
                // Addition
                $settings[$key]['total_amount'] += $setting['amount'] * $quantity;
            }
        }       
    }
    
    // Loop trough settings array (output)
    foreach ( $settings as $setting ) {
        // Greater than 0
        if ( $setting['total_amount'] > 0 ) {
            // Add fee
            $cart->add_fee( $setting['name'], $setting['total_amount'], false );    
        }
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );

I have tried renaming all of the fees to just "C.R.V." but then the cart will only display and count one fee. I apologize if this is very simple or staring at me in the face but I am extremely new to any sort of coding. Any help is very appreciated!

1 Answers1

3

If I have well understood, the following will apply a merged 'CRV' fee for defined products, based on your settings.

I have simplified your code, try:

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

    // Settings: amount / product Ids
    $settings = array(
        '0.05' => array( 11891, 11893 ),
        '0.1'  => array( 11892 ),
        '0.2'  => array( 825 ),
    );

    $total_amount = 0; // Initializing
    
    // Loop through cart items
    foreach ( $cart->get_cart() as $item ) {
        // Loop trough settings array
        foreach ( $settings as $amount => $product_ids ) {
            // Search for the product ID
            if ( in_array( $item['product_id'], $product_ids) ) {
                $total_amount += floatval($amount) * intval($item['quantity']); // Add to total amount
            }
        }
    }

    if ( $total_amount > 0 ) {
        $cart->add_fee( __( 'CRV', 'woocommerce' ), $total_amount, false ); 
    }
}

It should work.


Addition - Target with product Categories or Tags terms:

To target product categories or product tags, replace your in settings the product IDs arrays with desired term slugs arrays (for each array).

Then replace in the code:

if ( in_array( $item['product_id'], $product_ids) ) {

with (for product categories):

if ( has_term( $product_ids, 'product_cat', $item['product_id']) ) {

or (for product tags):

if ( has_term( $product_ids, 'product_tag', $item['product_id']) ) {
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Unfortunately, that did not work. It will not combine the fees when two different products are in the cart. Example: 5 Gatorades in the 0.10 Cent category and 1 Coke in the 5 Cent Category should total up to 55 Cents. However it is only showing 0.05 Cents. When 5 Gatorades are alone in the cart, we do get the desired fee. The issue is when two different products with different fees get added. It is only considering whichever array comes first in the code. – TryingHermosa17 Aug 31 '23 at 16:33
  • Oups! sorry there was an oversight on my code… I have updated and simplified my answer code.Try it, it will work now. – LoicTheAztec Aug 31 '23 at 17:10
  • Thank you! That worked. Just a quick question.. the final product will have thousands of product ids in this code, do you see that being an issue? – TryingHermosa17 Aug 31 '23 at 17:34
  • @TryingHermosa17 you could try targeting product categories, or tags, or just products in general. It depends if you are trying to apply this to only certain products or all products. – Richard Aug 31 '23 at 17:41
  • PHP should be able to handle that with ease. Now, you could use product custom fields (admin product setting), or set a custom taxonomy for it. You will see yourself, what is the best way. – LoicTheAztec Aug 31 '23 at 18:17
  • @Richard If I were to change it to target product tags, what would I change with the code? – TryingHermosa17 Sep 01 '23 at 18:31
  • 1
    I have added an addition to target product tags... – LoicTheAztec Sep 01 '23 at 23:36