mollie / PrestaShop

iDEAL, Creditcard, Bancontact, SOFORT, Bank transfer, PayPal & paysafecard for Prestashop
http://www.mollie.com
BSD 2-Clause "Simplified" License
69 stars 43 forks source link

compositeRoundingInaccuracies function issues #973

Closed mariuszsienkiewicz closed 1 week ago

mariuszsienkiewicz commented 2 months ago

There is an issue with how rounding inaccuracies are handled. The compositeRoundingInaccuracies function has some logical issues when a discount is applied to the cart. We have noticed this issue because Klarna didn't want to accept some of the orders.

Below is a function that handles these inaccuracies more effectively:

private function compositeRoundingInaccuracies($remaining, $apiRoundingPrecision, $orderLines)
{
    $remaining = round($remaining, $apiRoundingPrecision);

    if ($remaining < 0) {
        foreach (array_reverse($orderLines) as $hash => $items) {
            // Grab the line group's total amount
            $totalAmount = array_sum(array_column($items, 'totalAmount'));

            // Remove when total is lower than remaining
            if ($totalAmount > 0 && $totalAmount <= abs($remaining)) {
                // The line total is less than remaining, we should remove this line group and continue
                $remaining = $remaining + $totalAmount;
                unset($items);
                continue;
            }

            // Otherwise spread the cart line again with the updated total
            //TODO: check why remaining comes -100 when testing and new total becomes different
            $orderLines[$hash] = static::spreadCartLineGroup($items, $totalAmount + $remaining);
            break;
        }
    } elseif ($remaining > 0) {
        foreach (array_reverse($orderLines) as $hash => $items) {
            // Grab the line group's total amount
            $totalAmount = array_sum(array_column($items, 'totalAmount'));
            // Otherwise spread the cart line again with the updated total
            $orderLines[$hash] = static::spreadCartLineGroup($items, $totalAmount + $remaining);
            break;
        }
    }

    return $orderLines;
}

With this fix, the issue from the TODO comment: TODO: check why remaining comes -100 when testing and new total becomes different should be resolved.

mariuszsienkiewicz commented 2 months ago

Talking a bit about the code fixes – implementing it the way I described ensures that orders with discounts applied to products will have the discount correctly handled, and there won’t be issues with discrepancies between the sum of the product values in orderLines and what we pass from PrestaShop as the total order amount. We had a situation where PrestaShop, after applying discounts, had an inaccuracy of 0.02 euros, which caused the code to malfunction and add as much as around 1.6 euros to one of the products – which is, of course, completely incorrect due to the faulty logic of this function.

justelis22 commented 1 month ago

Hi there @mariuszsienkiewicz,

Can you please provide us with the exact steps to recreate this issue? Product prices, discounts, and order total would be needed.

Thanks!

Best Regards, Invertus Support team.

mariuszsienkiewicz commented 1 month ago

I will provide you with more information soon, so please don't close this issue in the meantime. :)

justelis22 commented 1 month ago

@mariuszsienkiewicz,

When you are available, please provide more information. We created several discounts which were applied to cart and product, with several vouchers as well. Tried different discount types, but Klarna payments seems to be working fine .

Can we get configurations and shop information(ps version)

If you have any questions, please let me know!

Best Regards, Invertus Support team.

justelis22 commented 1 week ago

Hello there,

As this has been inactive for some time now, I am closing the issue.

If you are still facing it and decide to come back, please reply and with the answer and we will continue working.

If you have any questions, please let me know!

Best Regards, Invertus Support team.