Create A Running Number
Tags: laravel, runningnumber
Published: 2021-10-19 12:56:32

You may come across, to have a running number, case id or reference number of your records, so that you can easily remember them - especially to your users. This can come in various formatting. 

But today I'm going to show you how simplest setup could help you save a day. Mine save more minutes, since this already few projects implemented - I just don't have to the time to make it as a package.

Now, let's assuming you want to create with the following format:

A-21-00001 where A is your record reference abbreviation / prefix, 21 is the year, and 00001 is your running number / reference / case id.


### Model & Migration

```bash
php artisan make:model RunningNumber -m
```

This will create a new model & migration. Just update the model & migration as following:

```php
<?php 

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class RunningNumber extends Model
{
    const TYPES = [
        'approval',
        'reject',
    ];

    const TYPE_PREFIX = [
        'approval' => 'APRV', 
        'reject' => 'RJCT',
    ];
}
```

```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateRunningNumberTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('running_numbers', function (Blueprint $table) {
            $table->id();
            $table->year('year');
            $table->unsignedInteger('number')->default(0);
            $table->string('type')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('running_numbers');
    }
}
```

Now you are done for model setup for Running Number.

### The Generator

Next, from your model, we need a method to be call, to generate the running number for your records.

Let's add the following snippet in the `RunningNumber` model:

```php
    public static function generate(string $type)
    {
        $type = strtoupper($type);
        if (! in_array($type, self::TYPES)) {
            throw new \Exception('Undefined running number type.');
        }
        $number = 0;
        $year = date('Y');
        if (! RunningNumber::where('type', $type)->where('year', $year)->exists()) {
            RunningNumber::create([
                'type' => $type,
                'number' => $number,
                'year' => $year,
            ]);
        }

        $running_number = RunningNumber::where('type', $type)->where('year', $year)->first();
        $running_number->number++;
        $running_number->save();
        $number = $running_number->number;
        $number = str_pad($number, 5, '0', STR_PAD_LEFT);

        // A-21-00001
        return RunningNumber::TYPE_PREFIX[$type].'-'.date('y').'-'.$number;
    }
```

### Usage

Once you are done, you may don't want your records to manually trigger above method. You can do the following in your records model:

```php
<?php 

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Submission extends Model
{
    protected static function booted()
    {
        static::creating(function ($submission) {
            $submission->case_id = RunningNumber::generate($submission->type);
        });
    }
}
```

### Conclusion

So that how I do basically generate the running number / reference numbers in some of projects. 

> I skipped writing Unit Test! Ops!

Photo by <a href="https://unsplash.com/@austris_a?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Austris Augusts</a> on <a href="https://unsplash.com/s/photos/running-number?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>