Add backend editor for discount codes
authorMagnus Hagander <magnus@hagander.net>
Thu, 5 Apr 2018 14:36:50 +0000 (16:36 +0200)
committerMagnus Hagander <magnus@hagander.net>
Thu, 5 Apr 2018 14:36:50 +0000 (16:36 +0200)
postgresqleu/confreg/backendforms.py
postgresqleu/confreg/backendviews.py
postgresqleu/confreg/migrations/0005_vat.py
postgresqleu/confreg/models.py
postgresqleu/urls.py
template/confreg/admin_dashboard_single.html

index 8f3d2c68fa236a4cda2c2b49b7c913a9175823c4..5ba7b7b28162a9ae0fdefcb11f3f5dc069eeb540 100644 (file)
@@ -20,6 +20,7 @@ from postgresqleu.confreg.models import RegistrationClass, RegistrationType, Reg
 from postgresqleu.confreg.models import ConferenceAdditionalOption, ConferenceFeedbackQuestion
 from postgresqleu.confreg.models import ConferenceSession, Track, Room
 from postgresqleu.confreg.models import ConferenceSessionScheduleSlot, VolunteerSlot
+from postgresqleu.confreg.models import DiscountCode
 
 from postgresqleu.confreg.models import valid_status_transitions, get_status_string
 
@@ -274,3 +275,46 @@ class BackendFeedbackQuestionForm(BackendForm):
                model = ConferenceFeedbackQuestion
                fields = ['question', 'isfreetext', 'textchoices', 'sortkey', 'newfieldset']
 
+
+class BackendNewDiscountCodeForm(django.forms.Form):
+       codetype = django.forms.ChoiceField(choices=((1, 'Fixed amount discount'), (2, 'Percentage discount')))
+
+       def get_newform_data(self):
+               return self.cleaned_data['codetype']
+
+class BackendDiscountCodeForm(BackendForm):
+       list_fields = ['code', 'validuntil', 'maxuses']
+
+       form_before_new = BackendNewDiscountCodeForm
+
+       exclude_date_validators = ['validuntil', ]
+
+       class Meta:
+               model = DiscountCode
+               fields = ['code', 'discountamount', 'discountpercentage', 'regonly', 'validuntil', 'maxuses',
+                                 'requiresregtype', 'requiresoption']
+
+       def fix_fields(self):
+               if self.newformdata == "1" and not self.instance.discountamount:
+                       self.instance.discountamount = 1
+               elif self.newformdata == "2" and not self.instance.discountpercentage:
+                       self.instance.discountpercentage = 1
+
+               if self.instance.discountamount:
+                       # Fixed amount discount
+                       del self.fields['discountpercentage']
+                       del self.fields['regonly']
+                       self.fields['discountamount'].validators.append(MinValueValidator(1))
+               else:
+                       # Percentage discount
+                       del self.fields['discountamount']
+                       self.fields['discountpercentage'].validators.extend([
+                               MinValueValidator(1),
+                               MaxValueValidator(99),
+                       ])
+               self.fields['maxuses'].validators.append(MinValueValidator(0))
+
+               self.fields['requiresregtype'].queryset = RegistrationType.objects.filter(conference=self.conference)
+               self.fields['requiresoption'].queryset = ConferenceAdditionalOption.objects.filter(conference=self.conference).exclude(pk=self.instance.pk)
+
+               self.update_protected_fields()
index 19d55c0a4b16e1caac7edd971b5b2438428d4c5f..b79742037e1a2499b3d75f8d21ad3c5349041a0b 100644 (file)
@@ -20,7 +20,7 @@ from backendforms import BackendRegistrationTypeForm, BackendRegistrationClassFo
 from backendforms import BackendRegistrationDayForm, BackendAdditionalOptionForm
 from backendforms import BackendTrackForm, BackendRoomForm, BackendConferenceSessionForm
 from backendforms import BackendConferenceSessionSlotForm, BackendVolunteerSlotForm
