Tutorial last revisioned on March 17, 2024 with Laravel 11
When working with invoices, you need to deal with serial numbers that look like ABC-000001. Do you know how to auto-generate them in Laravel? This tutorial will cover a few ways to do this.

DB Structure
For our example, we will use a simple invoice DB table with the following columns:
-
id -
user_id -
due_date -
amount -
serial- Full serial number likeABC-1 -
serial_number- Serial number like1 -
serial_series- Serial series likeABC
Here's how that looks in our migration:
Migration
Schema::create('invoices', function (Blueprint $table) { $table->id(); $table->foreignIdFor(User::class)->constrained(); $table->date('due_date'); $table->integer('amount'); $table->string('serial')->nullable(); $table->string('serial_series'); $table->integer('serial_number')->nullable(); $table->timestamps();});
This makes our Model look like this:
app/Models/Invoice.php
use Illuminate\Database\Eloquent\Casts\Attribute;use Illuminate\Database\Eloquent\Factories\HasFactory;use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Relations\BelongsTo; class Invoice extends Model{ use HasFactory; protected $fillable = [ 'user_id', 'due_date', 'amount', 'serial', 'serial_number', 'serial_series', ]; protected function amount(): Attribute { return Attribute::make( get: fn($value) => $value / 100, set: fn($value) => $value * 100, ); } public function user(): BelongsTo { return $this->belongsTo(User::class); }}
Create Invoice: Form
Let's create the Controller methods to save a new invoice and auto-generate the serial number.
This is the form, with series options coming from the config.
app/Http/Controllers/InvoiceController.php
use App\Http\Requests\StoreInvoiceRequest;use App\Models\Invoice;use App\Models\User; class InvoiceController extends Controller{ public function create() { $users = User::pluck('name', 'id'); $invoiceSeries = config('invoiceSettings.availableInvoiceSeries'); return view('invoices.create', [ 'users' => $users, 'invoiceSeries' => $invoiceSeries, ]); }}
These are the config values:
config/invoiceSettings.php
return [ 'availableInvoiceSeries' => [ 'ABC', 'DAF', 'GHI', 'UKS' ],];
And here's the form in...
Premium Members Only
This advanced tutorial is available exclusively to Laravel Daily Premium members.
Already a member? Login here
Premium membership includes:
Comments & Discussion
Verry usefull, i found this for primary, would this avoid using the job? I mean if some of the columns used is autoincrement. https://laravel.com/api/10.x/Illuminate/Database/Schema/Blueprint.html#method_primary
The main purpose of the job is not only to avoid the issue with repeating numbers, but to also solve the problem of re-trying the job.
Imagine, you have an index that's unique (mentioned in 3rd option) and when trying to create the invoice - it fails. Then you have to manually re-try the saving with a new number. Job does by itself.
Also, auto-increment is okay, but it would not be PER each of the series, so that causes other issues where gaps will appear. And gaps are pretty bad!
Is there a way to make it restart every year? 0001-2022 0002-2022 .... 0160-2022 0001-2023
yes!
Set your serial series to the year and that's it!
For example in config file set it to now("Y")
like this?
return [ 'availableInvoiceSeries' => [ now("Y"); ], ];
Yes, just without typos:
Of course, this will be the only selection in the dropdown, but you can make it a hidden field instead of select (if you don't need to select the series)
thank you very much for your help
Hello
Hi,