Sort algorithm: Magento checkout totals sorted wrongly causing wrong shipping tax calculation

前端 未结 6 910
生来不讨喜
生来不讨喜 2020-12-07 15:33

In Magento there is a functionality where you can define the order of total calculation by specifing before and after which totals a total should be run.

I added a c

6条回答
  •  再見小時候
    2020-12-07 16:17

    Thanks for persisting @Alex, here is a better answer with a better explanation :) My first answer was wrong.

    PHP implements the quicksort for all array sorting functions (reference zend_qsort.c).
    If two records in the array are identical, their place will be swapped.

    The problem is the giftwrap total record, which, according to _compareTotals(), is larger then subtotal and nominal but equal to all other totals.

    Depending on the original order of the $confArray input array and on the placement of the pivot element it is legal to swap giftwrap with e.g. discount, because both are equal, even though discount is larger then shipping.

    This might make the problem clearer from the sorting algorithms point of view:

    • shipping < tax_shipping
    • giftwrapping == shipping
    • giftwrapping == tax_shipping

    There are several possible solutions, even though the original problem is the choice of quicksort to build a directed acyclic dependency graph

    • One (bad, shortterm) solution would be to add more dependencies to the giftwrapping total, even though there might still be more problems with other totals that simply didn't surface so far.
    • The real solution would be to implement a topological sorting algorithm for the problem.

    Interestingly there are not many PHP packages floating around. There is an orphaned PEAR package Structures_Graph. Using that would probably be the quick solution, but it would mean transforming the $confArray into a Structures_Graph structure (so maybe not that quick).

    Wikipedia does a good job of explaining the problem, so rolling your own solution might be a fun challenge. The German Wikipedia topological sorting page breaks down the problem into logical steps and also has a great example algorithm in PERL.

提交回复
热议问题