FlarePoint: Laravel-based free CRM [REVIEW]

Today I’m starting a series of reviews: will be trying and testing various Laravel-based open-source projects available on GitHub and elsewhere. First to check out – is a self-hosted CRM project called Flarepoint.


Other reviews in this series:

  1. FlarePoint: Laravel-based free CRM
  2. Invoice Ninja – Laravel-powered solution for better invoicing
  3. Attendize – event tickets selling system based on Laravel 5
  4. Ribbbon – project management system on Laravel 5.1 and Vue.js
  5. Faveo: impressive helpdesk system built on Laravel
  6. Confomo: Laravel-based website to meet Twitter friends at conferences

For those who don’t know what CRM is – it stands for “Customer Relationship Management”. Basically, it’s a system to manage data of your clients, potential leads, tasks assigned to them for follow-up or other actions.

Flarepoint is a CRM built on Laravel 5.3 – launched quite recently, in July 2016. Its author is Casper Bottelet from Denmark.

Here’s how Flarepoint CRM looks in action:

flarepoint-01

As you can see, it’s a dashboard with all the functionality I had mentioned above.


Installation

Flarepoint is distributed as a full Laravel project for download and install on your server. That’s exactly what I did myself – tested it on my local Homestead.

Installation went well, instructions are perfectly clear and simple. Just clone, run composer install, database migration/seeds and you’re good to go. Well done.

Especially I liked that the system comes with ready-made seed files with data for Departments, Industries and other settings.

flarepoint crm database seeds

Usage

After installation, you can launch the application and see login screen.

flarepoint crm login screen

The first default user to login is admin@admin.com – admin123, provided in installation guide. Convenient.

We log in and see the same dashboard but empty.

flarepoint crm dashboard

And then, one by one, we can fill in the data for our clients.

flarepoint crm create client

In general, everything is straightforward. One thing I didn’t like that “Create entry” actions were only in the main menu on the left, but there were no “create” buttons in client list, or any lists. But that’s a minor issue, no big deal.

flarepoint crm menu

Laravel code

As I mentioned, Flarepoint comes as open-source project, so you can modify it however you want. So let’s take a look what’s underneath in the code. I usually start evaluating the codebase from routes file – in this case, since it’s Laravel 5.3 – we look at routes/web.php file.

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| This file is where you may define all of the routes that are handled
| by your application. Just tell Laravel the URIs it should respond
| to using a Closure or controller method. Build something great!
|
*/
Route::auth();
Route::get('/logout', 'Auth\LoginController@logout');
Route::group(['middleware' =--> ['auth']], function () {
 	/**
     * MAIN
     */
        Route::get('/', 'PagesController@dashboard');
        Route::get('dashboard', 'PagesController@dashboard')->name('dashboard');
    /**
     * USERS
     */
        Route::get('users/data', 'UsersController@anyData')->name('users.data');
        Route::get('users/taskdata/{id}', 'UsersController@taskData')->name('users.taskdata');
        Route::get('users/closedtaskdata/{id}', 'UsersController@closedTaskData')->name('users.closedtaskdata');
        Route::get('users/clientdata/{id}', 'UsersController@clientData')->name('users.clientdata');
        Route::resource('users', 'UsersController');
        /* ROLES */
        Route::resource('roles', 'RolesController');
    /**
     * CLIENTS
     */
        Route::get('clients/data', 'ClientsController@anyData')->name('clients.data');
        Route::post('clients/create/cvrapi', 'ClientsController@cvrapiStart');
        Route::post('clients/upload/{id}', 'DocumentsController@upload');
        Route::resource('clients', 'ClientsController');
    /**
     * TASKS
     */
        Route::get('tasks/data', 'TasksController@anyData')->name('tasks.data');
        Route::patch('tasks/updatestatus/{id}', 'TasksController@updateStatus');
        Route::patch('tasks/updateassign/{id}', 'TasksController@updateAssign');
        Route::post('tasks/updatetime/{id}', 'TasksController@updateTime');
        Route::post('tasks/invoice/{id}', 'TasksController@invoice');
        Route::resource('tasks', 'TasksController');
        Route::post('tasks/comments/{id}', 'CommentController@store');
    /**
     * LEADS
     */
        Route::get('leads/data', 'LeadsController@anyData')->name('leads.data');
        Route::patch('leads/updateassign/{id}', 'LeadsController@updateAssign');
        Route::resource('leads', 'LeadsController');
        Route::post('leads/notes/{id}', 'NotesController@store');
        Route::patch('leads/updatestatus/{id}', 'LeadsController@updateStatus');
        Route::patch('leads/updatefollowup/{id}', 'LeadsController@updateFollowup')->name('leads.followup');
    /**
     * SETTINGS
     */
        Route::get('settings', 'SettingsController@index')->name('settings.index');
        Route::patch('settings/permissionsUpdate', 'SettingsController@permissionsUpdate');
        Route::patch('settings/overall', 'SettingsController@updateOverall');
    /**
     * DEPARTMENTS
     */
        Route::resource('departments', 'DepartmentsController');
        
              
    /**
     * INTEGRATIONS
     */
        Route::resource('integrations', 'IntegrationsController');
      
        /* SLACK */
        Route::get('Integration/slack', 'IntegrationsController@slack');
    /**
     * NOTIFICATIONS
     */
        Route::get('notifications/getall', 'NotificationsController@getAll')->name('notifications.get');
        Route::post('notifications/markread', 'NotificationsController@markRead');
        Route::get('notifications/markall', 'NotificationsController@markAll');
    /**
     * INVOICES
     */
        Route::resource('invoices', 'InvoicesController');
        Route::post('invoice/updatepayment/{id}', 'InvoicesController@updatePayment')->name('invoice.payment.date');
        Route::post('invoice/reopenpayment/{id}', 'InvoicesController@reopenPayment')->name('invoice.payment.reopen');
        Route::post('invoice/sentinvoice/{id}', 'InvoicesController@updateSentStatus')->name('invoice.sent');
        Route::post('invoice/reopensentinvoice/{id}', 'InvoicesController@updateSentReopen')->name('invoice.sent.reopen');
        Route::post('invoice/newitem/{id}', 'InvoicesController@newItem')->name('invoice.new.item');
    /**
     * IMPORT AND EXPORT
     */
        Route::get('documents/import', 'DocumentsController@import');

    });

