Magento why 3 tax calculation methods? - algorithm

Today I was studying how Magento tax calculation works to understand the difference between the behaviors for "Tax Calculation Method Based On".
I traced deep into Mage_Tax_Model_Sales_Total_Quote_Tax which implements all methods in the _unitBaseCalculation, _rowBaseCalculation, _totalBaseCalculation.
I discovered that they produce exactly the same results. So why did they go through the trouble of implementing them ?
For example, unit-price calculation goes to the trouble of calculating the tax for the single unit and then dividing the discount amount by the qty (if tax applied after discount), then subtracting both, and then multiplying again by the quantity... which just introduces rounding errors.
Whereas Row Total calculation is the most intuitive one (which takes the price from the row "subtotal") minus discount amount (if tax applied after discount).
While the third one is just an aggregation of the second, calculated at once.
This just introduces confusion and obfuscation to the tax calculation logic. Can anyone shed a light onto why this was done ?
(Rounding errors ? Backward compatibility ? Candidate for TheDailyWTF prize ?)
EDIT: For the record this is true as of Magento 1.6 and 1.7, don't know about older versions.

I found this from: https://gist.github.com/2572772 (by Alan Storm it seems)
This feature was probably motivated by individual local rules (or client requests) as to how taxes should be calculated, as fractional amounts could add up differently depending on when adding and rounding occurs. THat said, I haven't run through the code to see if my guesses are right so YMMV. Other areas to consider for future research.
How does each mode play with shopping cart price rules and store wide discounts
For shopping cart price rules, it goes through painstaking trouble to divide the discount amount (which may not be divisible by the quote item quantity thus introducing a rounding error) so that the end result is the actually the same process, but only with different "when"s and "where"s as to rounding.

Related

Magento 2 same product with multiple product costs prices

I have an issue right now and I believe many people might have this issue I am wondering if someone has found a work around so my issue is I have products that I buy stock for on a daily basis due to excahnge rate and other things the same product sometimes costs me different every time so my issue is,
If I have a Samsung watch I have 5 units in stock that cost me £35 Then I see a good deal on them and buy another 10 units these cost me £30 but I still have the 5 units in stock that cost me £35 so how can I upload/update the 10 units making 15 units in total but have a seperate cost price for the 10 units compared to the 5 units as I need this for reporting profit and loss reports.
So Ideally I want to be able to update my stock qty each time I do so I need to set a new cost price for that same product for selected amount of qtys,
Right now I am currently making the same product/SKU Multiple times because the product is the same but has cost me multiple by prices and I do not want to not have it listed for sale until the other stock sells and I do not want to keep making multiple products as customers think the products are different..
Any help will be strongly appriciated!
Have you check Tire Price concept in magento ?
I think this will full fill your requirement.
Let me know if you have any query.

Methods of comparing prices

I will create a list of products that I wish to buy. Let's say they are all given a unique reference code. I have a list of suppliers I can buy from and for convenience each supplier uses the same reference code for each product.
Some suppliers charge shipping. Others only charge shipping if you spend less than a certain amount. Some suppliers discount certain products if you buy them more than once but there may be restrictions (such as by 1 get 1 free).
It is extremely easy to take the list of products I want to buy and tally up the total it would cost to buy all of them from each supplier. What I want to do though is create a script to work out whether it would be better to split the order.
For example:
Retailer A charges:
Product A - £5
Product B - £10
Product C - £10
Product D - £10
Shipping - £5
Retailer B charges:
Product A - £5
Product B - £12
Product C - £12
Product D - £30
Shipping - £5 - free if spending £20 or more
In this case, if I wanted to buy Product C only, the cheapest would be from retailer A.
If I wanted to buy:
1x Product A
2x Product B
1x Product D
The cheapest would be retailer B (because of the free delivery) for products A and B and to then split the order and purchase product D from retailer A (as the price even with delivery is significantly lower even with delivery included).
So in my head it's not a complex task and I can work it out very easily on paper. The question is, how I would translate this into code. I'm not looking for the code to do it - just some guidance on the theory of how to implement it.
If we restrict the problem to simply choosing which vendor to buy each product from, and you get a vendor-dependent reduction in shipping cost if you spend a vendor-dependent amount, then you can formulate your problem as an integer linear program (IP or ILP), which is a good strategy for problems suspected to be NP-hard because there has been a lot of research and software packages developed that try to solve ILP fast in practice. You can read about linear programming and ILP online. An ILP problem instance has variables, linear constraints on the variables, and a linear objective you want to minimize or maximize. Here's the ILP set up for your problem:
For each product that a vendor sells, you have one vendor-product variable that tells how many of the product you will purchase from the vendor. For each of these variables you have a constraint that the variable must be >= 0. For each product you wish to buy, you have a constraint that the sum of all the vendor-product variables for that product must equal the total number of the product that you wish to buy.
Then for each vendor that offers a shipping discount, you have a shipping discount variable which will be either 0 if you don't get the discount, or 1 if you do. For each one of these shipping discount variables, you have constraints that the variable must be >=0 and <= 1; you also have a constraint that says when you multiply each vendor-product variable for the vendor by the vendor's price for that product, and add it all up for the vendor (so you get the total amount you are spending at the vendor), this amount is >= the vendor's shipping discount variable multiplied by the vendor's minimum amount you need to spend to get the discount.
You also have for each vendor a vendor variable which is 1 if you use the vendor, and 0 if you don't. For each of these vendor variables A, you have constraints 1 >= A > =0 and also for each vendor-product variable B for the vendor, you have a constraint A >= B/N, where N is the total number of items you want to buy.
Finally the objective you want to maximize is made by multiplying each vendor-product variable by the vendor's price for that product, adding it all up (call this part of the objective X), and then multiplying each vendor's shipping discount variable by the shipping cost reduction you get if you get the discount, adding it all up (call this part of the objective Y), and multiplying each vendor variable by the vendor's undiscounted shipping cost, adding it all up (call this part of the objective Z) then your objective is simply to minimize X - Y + Z. This is all you need to define the ILP, then you can feed it into an ILP solver and hopefully get a solution quickly.
Mixed Integer Linear Programming is ok for your problem.
You can use a free solver such as Coin Clp. If you want to know about commercial MILP solver performances, you can find some benchmarks there : http://plato.asu.edu/bench.html.
If you want to have a rough idea of the time required to solve your problem, you can run your problem on NEOS Server : http://www.neos-server.org/neos/.
When you have a lot of 0-1 variable, you can also contemplate to use Constraint Programming which often suits better for heavy combinatorial problems.
Both MILP and CP algorithms use branch and bound technique, which is faster than naive enumeration.
Cheers

