浏览代码

Register discounts on the order line

master
Lars van de Kerkhof 2 年前
父节点
当前提交
e6fb1897a4
共有 2 个文件被更改,包括 52 次插入19 次删除
  1. 51
    19
      src/oscar/apps/basket/abstract_models.py
  2. 1
    0
      src/oscar/apps/basket/utils.py

+ 51
- 19
src/oscar/apps/basket/abstract_models.py 查看文件

@@ -727,8 +727,9 @@ class AbstractLine(models.Model):
727 727
     def __init__(self, *args, **kwargs):
728 728
         super().__init__(*args, **kwargs)
729 729
         # Instance variables used to persist discount information
730
-        self._discount_excl_tax = D("0.00")
731
-        self._discount_incl_tax = D("0.00")
730
+        self.discounts = []
731
+        # self._discount_excl_tax = D("0.00")
732
+        # self._discount_incl_tax = D("0.00")
732 733
         self.consumer = LineOfferConsumer(self)
733 734
 
734 735
     class Meta:
@@ -764,8 +765,9 @@ class AbstractLine(models.Model):
764 765
         """
765 766
         Remove any discounts from this line.
766 767
         """
767
-        self._discount_excl_tax = D("0.00")
768
-        self._discount_incl_tax = D("0.00")
768
+        self.discounts = []
769
+        # self._discount_excl_tax = D("0.00")
770
+        # self._discount_incl_tax = D("0.00")
769 771
         self.consumer = LineOfferConsumer(self)
770 772
 
771 773
     def discount(self, discount_value, affected_quantity, incl_tax=True, offer=None):
@@ -778,14 +780,13 @@ class AbstractLine(models.Model):
778 780
                     "Attempting to discount the tax-inclusive price of a line "
779 781
                     "when tax-exclusive discounts are already applied"
780 782
                 )
781
-            self._discount_incl_tax += discount_value
782 783
         else:
783 784
             if self._discount_incl_tax > 0:
784 785
                 raise RuntimeError(
785 786
                     "Attempting to discount the tax-exclusive price of a line "
786 787
                     "when tax-inclusive discounts are already applied"
787 788
                 )
788
-            self._discount_excl_tax += discount_value
789
+        self.discounts.append((discount_value, affected_quantity, incl_tax, offer))
789 790
         self.consume(affected_quantity, offer=offer)
790 791
 
791 792
     def consume(self, quantity, offer=None):
@@ -870,6 +871,22 @@ class AbstractLine(models.Model):
870 871
     # Properties
871 872
     # ==========
872 873
 
874
+    @property
875
+    def _discount_incl_tax(self):
876
+        return sum([discount[0] for discount in self.discounts if discount[2]], 0)
877
+
878
+    @_discount_incl_tax.setter
879
+    def _discount_incl_tax(self, value):
880
+        raise Exception("_discount_incl_tax kan je niet setten")
881
+
882
+    @property
883
+    def _discount_excl_tax(self):
884
+        return sum([discount[0] for discount in self.discounts if not discount[2]], 0)
885
+
886
+    @_discount_excl_tax.setter
887
+    def _discount_excl_tax(self, value):
888
+        raise Exception("_discount_excl_tax kan je niet setten")
889
+
873 890
     @property
874 891
     def has_discount(self):
875 892
         return bool(self.consumer.consumed())
@@ -884,8 +901,9 @@ class AbstractLine(models.Model):
884 901
 
885 902
     @property
886 903
     def discount_value(self):
904
+        return sum([discount[0] for discount in self.discounts], 0)
887 905
         # Only one of the incl- and excl- discounts should be non-zero
888
-        return max(self._discount_incl_tax, self._discount_excl_tax)
906
+        # return max(self._discount_incl_tax, self._discount_excl_tax)
889 907
 
890 908
     # pylint: disable=W0201
891 909
     @property
@@ -928,33 +946,47 @@ class AbstractLine(models.Model):
928 946
 
929 947
     @property
930 948
     def line_price_excl_tax_incl_discounts(self):
931
-        if self._discount_excl_tax and self.line_price_excl_tax is not None:
932
-            return max(0, self.line_price_excl_tax - self._discount_excl_tax)
933
-        if self._discount_incl_tax and self.line_price_incl_tax is not None:
934
-            # This is a tricky situation.  We know the discount as calculated
935
-            # against tax inclusive prices but we need to guess how much of the
936
-            # discount applies to tax-exclusive prices.  We do this by
937
-            # assuming a linear tax and scaling down the original discount.
949
+        if self.line_price_excl_tax is None:
950
+            return None
951
+
952
+        excl_tax_discounts = sum(
953
+            [discount[0] for discount in self.discounts if not discount[2]], 0
954
+        )
955
+        incl_tax_discounts = sum(
956
+            [discount[0] for discount in self.discounts if discount[2]], 0
957
+        )
958
+
959
+        if excl_tax_discounts and self.line_price_excl_tax is not None:
960
+            return max(0, self.line_price_excl_tax - excl_tax_discounts)
961
+
962
+        if incl_tax_discounts and self.line_price_incl_tax is not None:
938 963
             return max(
939 964
                 0,
940 965
                 self.line_price_excl_tax
941
-                - round_half_up(self._tax_ratio * self._discount_incl_tax),
966
+                - round_half_up(self._tax_ratio * incl_tax_discounts),
942 967
             )
968
+
943 969
         return self.line_price_excl_tax
944 970
 
945 971
     @property
946 972
     def line_price_incl_tax_incl_discounts(self):
973
+        excl_tax_discounts = sum(
974
+            [discount[0] for discount in self.discounts if not discount[2]], 0
975
+        )
976
+        incl_tax_discounts = sum(
977
+            [discount[0] for discount in self.discounts if discount[2]], 0
978
+        )
979
+
947 980
         # We use whichever discount value is set.  If the discount value was
948 981
         # calculated against the tax-exclusive prices, then the line price
949 982
         # including tax
950
-        if self.line_price_incl_tax is not None and self._discount_incl_tax:
983
+        if self.line_price_incl_tax is not None and incl_tax_discounts:
951 984
             return max(0, self.line_price_incl_tax - self._discount_incl_tax)
952
-        elif self.line_price_excl_tax is not None and self._discount_excl_tax:
985
+        elif self.line_price_excl_tax is not None and excl_tax_discounts:
953 986
             return max(
954 987
                 0,
955 988
                 round_half_up(
956
-                    (self.line_price_excl_tax - self._discount_excl_tax)
957
-                    / self._tax_ratio
989
+                    (self.line_price_excl_tax - excl_tax_discounts) / self._tax_ratio
958 990
                 ),
959 991
             )
960 992
 

+ 1
- 0
src/oscar/apps/basket/utils.py 查看文件

@@ -115,6 +115,7 @@ class LineOfferConsumer(object):
115 115
         basket line is consumed for *any* offer, else only for the
116 116
         specified offer.
117 117
         """
118
+        # raise Exception("viggo is henk")
118 119
         if offer:
119 120
             self._cache(offer)
120 121
             available = self.available(offer)

正在加载...
取消
保存