|
|
@@ -16,28 +16,36 @@ class AbstractVoucher(models.Model):
|
|
16
|
16
|
(c) Once per customer
|
|
17
|
17
|
"""
|
|
18
|
18
|
name = models.CharField(_("Name"), max_length=128,
|
|
19
|
|
- help_text=_("""This will be shown in the checkout and basket once the voucher is entered"""))
|
|
20
|
|
- code = models.CharField(_("Code"), max_length=128, db_index=True, unique=True,
|
|
|
19
|
+ help_text=_("This will be shown in the checkout and basket "
|
|
|
20
|
+ "once the voucher is entered"))
|
|
|
21
|
+ code = models.CharField(_("Code"), max_length=128,
|
|
|
22
|
+ db_index=True, unique=True,
|
|
21
|
23
|
help_text=_("""Case insensitive / No spaces allowed"""))
|
|
22
|
|
- offers = models.ManyToManyField('offer.ConditionalOffer', related_name='vouchers', verbose_name=_("Offers"),
|
|
23
|
|
- limit_choices_to={'offer_type': "Voucher"})
|
|
|
24
|
+ offers = models.ManyToManyField(
|
|
|
25
|
+ 'offer.ConditionalOffer', related_name='vouchers',
|
|
|
26
|
+ verbose_name=_("Offers"), limit_choices_to={'offer_type': "Voucher"})
|
|
24
|
27
|
|
|
25
|
|
- SINGLE_USE, MULTI_USE, ONCE_PER_CUSTOMER = ('Single use', 'Multi-use', 'Once per customer')
|
|
|
28
|
+ SINGLE_USE, MULTI_USE, ONCE_PER_CUSTOMER = (
|
|
|
29
|
+ 'Single use', 'Multi-use', 'Once per customer')
|
|
26
|
30
|
USAGE_CHOICES = (
|
|
27
|
31
|
(SINGLE_USE, _("Can be used once by one customer")),
|
|
28
|
32
|
(MULTI_USE, _("Can be used multiple times by multiple customers")),
|
|
29
|
33
|
(ONCE_PER_CUSTOMER, _("Can only be used once per customer")),
|
|
30
|
34
|
)
|
|
31
|
|
- usage = models.CharField(_("Usage"), max_length=128, choices=USAGE_CHOICES, default=MULTI_USE)
|
|
|
35
|
+ usage = models.CharField(_("Usage"), max_length=128,
|
|
|
36
|
+ choices=USAGE_CHOICES, default=MULTI_USE)
|
|
32
|
37
|
|
|
33
|
38
|
start_date = models.DateField(_('Start Date'))
|
|
34
|
39
|
end_date = models.DateField(_('End Date'))
|
|
35
|
40
|
|
|
36
|
41
|
# Audit information
|
|
37
|
|
- num_basket_additions = models.PositiveIntegerField(_("Times added to basket"), default=0)
|
|
|
42
|
+ num_basket_additions = models.PositiveIntegerField(
|
|
|
43
|
+ _("Times added to basket"), default=0)
|
|
38
|
44
|
num_orders = models.PositiveIntegerField(_("Times on orders"), default=0)
|
|
39
|
|
- total_discount = models.DecimalField(_("Total discount"), decimal_places=2, max_digits=12, default=Decimal('0.00'))
|
|
40
|
|
-
|
|
|
45
|
+ total_discount = models.DecimalField(
|
|
|
46
|
+ _("Total discount"), decimal_places=2, max_digits=12,
|
|
|
47
|
+ default=Decimal('0.00'))
|
|
|
48
|
+
|
|
41
|
49
|
date_created = models.DateField(auto_now_add=True)
|
|
42
|
50
|
|
|
43
|
51
|
class Meta:
|
|
|
@@ -50,8 +58,10 @@ class AbstractVoucher(models.Model):
|
|
50
|
58
|
return self.name
|
|
51
|
59
|
|
|
52
|
60
|
def clean(self):
|
|
53
|
|
- if self.start_date and self.end_date and self.start_date > self.end_date:
|
|
54
|
|
- raise exceptions.ValidationError(_('End date should be later than start date'))
|
|
|
61
|
+ if (self.start_date and self.end_date and
|
|
|
62
|
+ self.start_date > self.end_date):
|
|
|
63
|
+ raise exceptions.ValidationError(
|
|
|
64
|
+ _('End date should be later than start date'))
|
|
55
|
65
|
|
|
56
|
66
|
def save(self, *args, **kwargs):
|
|
57
|
67
|
self.code = self.code.upper()
|
|
|
@@ -68,8 +78,9 @@ class AbstractVoucher(models.Model):
|
|
68
|
78
|
def is_available_to_user(self, user=None):
|
|
69
|
79
|
"""
|
|
70
|
80
|
Test whether this voucher is available to the passed user.
|
|
71
|
|
-
|
|
72
|
|
- Returns a tuple of a boolean for whether it is successulf, and a message
|
|
|
81
|
+
|
|
|
82
|
+ Returns a tuple of a boolean for whether it is successulf, and a
|
|
|
83
|
+ message
|
|
73
|
84
|
"""
|
|
74
|
85
|
is_available, message = False, ''
|
|
75
|
86
|
if self.usage == self.SINGLE_USE:
|
|
|
@@ -81,13 +92,16 @@ class AbstractVoucher(models.Model):
|
|
81
|
92
|
elif self.usage == self.ONCE_PER_CUSTOMER:
|
|
82
|
93
|
if not user.is_authenticated():
|
|
83
|
94
|
is_available = False
|
|
84
|
|
- message = _("This voucher is only available to signed in users")
|
|
|
95
|
+ message = _(
|
|
|
96
|
+ "This voucher is only available to signed in users")
|
|
85
|
97
|
else:
|
|
86
|
|
- is_available = self.applications.filter(voucher=self, user=user).count() == 0
|
|
|
98
|
+ is_available = self.applications.filter(
|
|
|
99
|
+ voucher=self, user=user).count() == 0
|
|
87
|
100
|
if not is_available:
|
|
88
|
|
- message = _("You have already used this voucher in a previous order")
|
|
|
101
|
+ message = _("You have already used this voucher in "
|
|
|
102
|
+ "a previous order")
|
|
89
|
103
|
return is_available, message
|
|
90
|
|
-
|
|
|
104
|
+
|
|
91
|
105
|
def record_usage(self, order, user):
|
|
92
|
106
|
"""
|
|
93
|
107
|
Records a usage of this voucher in an order.
|
|
|
@@ -109,17 +123,20 @@ class AbstractVoucher(models.Model):
|
|
109
|
123
|
@property
|
|
110
|
124
|
def benefit(self):
|
|
111
|
125
|
return self.offers.all()[0].benefit
|
|
112
|
|
-
|
|
113
|
|
-
|
|
|
126
|
+
|
|
|
127
|
+
|
|
114
|
128
|
class AbstractVoucherApplication(models.Model):
|
|
115
|
129
|
"""
|
|
116
|
130
|
For tracking how often a voucher has been used
|
|
117
|
131
|
"""
|
|
118
|
|
- voucher = models.ForeignKey('voucher.Voucher', related_name="applications", verbose_name=_("Voucher"))
|
|
119
|
|
-
|
|
120
|
|
- # It is possible for an anonymous user to apply a voucher so we need to allow
|
|
121
|
|
- # the user to be nullable
|
|
122
|
|
- user = models.ForeignKey('auth.User', blank=True, null=True, verbose_name=_("User"))
|
|
|
132
|
+ voucher = models.ForeignKey(
|
|
|
133
|
+ 'voucher.Voucher', related_name="applications",
|
|
|
134
|
+ verbose_name=_("Voucher"))
|
|
|
135
|
+
|
|
|
136
|
+ # It is possible for an anonymous user to apply a voucher so we need to
|
|
|
137
|
+ # allow the user to be nullable
|
|
|
138
|
+ user = models.ForeignKey('auth.User', blank=True, null=True,
|
|
|
139
|
+ verbose_name=_("User"))
|
|
123
|
140
|
order = models.ForeignKey('order.Order', verbose_name=_("Order"))
|
|
124
|
141
|
date_created = models.DateField(_("Date Creted"), auto_now_add=True)
|
|
125
|
142
|
|