Skip links

Creating a CRM in Laravel

In this article, we will learn how to create a starter CRM in laravel. I will guide you step by step, command by command on how to create a CRM with a scalable database structure. All of this code is available on GitHub, feel free to download & extend.

View Source Code on Github

Step 1 – Create Laravel project

// type this command in terminal
composer create-project --prefer-dist laravel/laravel starterCRM

Step 2 – Plan Database Structure

This is just a visual presentation of how our tables will look like.

Step 3 – Install Login UI

make sure you are in a laravel folder before you install laravel/ui

cd starterCRM
composer require laravel/ui --dev
php artisan ui bootstrap --auth

// Install Dependencies 
sudo npm install && npm run dev

Step 4 – Create a database and connect with your laravel application

You can use xampp from apachefriends.org to install PHP/MySQL to your machine. or you can also install MySQL directly on your machine. However, for beginners, xampp is the easiest solution for installing PHP and MySQL.

Create a new MySQL database starterCRM

Open laravel project on your text editor and edit .env file.

Find DB_DATABASE and add your database details along with DB_USERNAME and DB_PASSWORD. on xampp default username is root and password is empty.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=starterCRM
DB_USERNAME=root
DB_PASSWORD=

Step 5 – Run Laravel UI Migrations, open terminal and type following command

php artisan migrate

php artisan migrate command will create following tables

Step 6 – Create Model, Controller & Migrations

php artisan make:model services -mcr
php artisan make:model lead -mcr
php artisan make:model clients -mcr 
php artisan make:model leadDetails -mcr
php artisan make:model todo -mcr
php artisan make:model statusUpdates -mcr 

these commands will create models, controllers and migrations for services, lead, clients, leadDetails, todo and statusUpdates.

  • Models will be created in app/Models folder
  • Controllers will be created in the app/Http folder
  • Migrations will be created in the database/migrations folder

You can check the respective folders and find those files.

// Output will be similar to this, just timestamps would differ

Model created successfully.
Created Migration: 2021_11_30_062540_create_services_table
Controller created successfully.
Model created successfully.
Created Migration: 2021_11_30_062541_create_leads_table
Controller created successfully.
Model created successfully.
Created Migration: 2021_11_30_062542_create_clients_table
Controller created successfully.
Model created successfully.
Created Migration: 2021_11_30_062542_create_lead_details_table
Controller created successfully.
Model created successfully.
Created Migration: 2021_11_30_062543_create_todos_table
Controller created successfully.
Model created successfully.
Created Migration: 2021_11_30_062544_create_status_updates_table
Controller created successfully.

Step 7 – Create Database Schema

Let’s first create a schema for the services table. Open migration file for services that we created in the last step.

The current code should be like this. We will add schema between $table->id() and $table->timestamps();

<?php

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

class CreateServicesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('services', function (Blueprint $table) {
            $table->id();

            // we will add our code here
            $table->string('name');
            $table->text('description')->nullable();
            $table->integer('price')->nullable();
            $table->foreignId('user_id');
            // our code ends 

            $table->timestamps();
        });
    }

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

Similarly, add the following code to leads migration

 public function up()
    {
        Schema::create('leads', function (Blueprint $table) {
            $table->id();
            $table->foreignId('client_id');
            $table->text('requirement')->nullable();
            $table->string('estimatedBudget')->nullable();
            $table->date('startDate')->nullable();
            $table->date('endDate')->nullable();
            $table->enum('status', ['In Progress', 'Order Generated', 'On Hold', 'Cancelled', 'Not Eligible'])->default('In Progress');
            $table->foreignId('user_id');
            $table->timestamps();
        });
    }

Now, add the following code to clients migrtaion

 public function up()
    {
        Schema::create('clients', function (Blueprint $table) {
            $table->id();
            $table->string('fullName');
            $table->string('email')->nullable();
            $table->string('phone')->nullable();
            $table->string('address')->nullable();
            $table->string('taxId')->nullable();
            $table->string('source')->nullable();
            $table->text('notes')->nullable();
            $table->foreignId('user_id')->nullable();
            $table->timestamps();
        });
    }

Now, add the following code to the lead_details migration

 public function up()
    {
        Schema::create('lead_details', function (Blueprint $table) {
            $table->id();
            $table->foreignId('lead_id');
            $table->foreignId('service_id');
            $table->integer('quantity')->default(1);
            $table->text('notes')->nullable();
            $table->timestamps();
        });
    }

Now, add the following code to the todo migration

 public function up()
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('description')->nullable();
            $table->date('dueDate')->nullable();
            $table->boolean('status')->default(0);
            $table->foreignId('user_id');
            $table->foreignId('lead_id')->nullable();
            $table->timestamps();
        });
    }

finall, add the following code to the status_updates migration

  public function up()
    {
        Schema::create('status_updates', function (Blueprint $table) {
            $table->id();
            $table->foreignid('lead_id')->nullable();
            $table->string('notes');
            $table->boolean('status')->default(0);
            $table->foreignId('user_id');
            $table->timestamps();
        });
    }

Step 8 – Run Migrations, to create tables in database

php artisan migrate
Updated database strucutre after running migrations – php artisan migrate

Step 9 – Creating routes in routes/web.php

Creating all HTTP Verb Routes with a single line of Code

In the routes configuration file — routes/web.php — add the following code to define all Client routes.

use App\Http\Controllers\ClientsController;


Route::resource('clients', ClientsController::class)->middleware('auth');

Once you add this code, type the following command to check if routes have been created properly or if we have any error.

php artisan route:list

The output should be similar to the below image

use App\Http\Controllers\LeadController;
use App\Http\Controllers\ServicesController;
use App\Http\Controllers\TodoController;


Route::resource('lead', LeadController::class)->middleware('auth');
Route::resource('services', ServicesController::class)->middleware('auth');
Route::resource('todo', TodoController::class)->middleware('auth');

Now similarly create all other routes and check for any errors by typing php artisan route:list.

Step 10 – Working with Views.

Now Step by step we will be working on creating all different view files for lead, client, services, and todo. Code for Views will be too much for this article. I request you all to follow along with the remainder of the article on Github. Download the source code, learn, practice, extend & enjoy!

Best of Luck!

Leave a comment