Skip to main content

Moving Customers through Pipeline Stages

Premium
4 min read

Currently, we have Customers and Pipeline Stages in our system. Still, there is no easy way to move our Customers within the Pipeline while saving its history. Let's fix that by adding a table Action:

In this lesson, we will do the following:

  • Create a CustomerPipelineStage Model to save the history of the Customer's Pipeline Stage changes and any comments added.
  • Add a custom Table Action to move customers to other pipeline stages.
  • Add creating and updating action Observers to our Customer Model to save the history.

Creating Logs Model and Table

Our CustomerPipelineStage Model will be a simple table with the following fields:

  • customer_id - the Customer ID
  • pipeline_stage_id (nullable) - the Pipeline Stage ID. It is nullable to allow notes without status change.
  • user_id (nullable) - the User who made the change. It is nullable to allow system-triggered changes to be logged.
  • notes (nullable, text) - any notes added to the change

Let's create the Migration:

Migration

use App\Models\Customer;
use App\Models\PipelineStage;
use App\Models\User;
 
// ...
 
Schema::create('customer_pipeline_stages', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Customer::class)->constrained();
$table->foreignIdFor(PipelineStage::class)->nullable()->constrained();
$table->foreignIdFor(User::class)->nullable()->constrained();
$table->text('notes')->nullable();
$table->timestamps();
});

Next, we will create the Model:

app/Models/CustomerPipelineStage.php

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
class CustomerPipelineStage extends Model
{
protected $fillable = [
'customer_id',
'pipeline_stage_id',
'user_id',
'notes'
];
 
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
 
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
 
public function pipelineStage(): BelongsTo
{
return $this->belongsTo(PipelineStage::class);
}
}

And finally, we will add the relationship to our Customer Model:

app/Models/Customer.php

use Illuminate\Database\Eloquent\Relations\HasMany;
 
// ...
 
public function pipelineStageLogs(): HasMany
{
return $this->hasMany(CustomerPipelineStage::class);
}

That's it. We can run:

php artisan migrate:fresh --seed

And have the Database table ready for our customer logs.


Creating Table Action

Now that we have our Database and Models ready, we can...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (30 h 01 min)

You also get:

55 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

MR
Martin Radu ✓ Link copied!

before Creating Table Action you need to run php artisan migrate:fresh --seed the Creating Table Action it's done in the app\Filament\Resources\CustomerResource.php file

M
Modestas ✓ Link copied!

Updated to better reflect that migration is needed!

SP
Steve Purcell ✓ Link copied!

Could someone explain what the observer is doing here? Is it logging the pipeline change somewhere other than in the model? I have not used observers much or at all.

Thanks

M
Modestas ✓ Link copied!

Observers are meant to observe Models events (ex. created, updated). In our case, we are observing the Created event and creating new log item from this. This allows you to create the Customer from anywhere using Customer::create(); and it will always have the first log item created

A
anjanesh ✓ Link copied!

So this is equilavent to a MySQL trigger ?

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.