Fix #1080 -- Deal with gaps in the invoice database (#1086)

This commit is contained in:
Raphael Michel
2018-11-20 10:36:13 +01:00
committed by GitHub
parent 1cba4b1d45
commit c93f804992
2 changed files with 18 additions and 5 deletions

View File

@@ -2,6 +2,8 @@ import string
from decimal import Decimal from decimal import Decimal
from django.db import DatabaseError, models, transaction from django.db import DatabaseError, models, transaction
from django.db.models import Max
from django.db.models.functions import Cast
from django.utils import timezone from django.utils import timezone
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.functional import cached_property from django.utils.functional import cached_property
@@ -124,8 +126,12 @@ class Invoice(models.Model):
numeric_invoices = Invoice.objects.filter( numeric_invoices = Invoice.objects.filter(
event__organizer=self.event.organizer, event__organizer=self.event.organizer,
prefix=self.prefix, prefix=self.prefix,
).exclude(invoice_no__contains='-') ).exclude(invoice_no__contains='-').annotate(
return self._to_numeric_invoice_number(numeric_invoices.count() + 1) numeric_number=Cast('invoice_no', models.IntegerField())
).aggregate(
max=Max('numeric_number')
)['max'] or 0
return self._to_numeric_invoice_number(numeric_invoices + 1)
def _get_invoice_number_from_order(self): def _get_invoice_number_from_order(self):
return '{order}-{count}'.format( return '{order}-{count}'.format(
@@ -183,7 +189,7 @@ class Invoice(models.Model):
class Meta: class Meta:
unique_together = ('organizer', 'prefix', 'invoice_no') unique_together = ('organizer', 'prefix', 'invoice_no')
ordering = ('invoice_no',) ordering = ('date', 'invoice_no',)
class InvoiceLine(models.Model): class InvoiceLine(models.Model):

View File

@@ -294,20 +294,27 @@ def test_invoice_numbers(env):
event.settings.set('invoice_numbers_consecutive', True) event.settings.set('invoice_numbers_consecutive', True)
inv5 = generate_invoice(order) inv5 = generate_invoice(order)
inv6 = generate_invoice(order)
inv7 = generate_invoice(order)
Invoice.objects.filter(pk=inv6.pk).delete() # This should never ever happen, but what if it happens anyway?
inv8 = generate_invoice(order)
inv23 = generate_invoice(order2) inv23 = generate_invoice(order2)
# expected behaviour for switching between numbering formats # expected behaviour for switching between numbering formats or dealing with gaps
assert inv1.invoice_no == '00001' assert inv1.invoice_no == '00001'
assert inv2.invoice_no == '00002' assert inv2.invoice_no == '00002'
assert inv3.invoice_no == '{}-3'.format(order.code) assert inv3.invoice_no == '{}-3'.format(order.code)
assert inv4.invoice_no == '{}-4'.format(order.code) assert inv4.invoice_no == '{}-4'.format(order.code)
assert inv5.invoice_no == '00003' assert inv5.invoice_no == '00003'
assert inv6.invoice_no == '00004'
assert inv7.invoice_no == '00005'
assert inv8.invoice_no == '00006'
# test that separate orders are counted separately in this mode # test that separate orders are counted separately in this mode
assert inv21.invoice_no == '{}-1'.format(order2.code) assert inv21.invoice_no == '{}-1'.format(order2.code)
assert inv22.invoice_no == '{}-2'.format(order2.code) assert inv22.invoice_no == '{}-2'.format(order2.code)
# but consecutively in this mode # but consecutively in this mode
assert inv23.invoice_no == '00004' assert inv23.invoice_no == '00007'
# test Invoice.number, too # test Invoice.number, too
assert inv1.number == '{}-00001'.format(event.slug.upper()) assert inv1.number == '{}-00001'.format(event.slug.upper())