6

I want to auto increament the invoice number which is 3 digits char and 4 digits number.

class Invoice:
    invoice_no = models.CharField(max_length=500, null=True, blank=True, validators=[RegexValidator(regex='^[a-zA-Z0-9]*$',message='Invoice must be Alphanumeric',code='invalid_invoice number'),])

I register this model in backend. But now when i click on create invoice in admin the invoice should be auto filled. When i again click on create new invoice in admin, the invoice_number should be incremented by one and should be auto field.

Ex for Invoice number MAG0001, MAG0002, MAG0003 etc and this should be auto field in admin when i click on create new invoice.

Wagh
  • 4,202
  • 5
  • 39
  • 62
  • Nothing i searched for it but did not got anything. – Wagh Jan 28 '15 at 17:54
  • 1
    Not to be rude, and I can't speak for everyone, but a lot of contributors to Stack Overflow are much more willing to help someone that has put some effort into solving the issue at hand. My best advice would be to try to solve the problem on your own first, and if you're still having issues, then ask a question here. – Brandon Taylor Jan 28 '15 at 17:56
  • Ok Sure i am trying for it. thanks for advice – Wagh Jan 28 '15 at 17:58

5 Answers5

17

Define a function to generate invoice number.

def increment_invoice_number():
    last_invoice = Invoice.objects.all().order_by('id').last()
    if not last_invoice:
         return 'MAG0001'
    invoice_no = last_invoice.invoice_no
    invoice_int = int(invoice_no.split('MAG')[-1])
    new_invoice_int = invoice_int + 1
    new_invoice_no = 'MAG' + str(new_invoice_int).zfill(4)
    return new_invoice_no

Now use this function as default value in your model filed.

invoice_no = models.CharField(max_length=500, default=increment_invoice_number, null=True, blank=True)

This is just an idea. Modify the function to match your preferred invoice number format.

sanbinary
  • 81
  • 1
  • 8
arulmr
  • 8,620
  • 9
  • 54
  • 69
  • Where do i need to put this function? in views or models? – Wagh Jan 28 '15 at 18:25
  • getting error ImportError: cannot import name Invoice – Wagh Jan 28 '15 at 18:29
  • the function must go above your model class, or be included in the model.py file at the top. Also note my answer as this one has the same issues as mine. – warath-coder Jan 28 '15 at 18:51
  • if its above model class then its not recognizing the Invoice class in last_invoice = Invoice.objects.all().order_by('id').last() this line. What is the solution for this? – Wagh Jan 29 '15 at 03:34
  • not sure how to get around that... why not save the last invoice ID in another table/model and fetch it from there, would add another call/save to db however. – warath-coder Jan 29 '15 at 04:23
  • remove the `()` on the default function call – warath-coder Jan 29 '15 at 04:44
  • Having used such logic, I can now affirm that this breaks on have traffic sites. The numbering will not sort, 4 digits is too few, and you risk getting duplicate numbers. :-( – vdboor Jun 09 '15 at 14:51
4

In above arulmr answer just edit char field

def increment_invoice_number():
    last_invoice = Invoice.objects.all().order_by('id').last()
    if not last_invoice:
        return 'MAG0001'
    invoice_no = last_invoice.invoice_no
    invoice_int = int(invoice_no.split('MAG')[-1])
    width = 4
    new_invoice_int = invoice_int + 1
    formatted = (width - len(str(new_invoice_int))) * "0" + str(new_invoice_int)
    new_invoice_no = 'MAG' + str(formatted)
    return new_invoice_no  

class Invoice(models.Model):
    invoice_no = models.CharField(max_length = 500, default = increment_invoice_number, null = True, blank = True)

This will work fine.

Wagh
  • 4,202
  • 5
  • 39
  • 62
3
def invoiceIncrement():
    get_last_invoice_number
    incremente_last_invoice_number
    return next_invoice_number

class Invoice:
    invoice_no = models.CharField(max_length=500, null=True, blank=True, 
        validators=[RegexValidator(regex='^[a-zA-Z0-9]*$',
        message='Invoice must be Alphanumeric',code='invalid_invoice number'),], 
        default=invoiceIncrement)

Try this: there are some obvious issues:

  1. if more than one person adds an invoice at the same time, could have collision

  2. will need to make an extra db call each time you create a new invoice.

Also: you may want to just consider using either an auto_increment or UUID.

warath-coder
  • 2,087
  • 1
  • 17
  • 21
1

Maybe this code can help

def increment_invoice_number():
    last_invoice = Invoice.objects.all().order_by('id').last()
    if not last_invoice:
        return 'MAG0001'
    invoice_no = last_invoice.invoice_no
    new_invoice_no = str(int(invoice_no[4:]) + 1)
    new_invoice_no = invoice_no[0:-(len(new_invoice_no))] + new_invoice_no
    return new_invoice_no
0
def invoice_number_gen():
   last_invoice = Invoice.objects.all().order_by('id').last()
   last_invoice_number = last_invoice.invoice_no
   #invoice number format is 'customer_name_short + number' eg: CS003 
   last_invoice_digits =int(last_invoice_number[2:]) 
   #comment: slicing CS003 to get the number 003 and converting to int.
   last_invoice_initials = last_invoice_number[:2]              
   new_invoice_digits = last_invoice_digits + 1
   new_invoice_number = last_invoice_initials + str(new_invoice_digits)
   return (new_invoice_number)
Sangeeth Joseph
  • 152
  • 1
  • 8