Skip to main content

Create Customer Quotes with Products

Premium
10 min read

Next, we will dive deeper into a specific CRM use case: Products and Quotes. In this lesson, we will start creating our simple Products and allow users to create Quotes that later we will turn into a PDF. Here's what our Products and Quotes will look like:

In this lesson, we will do the following:

  • Create a Product Model, Database Table, and CRUD
  • Create a Quote Model, Database Table, and CRUD
  • Create a complex Quote create/edit form with real-time calculations
  • Create an action button on the Customer list to create a Quote
  • Modify how our Customer actions look like

Creating the Product Model

Our first task is to create a Product table in the database so that we would have something to sell:

Migration

Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->integer('price');
$table->timestamps();
});

Next, let's work on the Model:

app/Models/Product.php

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
class Product extends Model
{
use HasFactory;
 
protected $fillable = ['name', 'price'];
 
protected function price(): Attribute
{
return Attribute::make(
get: static fn($value) => $value / 100,
set: static fn($value) => $value * 100,
);
}
}

Lastly, for our Database setup, we need a seeder:

database/seeders/DatabaseSeeder.php

use App\Models\Product;
 
// ...
 
public function run(): void
{
// ...
 
$products = [
['name' => 'Product 1', 'price' => 12.99],
['name' => 'Product 2', 'price' => 2.99],
['name' => 'Product 3', 'price' => 55.99],
['name' => 'Product 4', 'price' => 99.99],
['name' => 'Product 5', 'price' => 1.99],
['name' => 'Product 6', 'price' => 12.99],
['name' => 'Product 7', 'price' => 15.99],
['name' => 'Product 8', 'price' => 29.99],
['name' => 'Product 9', 'price' => 33.99],
['name' => 'Product 10', 'price' => 62.99],
['name' => 'Product 11', 'price' => 42.99],
['name' => 'Product 12', 'price' => 112.99],
['name' => 'Product 13', 'price' => 602.99],
['name' => 'Product 14', 'price' => 129.99],
['name' => 'Product 15', 'price' => 1200.99],
];
 
foreach ($products as $product) {
Product::create($product);
}
}

Then running php artisan migrate:fresh --seed will give us a simple set of products to test the system.


Creating Product Resource

Next, we want to manage the products using Filament, so let's create a new resource:

php artisan make:filament-resource Product --generate

This will generate all of our Resource files. This time, we...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (36 h 00 min)

You also get:

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

Already a member? Login here

Marc-Antoine Favreau avatar
Marc-Antoine Favreau

I've updated to PHP 8.3 and disabled lazy loading and now I have lazy loading issues with the product name in the product-quote-list.blade.php, anybody else is having this issue or did I messed something else?

The error : Attempted to lazy load [product] on model [App\Models\ProductQuote] but lazy loading is disabled.

Modestas avatar

It might have been there at the start, will have to take a look to see what causes it. Thanks for reporting!

Modestas avatar

Hi, sorry for overdue reply - I have checked the project with LazyLoading prevented and it seems to function just fine. I was unable to find any issues with this.

Could you provide more details on your issue? Especially from where did the file product-quote-list.blade.php came from, as we are also unable to find this in our project

Strongs avatar

Hi. In principle, could you use this lesson and the last one to create a printable list of users loaded onto an event? I'm having issues finding a solution in filament for just that and this could be my saviour! Great course by the way

Modestas avatar

In theory - yes, this can be done. But I'm not sure exactly as I haven't played around with printable lists at all

Strongs avatar

Thanks. I will give it a go and if I get anything workable, I will post back here.