Auto increament the invoice number in django backend for new invoice
Asked Answered
A

5

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.

Acidic answered 28/1, 2015 at 17:43 Comment(3)
Nothing i searched for it but did not got anything.Acidic
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.Matriculation
Ok Sure i am trying for it. thanks for adviceAcidic
H
18

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.

Hippolytus answered 28/1, 2015 at 18:10 Comment(7)
Where do i need to put this function? in views or models?Acidic
getting error ImportError: cannot import name InvoiceAcidic
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.Nyaya
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?Acidic
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.Nyaya
remove the () on the default function callNyaya
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. :-(Czardas
A
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.

Acidic answered 29/1, 2015 at 4:54 Comment(0)
N
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.

Nyaya answered 28/1, 2015 at 17:56 Comment(1)
had to remove () on the default=invoiceIncrementNyaya
N
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
Number answered 26/12, 2015 at 9:54 Comment(0)
B
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)
Buford answered 11/11, 2021 at 4:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.