awesomemotive / easy-digital-downloads

Sell digital downloads through WordPress
https://easydigitaldownloads.com
GNU General Public License v2.0
868 stars 473 forks source link

Fees class does not allow duplicate "labels" #7837

Open arraypress opened 4 years ago

arraypress commented 4 years ago

Bug Report

Expected behavior

When using the fees class to add negative fees on a per-cart item basis, a very strange issue arises where fees are not applied if a duplicate label is used. This also happens in Simple Shipping if you have two products with the same name (since it pulls the title and won't apply the fee correctly).

The first item will be applied, but later items are not. Each "fee" has a unique key, so the key isn't the issue. Walking through the fees class code, everything "works" as expected and I couldn't clearly see the reason why this is not working.

I am adding fees as follows (within a foreach loop of the cart items):

$fee_label    = sprintf( __( '%s Discount', 'edd-simple-shipping' ), get_the_title( $cart_item['id'] ) );

EDD()->fees->add_fee( array(
'amount'            => eddcd_get_fee_amount( $fee_amount ),
'label'             => $fee_label,
'id'                => 'cd_' . $cart_index,
'download_id'   => $download_id,
'price_id'      => $price_id,
'no_tax'            => true,
) );

Actual behavior

The first fee is applied correctly, later fees are not if the title/label matches.

Information (if a specific version is affected):

PHP Version: 7.3

EDD Version (or branch): 2.9.23

WordPress Version: 5.4

Any other relevant information:

arraypress commented 4 years ago

For the sake of clarity, here are what the arrays look like when it works properly (unique labels):

Array
(
    [name] => Calendar Feeds 4
    [id] => 1112
    [item_number] => Array
        (
            [id] => 1112
            [options] => Array
                (
                    [price_id] => 1
                )

            [quantity] => 1
        )

    [item_price] => 12
    [quantity] => 1
    [discount] => 0
    [subtotal] => 6
    [tax] => 0
    [fees] => Array
        (
            [cd_0] => Array
                (
                    [amount] => -6.00
                    [label] => Calendar Feeds 4 Discount
                    [no_tax] => 1
                    [type] => fee
                    [download_id] => 1112
                    [price_id] => 1
                )

        )

    [price] => 6
)
Array
(
    [name] => Calendar Feeds 8
    [id] => 1120
    [item_number] => Array
        (
            [id] => 1120
            [options] => Array
                (
                    [price_id] => 1
                )

            [quantity] => 1
        )

    [item_price] => 12
    [quantity] => 1
    [discount] => 0
    [subtotal] => 6
    [tax] => 0
    [fees] => Array
        (
            [cd_1] => Array
                (
                    [amount] => -6.00
                    [label] => Calendar Feeds 8 Discount
                    [no_tax] => 1
                    [type] => fee
                    [download_id] => 1120
                    [price_id] => 1
                )

        )

    [price] => 6
)
arraypress commented 4 years ago

This is what happens to the second item if the labels are the same:

Array
(
    [name] => Calendar Feeds 4
    [id] => 1120
    [item_number] => Array
        (
            [id] => 1120
            [options] => Array
                (
                    [price_id] => 1
                )

            [quantity] => 1
        )

    [item_price] => 12
    [quantity] => 1
    [discount] => 0
    [subtotal] => 12
    [tax] => 0
    [fees] => Array
        (
        )

    [price] => 12
)