|
|
@@ -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
|