diff --git a/src/pretix/api/serializers/event.py b/src/pretix/api/serializers/event.py index 34afa9ef5d..7c1c739d45 100644 --- a/src/pretix/api/serializers/event.py +++ b/src/pretix/api/serializers/event.py @@ -597,6 +597,7 @@ class EventSettingsSerializer(serializers.Serializer): 'invoice_numbers_consecutive', 'invoice_numbers_prefix', 'invoice_numbers_prefix_cancellations', + 'invoice_numbers_counter_length', 'invoice_attendee_name', 'invoice_include_expire_date', 'invoice_address_explanation_text', diff --git a/src/pretix/base/models/invoices.py b/src/pretix/base/models/invoices.py index e617dc8d05..1692ac2895 100644 --- a/src/pretix/base/models/invoices.py +++ b/src/pretix/base/models/invoices.py @@ -116,8 +116,8 @@ class Invoice(models.Model): objects = ScopedManager(organizer='event__organizer') @staticmethod - def _to_numeric_invoice_number(number): - return '{:05d}'.format(int(number)) + def _to_numeric_invoice_number(number, places): + return ('{:0%dd}' % places).format(int(number)) @property def full_invoice_from(self): @@ -173,7 +173,7 @@ class Invoice(models.Model): ] return '\n'.join([p.strip() for p in parts if p and p.strip()]) - def _get_numeric_invoice_number(self): + def _get_numeric_invoice_number(self, c_length): numeric_invoices = Invoice.objects.filter( event__organizer=self.event.organizer, prefix=self.prefix, @@ -182,7 +182,7 @@ class Invoice(models.Model): ).aggregate( max=Max('numeric_number') )['max'] or 0 - return self._to_numeric_invoice_number(numeric_invoices + 1) + return self._to_numeric_invoice_number(numeric_invoices + 1, c_length) def _get_invoice_number_from_order(self): return '{order}-{count}'.format( @@ -209,7 +209,7 @@ class Invoice(models.Model): self.prefix += 'TEST-' for i in range(10): if self.event.settings.get('invoice_numbers_consecutive'): - self.invoice_no = self._get_numeric_invoice_number() + self.invoice_no = self._get_numeric_invoice_number(self.event.settings.invoice_numbers_counter_length) else: self.invoice_no = self._get_invoice_number_from_order() try: diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index e176198a06..a73b8823c3 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -309,6 +309,16 @@ DEFAULTS = { help_text=_("The expiration date will not be shown if the invoice is generated after the order is paid."), ) }, + 'invoice_numbers_counter_length': { + 'default': '5', + 'type': int, + 'form_class': forms.IntegerField, + 'serializer_class': serializers.IntegerField, + 'form_kwargs': dict( + label=_("Minimum length of invoice number after prefix"), + help_text=_("The part of your invoice number after your prefix will be filled up with leading zeros up to this length, e.g. INV-001 or INV-00001."), + ) + }, 'invoice_numbers_consecutive': { 'default': 'True', 'type': bool, diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index d0e6750852..350063623c 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -677,6 +677,7 @@ class InvoiceSettingsForm(SettingsForm): 'invoice_numbers_consecutive', 'invoice_numbers_prefix', 'invoice_numbers_prefix_cancellations', + 'invoice_numbers_counter_length', 'invoice_address_explanation_text', 'invoice_email_attachment', 'invoice_address_from_name', diff --git a/src/pretix/control/templates/pretixcontrol/event/invoicing.html b/src/pretix/control/templates/pretixcontrol/event/invoicing.html index 85409aa64c..41a300065f 100644 --- a/src/pretix/control/templates/pretixcontrol/event/invoicing.html +++ b/src/pretix/control/templates/pretixcontrol/event/invoicing.html @@ -19,6 +19,7 @@ {% bootstrap_field form.invoice_numbers_consecutive layout="control" %} {% bootstrap_field form.invoice_numbers_prefix layout="control" %} {% bootstrap_field form.invoice_numbers_prefix_cancellations layout="control" %} + {% bootstrap_field form.invoice_numbers_counter_length layout="control" %}