lukepolo / laracart

Laravel Shopping Cart Package
https://laracart.lukepolo.com
MIT License
576 stars 86 forks source link

Item addCoupon() behaves differently from LaraCart::addCoupon() #289

Closed dennisoderwald closed 3 years ago

dennisoderwald commented 3 years ago

In my tests I recently noticed that it makes a difference whether a coupon is included via LaraCart::addCoupon() or $item->addCoupon().

    $product = Product::find(1);
    $item = LaraCart::add($product);
    $item->tax = $product->tax; // 19%

    $item->addSubItem([
        'description' => 'Product A',
        'price' => 8.40336,
        'qty' => 1
    ]);

    $item->addSubItem([
        'description' => 'Product B',
        'price' => 4.20168,
        'qty' => 1
    ]);

    $couponPercentage = new \LukePOLO\LaraCart\Coupons\Percentage('CODE', 0.5);
    $item->addCoupon($couponPercentage);

Expected result:

Netto (LaraCart::subTotal()): 12.61 Total Discount (LaraCart::totalDiscount()): 7.50 Tax Total (LaraCart::taxTotal()): 2.39 Total (LaraCart::total()): 7.50

Output result:

Netto (LaraCart::subTotal()): 5.11 Total Discount (LaraCart::totalDiscount()): 7.50 Tax Total (LaraCart::taxTotal()): -0.23 Total (LaraCart::total()): 4.88

lukepolo commented 3 years ago

So after reading how coupons work I can see how I got into this situation.

Issue:

  1. Taxes should be applied AFTER discount (mostly)
  2. A cart coupon has been added ($10 off entire cart)
  3. The cart has multiple items of different tax rate

The problem becomes, I have to remove the discount before taxing.

Which item should be chosen to remove the fixed amount? (highest tax / highest cost etc.)

Im about to change it if you have multiple items with taxes you either

A. cannot apply coupons at the cart level B. you have to check them out separately

dennisoderwald commented 3 years ago

@lukepolo Thank you for taking the time.

Of course, I can not speak for how it looks in other countries, but in Germany to be safe, I explain the taxation again with an example:

Example of a voucher with percentage discount:

Item 1: 119€ (19% VAT) Item 2: 107€ (7% VAT) Voucher: 10%

Total cost: 119 -11,90 + 107 - 10,7 € = 203,40€.

The VAT rate here is 19€ - 1,9€ + 7€ - 1,12€ = 22,98€.

The voucher must therefore be divided into two tax rates. Wrong is the use of a maximum or minimum tax rate:

Using a maximum tax rate (19% of 11,90+10,70 = 3,61€) would result in a too low VAT amount of 22,39€. Using a minimum tax rate (7% of 11,90+10,70 = 1,48€) would result in a too high VAT amount of 24,52€.

There is one special feature (which German systems often take into account and which I would see as an advantage of the library):

Vouchers with absolute amounts can also be used to save cash.

Example:

Item 1: 119€ (19% VAT) Item 2: 107€ (7% VAT) Gift: 50€

Since the voucher is given as a gift, the purchase price of the items is reduced and there is less VAT. And this is exactly where you can save as a store owner. Let's look at two extremes for this:

Item 1 we reduced:

Item 1: 119€ - 50€ 69€ (11,02 € VAT.) Item 2: 107€ (7 € VAT)

Total: 157,98€ net, 18,02 € VAT.

Item 2 is reduced:

Item 1: 119€ (19 € VAT) Item 2: 107€ - 50€ 57€ (9,10 € VAT)

Total: 147,90 € net, 28,10 € VAT.

So, intelligently applied, the store owner earns 10€ more net. Consequently, the most favorable variant is to apply the voucher only to those items that have the highest VAT rate. This way the store owner has to pay less VAT and saves money.

lukepolo commented 3 years ago

👍🏻 , I was just coding it to be like this :-)

the hard part is to figure out how much was applied and if it spills over we should still remove it from the smaller vat.

I'm focusing on making the code simpler to read and manage, while hoping to keep most of the features intact.

dennisoderwald commented 3 years ago

Germany is unfortunately very complicated in the tax system. The question is whether there are enough interested parties to implement and take into account so complex and whether this is at all justifiable in terms of effort. Of course, I would be very happy about it and like to test diligently as soon as there is a branch!

dennisoderwald commented 3 years ago

@lukepolo I just thought about it again also in terms of the preparation of the code, because there are already many configuration options that have been added over time (organically).

Maybe it would be good to provide presets as JSON file where configurations are mapped to fulfill certain tax systems? This would also make it easier for newcomers to understand the system and the JSON file is the basis of the configuration per country/circumstances.

You can think about it.

lukepolo commented 3 years ago

yah we could certainly do that, im trying to trim down some on the configs (default tax by item is one of them)

lukepolo commented 3 years ago

https://github.com/lukepolo/laracart/pull/290 , its a start, but feels alot better in terms of how we apply coupons and discounts

lukepolo commented 3 years ago

i dont have the smart fixed in there yet, should be pretty easy though, ill sort items by their tax rate and then apply the coupons to those first.

lukepolo commented 3 years ago

I have solved this in the newer branch thats coming out soon.