Reputation: 335
I have a django model for my invoices.
Now I need to generate unique invoice numbers for each day (in my Django Views function).
Example, invoice no, for 7th April, 2016 shall be like: 16040701, 16040702, 16040703, etc.
How can this be achieved?
Upvotes: 0
Views: 2232
Reputation: 9
class SerialNumberField(CharField):
_for = None
def __init__(self, *args, **kwargs):
self._for = kwargs.pop('_for', None)
kwargs.setdefault('max_length', 20)
kwargs.setdefault('editable', False)
super().__init__(*args, **kwargs)
def contribute_to_class(self, cls, name):
super().contribute_to_class(cls, name)
self.model = cls
def generate_serial_number(self):
today = timezone.now().date()
today_obj = self.model.objects.filter(created_date=today)
count = today_obj.count() + 1
return f"#{self._for}{today.strftime('%Y%m%d')}-{count:03d}"
def pre_save(self, model_instance, add):
if not getattr(model_instance, self.attname):
setattr(model_instance, self.attname, self.generate_serial_number())
return super().pre_save(model_instance, add)
This field is simple to use as a serialnumberfield no need of maintaining the last bill count to put the next bill.
Upvotes: 0
Reputation: 638
I would do this by overriding save() in your Invoice model. First, add a field for your invoice number to your model:
invoice_id = models.CharField(blank=True, max_length=8)
Then, override the save() method:
def save(self, *args, **kwargs):
today = datetime.date.today()
today_string = today.strftime('%y%m%d')
next_invoice_number = '01'
last_invoice = Invoice.objects.filter(invoice_id__startswith=today_string).order_by('invoice_id').last()
if last_invoice:
last_invoice_number = int(last_invoice.invoice_id[6:])
next_invoice_number = '{0:02d}'.format(last_invoice_number + 1)
self.invoice_id = today_string + next_invoice_number
super(Invoice, self).save(*args, **kwargs)
This will give you the format yymmdd##
that you are looking for. Note: this will not work if you have more than 99 invoices per day. If you needed more than 99, change {0:02d}
to {0:03d}
and set max_length=9
on your invoice_id field. This will accommodate 999 invoices per day with the format yymmdd###
.
Upvotes: 2