-from backendforms import BackendFeedbackQuestionForm
+from backendforms import BackendFeedbackQuestionForm, BackendDiscountCodeForm
 
 def get_authenticated_conference(request, urlname):
        if not request.user.is_authenticated:
@@ -278,3 +278,11 @@ def edit_feedbackquestions(request, urlname, rest):
                                                           rest,
                                                           allow_new=True,
                                                           allow_delete=True)
+
+def edit_discountcodes(request, urlname, rest):
+       return backend_list_editor(request,
+                                                          urlname,
+                                                          BackendDiscountCodeForm,
+                                                          rest,
+                                                          allow_new=True,
+                                                          allow_delete=True)
index e47506e4c90e2e1410169aa9c06aee0a258370cf..face8b3bd270b3ca9e4d03610c8f9864632e2370 100644 (file)
@@ -30,7 +30,7 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='discountcode',
             name='discountamount',
-            field=models.DecimalField(max_digits=10, decimal_places=2),
+            field=models.DecimalField(max_digits=10, decimal_places=2, default=0),
         ),
         migrations.AlterField(
             model_name='registrationtype',
index cda6b3fcbf04b629df5ba891b3b8e430728f8c43..c53efc19567d6d6f12438d28a0e6f3c48845d357 100644 (file)
@@ -824,7 +824,7 @@ class PrepaidVoucher(models.Model):
 class DiscountCode(models.Model):
        conference = models.ForeignKey(Conference, null=False, blank=False)
        code = models.CharField(max_length=100, null=False, blank=False)
-       discountamount = models.DecimalField(decimal_places=2, max_digits=10, null=False)
+       discountamount = models.DecimalField(decimal_places=2, max_digits=10, null=False, default=0)
        discountpercentage = models.IntegerField(null=False, blank=False, default=0)
        regonly = models.BooleanField(null=False, blank=False, default=False, help_text="Apply percentage discount only to the registration cost, not additional options. By default, it's applied to both.")
        validuntil = models.DateField(blank=True, null=True)
index aaff6c39b33eccbb3e4a3125249ef9d7d61c1bd3..f42ac37a8d4fbbe933ec58e1d8558cb49076d942 100644 (file)
@@ -148,6 +148,7 @@ urlpatterns = [
        url(r'^events/admin/(\w+)/scheduleslots/(.*/)?$', postgresqleu.confreg.backendviews.edit_scheduleslots),
        url(r'^events/admin/(\w+)/volunteerslots/(.*/)?$', postgresqleu.confreg.backendviews.edit_volunteerslots),
        url(r'^events/admin/(\w+)/feedbackquestions/(.*/)?$', postgresqleu.confreg.backendviews.edit_feedbackquestions),
+       url(r'^events/admin/(\w+)/discountcodes/(.*/)?$', postgresqleu.confreg.backendviews.edit_discountcodes),
 
        url(r'^events/sponsor/', include('postgresqleu.confsponsor.urls')),
 
index 37d09aed84f858495e2dee48ea6fcbbac3c859d4..44236289c53db9b30ea309275a49df62106bb002 100644 (file)
@@ -57,7 +57,7 @@
 <h2>Prepaid vouchers and discount codes</h2>
 <div class="row">
   <div class="col-md-3 col-sm-6 col-xs-12 buttonrow"><a class="btn btn-default btn-block" href="/events/admin/{{c.urlname}}/prepaid/list/">Prepaid vouchers</a></div>
-  <div class="col-md-3 col-sm-6 col-xs-12 buttonrow"><a class="btn btn-default btn-block" href="/admin/confreg/discountcode/?conference__id__exact={{c.id}}">Discount codes</a></div>
+  <div class="col-md-3 col-sm-6 col-xs-12 buttonrow"><a class="btn btn-default btn-block" href="/events/admin/{{c.urlname}}/discountcodes/">Discount codes</a></div>
 </div>
 
 <h2>Metadata</h2>