Again, everything is pretty simple – all actions hidden under auth middleware, and most of them are Resource controllers, except for additional action for every item.

We also see a few integrations (like Slack), import of documents and permissions management. All really useful.

Now, let’s take a look at one random Controller – let’s say, ClientsController.php:

class ClientsController extends Controller
{

    protected $users;
    protected $clients;
    protected $settings;

    public function __construct(
        UserRepositoryContract $users,
        ClientRepositoryContract $clients,
        SettingRepositoryContract $settings
    ) {
        $this->users = $users;
        $this->clients = $clients;
        $this->settings = $settings;
        $this->middleware('client.create', ['only' => ['create']]);
        $this->middleware('client.update', ['only' => ['edit']]);
    }
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        return view('clients.index');
    }

As we can see, Repository pattern is being used, and index() method just calls the view. So I assume there’s something going on in JavaScript side – let’s look at clients/index.blade.php view:

@extends('layouts.master')
@section('heading')

@stop

@section('content')

<table class="wp-block-table table table-hover">
<thead>
<tr>
  <th>@lang('client.headers.name')</th>
  <th>@lang('client.headers.company')</th>
  <th>@lang('client.headers.mail')</th>
  <th>@lang('client.headers.primary_number')</th>
  <th> </th>
  <th> </th>
</tr>
</thead>
</table>

@stop

@push('scripts')
<script>
$(function() {
    $('#clients-table').DataTable({
        processing: true,
        serverSide: true,
       
        ajax: '{!! route('clients.data') !!}',
        columns: [
            
            { data: 'namelink', name: 'name' },
            { data: 'company_name', name: 'company_name' },
            { data: 'email', name: 'email' },
            { data: 'primary_number', name: 'primary_number' },
          
             { data: 'edit', name: 'edit', orderable: false, searchable: false},
        
            
             { data: 'delete', name: 'delete', orderable: false, searchable: false},
         
           
        ]
    });
});
</script>
@endpush

Guess what – I was right, the data is served via Datatables package and with AJAX.


Conclusion

All in all, Flarepoint looks like a really good minimal CRM project – I can congratulate Casper on great work:

  • Useful and usable system
  • Clean and professional code
  • Simple-to-use and with proper documentation

You can also use Flarepoint as an example project to learn or improve your Laravel knowledge.

Some links once again:


Other reviews in this series:

  1. FlarePoint: Laravel-based free CRM
  2. Invoice Ninja – Laravel-powered solution for better invoicing
  3. Attendize – event tickets selling system based on Laravel 5
  4. Ribbbon – project management system on Laravel 5.1 and Vue.js
  5. Faveo: impressive helpdesk system built on Laravel
  6. Confomo: Laravel-based website to meet Twitter friends at conferences

Like our articles?
Check out our Laravel online courses!

9 COMMENTS

  1. Hi Povilas,

    It looks very good! Fantastic job.

    I have a problem with launch project on my computer. I already configurate hosts file on System32 and Virtual Hosts in Apache. When launch app (name crm.dev) following message appears:

    Warning: require(C:\wamp64\www\Flarepoint-crm-develop\bootstrap/../vendor/autoload.php): failed to open stream: No such file or directory in C:\wamp64\www\Flarepoint-crm-develop\bootstrap\autoload.php on line 17

    Line code on autoload.php is ” require __DIR__.’/../vendor/autoload.php’; ”

    Am I doing something wrong?

    Hope your answer

    Nicolas.

  2. Hello Povilas,

    Just wanted to say thank you for writing this (and the other reviews). I’m fairly new to the world of Laravel and I’m enjoying your reviews!

    Michael

  3. I just follow the installation step by step, but find that
    Sorry, the page you are looking for could not be found
    NotFoundHttpException in RouteCollection.php line 161:

      • Sorry, I cannot comment for the creators of FlarePoint, see their documentation.
        It could be Laravel version – since, I think, Laravel 5.3 Auth routes were changed from /auth/login to /login – maybe that’s the clue?

  4. Thank you for your opinion.
    I just test >php -S localhost:9000 -t public
    then it works!
    So I guess the problem is in my local wamp environment .

LEAVE A REPLY

Please enter your comment!
Please enter your name here