Browse Source

Fix invoice number on sequence of previous month

If an invoice 2016-09-0000001 existed, when validating an invoice in 10/2016, it
was continuing the september serie, being numbered 2016-09-000002 instead of
being 2016-10-000001.
Jocelyn Delalande 8 years ago
parent
commit
8c513c8e5a
2 changed files with 26 additions and 2 deletions
  1. 15 1
      coin/billing/models.py
  2. 11 1
      coin/billing/tests.py

+ 15 - 1
coin/billing/models.py

@@ -67,6 +67,19 @@ class InvoiceNumber:
                 day=1),
             int(m.group('index')))
 
+    @staticmethod
+    def time_sequence_filter(date, field_name='date'):
+        """ Build queryset filter to be used to get the invoices from the
+        numbering sequence of a given date.
+
+        :param field_name: the invoice field name to filter on.
+
+        :type date: datetime
+        :rtype: dict
+        """
+
+        return {'{}__month'.format(field_name): date.month}
+
 
 class InvoiceQuerySet(models.QuerySet):
     def get_next_invoice_number(self, date):
@@ -81,7 +94,8 @@ class InvoiceQuerySet(models.QuerySet):
         return str(invoice_number)
 
     def _get_last_invoice_number(self, date):
-        return self.with_valid_number().aggregate(
+        same_seq_filter = InvoiceNumber.time_sequence_filter(date)
+        return self.filter(**same_seq_filter).with_valid_number().aggregate(
             models.Max('number'))['number__max']
 
     def with_valid_number(self):

+ 11 - 1
coin/billing/tests.py

@@ -226,12 +226,22 @@ class BillingTests(TestCase):
 
 
 class InvoiceQuerySetTests(TestCase):
-    def test_get_first_of_month_invoice_number(self):
+    def test_get_first_invoice_number_ever(self):
         self.assertEqual(
             Invoice.objects.get_next_invoice_number(datetime.date(2016,1,1)),
             '2016-01-000001')
 
     @freeze_time('2016-01-01')
+    def test_get_first_of_month_invoice_number(self):
+        # One bill on a month…
+        Invoice.objects.create().validate()
+
+        # … Does not affect the numbering of following month.
+        self.assertEqual(
+            Invoice.objects.get_next_invoice_number(datetime.date(2016,2,15)),
+            '2016-02-000001')
+
+    @freeze_time('2016-01-01')
     def test_number_workflow(self):
         iv = Invoice.objects.create()
         self.assertEqual(iv.number, 'DRAFT-1')