Paypal Rounding Algorithm

Does anyone know what algorithm Paypal uses to round? I'm doing some testing with discount promo codes on my site, and I'm coming up with different totals than what Paypal comes up with when I pass the same discount amount using the "discount_rate_cart" variable.
For example, a couple of items on my site total $309.95. Applying a 10% discount ( 309.95 * .9 = 278.955) should yield a total of $278.96, as .955 should round up to .96. However, when I pass the total $309.95 and the 10% discount to PayPal, they come up with a total of $278.95. They rounded down when they should have rounded up.
Does anybody know why this is happening? Please note, I'm not doing anything fancy like currency conversion here, just simple algebra for giving discounts on the total cost of the shopping cart.
So the algorithm is banking rounding but on a transaction by transaction basis. This means the discount is a transaction of its ow e.g.
10% of $309.95 is $30.995 and bank rounding is to the nearest even number being $31.00.
Therefore:
$309.95
-$ 31.00
========
$278.95
So theoretically if you had a discount of $30.987 this will round to $30.98 not $30.99.

Complex configurable products

Here is the scenario. I have a configurable product which has two attributes. However, the price increment for the second attribute is dependent on the first. The price increments are a combination of fixed and percentage. So, lets assume the two attributes in question are size and colour - the amount added on for larger sizes is fixed, but the amount added on for different colours is a percentage.
The issue is that magento is adding the percentage increment for colour to the base price, not to the price plus the fixed increment for size.
As an example, let assume my product is available in three sizes, small medium and large; and in three colours, red, green and blue. The increment for medium and large are £5 and £10 respectively, and the increment for colour is 5% for green and 10% for blue (to be applied dependent on the size selected). My product has a base price of £100.
A customer purchasing a medium red product would pay £105, however magento applies the same price to a customer purchasing a medium blue product (because the percentage increase is calculated BEFORE the size is selected).
Is there any way to handle this so that the correct percentage increase is calculated AFTER the size is selected?
Cheers
Simon
Generally I do not like to recommend this extension as it makes pricing in Magneto way more complicated and time consuming (I just got out of it myself and it was not the fault of the module), but I think this might be the solution for you:
http://www.magentocommerce.com/magento-connect/simple-configurable-products.html
Basically this modifies the way Configurable products are priced so that it uses the price of the simple product and not the values contained in the super attributes.
The upside is that the price of the simple product is the price that it will be sold for on the configurable page.
The downside is that it is very easy to have the website do some funky things with pricing if you are not careful. For example we had a lot of scenarios where the configurable product price was $10.00, but all the simple products price was $8. Each item in the dropdown had a "negative upcharge" in there.
This was not the modules fault, rather carelessness of people managing the products.

Magento discount calcuation 1p off

I have setup a shopping cart price rule of 10%. If I add a product value 33.95 in the cart and apply that rule, it shows discount of 3.40 which is suppose to be 3.39. I am assuming its rounding up to 2 digit and may be needs changing to 3 digit (I'm assuming this) but don't know where to make this change.
Welcome to the world of rounding errors in Magento.
Usually, it is not a cause for major concern, as the cart total is correct; but the row level items are calculated wrong. This also effects the admin order display and invoice PDFs.
Different versions have different rounding bugs, there isn't a fix in the strictest sense, we just patch them as we go along.

Resources