Pārlūkot izejas kodu

Added missing implementation for computing line_price_excl_tax_incl_discounts when line_price_excl_tax is not known at all.

master
Lars van de Kerkhof 1 gadu atpakaļ
vecāks
revīzija
cdd03bde8c
1 mainītis faili ar 35 papildinājumiem un 9 dzēšanām
  1. 35
    9
      src/oscar/apps/basket/abstract_models.py

+ 35
- 9
src/oscar/apps/basket/abstract_models.py Parādīt failu

@@ -842,6 +842,14 @@ class AbstractLine(models.Model):
842 842
 
843 843
     @property
844 844
     def _tax_ratio(self):
845
+        # this function tries to computate the tax ratio based on the incl tax price
846
+        # versus the excl tax price. Since these values are allready rounded, this will
847
+        # NOT return the exact ratio corresponding to your tax rate.
848
+        # if this is a problem you need to provide your own implementation of _tax_ratio
849
+        # that returns the ratio based on the exact tax percentage in use.
850
+        # one way to make this value correct is to use 4 decimals for all prices everywhere,
851
+        # and round only at the last moment when presenting the values to the user.
852
+        # that would make this value precise and correct because there would be no rounding
845 853
         if not self.unit_price_incl_tax:
846 854
             return 0
847 855
         return self.unit_price_excl_tax / self.unit_price_incl_tax
@@ -950,18 +958,36 @@ class AbstractLine(models.Model):
950 958
             return None
951 959
 
952 960
         excl_tax_discounts = self.discounts.excl_tax
953
-        incl_tax_discounts = self.discounts.incl_tax
954
-
955
-        if excl_tax_discounts and self.line_price_excl_tax is not None:
961
+        if excl_tax_discounts:
962
+            # there are discounts that return a value excluding tax, we can simply
963
+            # subtract this value from line_price_excl_tax to get to line_price_excl_tax_incl_discounts
956 964
             return max(0, self.line_price_excl_tax - excl_tax_discounts)
957 965
 
958
-        if incl_tax_discounts and self.line_price_incl_tax is not None:
959
-            return max(
960
-                0,
961
-                self.line_price_excl_tax
962
-                - round_half_up(self._tax_ratio * incl_tax_discounts),
963
-            )
966
+        # This is a tricky situation.  We know the discount as calculated
967
+        # against tax inclusive prices but we need to guess how much of the
968
+        # discount applies to tax-exclusive prices.  We do this by
969
+        # assuming a linear tax and scaling down the original discount.
970
+        # Please refer to the _tax_ratio method for more details on how
971
+        # to make this calculation more precise.
972
+
973
+        incl_tax_discounts = self.discounts.incl_tax
974
+        if incl_tax_discounts and self._tax_ratio:
975
+            if self.line_price_excl_tax is not None:
976
+                # if we got a precise line_price_excl_tax use that first, if _tax_ratio is off,
977
+                # this will create the smallest deviation becaise incl_tax_discounts is usually
978
+                # smaller than line_price_excl_tax
979
+                return max(
980
+                    0,
981
+                    self.line_price_excl_tax
982
+                    - round_half_up(self._tax_ratio * incl_tax_discounts),
983
+                )
984
+            elif self.line_price_incl_tax is not None:
985
+                # when all else fails, compute based on line_price_incl_tax
986
+                return max(
987
+                    0, self._tax_ratio * (self.line_price_incl_tax - incl_tax_discounts)
988
+                )
964 989
 
990
+        # there are no discounts so just return the line_price_excl_tax
965 991
         return self.line_price_excl_tax
966 992
 
967 993
     @property

Notiek ielāde…
Atcelt
Saglabāt