(Part 9) Membuat Aplikasi POS (Point of Sales Laravel 5.6 - Chart

(Part 9) Membuat Aplikasi POS (Point of Sales Laravel 5.6 - Chart

Pendahuluan

Hal lain yang patut kita perhitungkan untuk melengkapi fitur laporan adalah dengan membuat chart penjualan. Dengan chart, user dapat melihat grafik penjualan sehingga dapat menganalisa untuk proses bisnis kedepannya. Dalam materi ini kita akan membuat dashboard dari aplikasi POS (Point of sales) dimana diantara fitur yang akan kita hadirkan dalam dashboard tersebut adalah akumulasi informasi yang ditampung oleh aplikasi, dan juga chart seperti yang disinggung diawal.

membuat aplikasi pos laravel

Baca Juga: Tips Menggunakan Eloquent Laravel

Membuat Grafik Dengan Chart.js

Salah satu library yang paling menarik dan popular digunakan untuk membuat chart adalah Chart.js, sedangkan untuk berkomunikasi dengan Laravel adalah dengan membuat API, kali ini kita akan mengintegrasikannya dengan Vue.js dan axios karena sepanjang seri ini kita telah memulainya dengan Vue.js.

Buka command line dan install library Chart.js terlebih dahulu dengan command:

npm install chart.js --save

Kemudian buka file HomeController.php, lalu modifikasi sehingga menjadi:

<?php
​
namespace App\Http\Controllers;
​
use Illuminate\Http\Request;
use Carbon\Carbon;
use Order;
use DB;
​
class HomeController extends Controller
{
    //METHOD INI AKAN KITA MODIFIKASI PADA SUB TOPIK BERIKUTNYA
    public function index()
    {
        return view('home');
    }
    
    //METHOD INI UNTUK MENG-GENERATE DATA ORDER 7 HARI TERAKHIR
    public function getChart()
    {
        //MENGAMBIL TANGGAL 7 HARI YANG TELAH LALU DARI TANGGAL HARI INI
        $start = Carbon::now()->subWeek()->addDay()->format('Y-m-d') . ' 00:00:01';
        //MENGAMBIL TANGGAL HARI INI
        $end = Carbon::now()->format('Y-m-d') . ' 23:59:00';
        
        //SELECT DATA KAPAN RECORDS DIBUAT DAN JUGA TOTAL PESANAN
        $order = Order::select(DB::raw('date(created_at) as order_date'), DB::raw('count(*) as total_order'))
            //DENGAN KONDISI ANTARA TANGGAL YANG ADA DI VARIABLE $start DAN $end 
            ->whereBetween('created_at', [$start, $end])
            //KEMUDIAN DI KELOMPOKKAN BERDASARKAN TANGGAL
            ->groupBy('created_at')
            ->get()->pluck('total_order', 'order_date')->all();
        
        //LOOPING TANGGAL DENGAN INTERVAL SEMINGGU TERAKHIR
        for ($i = Carbon::now()->subWeek()->addDay(); $i <= Carbon::now(); $i->addDay()) {
            //JIKA DATA NYA ADA 
            if (array_key_exists($i->format('Y-m-d'), $order)) {
                //MAKA TOTAL PESANANNYA DI PUSH DENGAN KEY TANGGAL
                $data[$i->format('Y-m-d')] = $order[$i->format('Y-m-d')];
            } else {
                //JIKA TIDAK, MASUKKAN NILAI 0
                $data[$i->format('Y-m-d')] = 0;
            }
        }
        return response()->json($data);
    }
}

Note: Method __construct() yang didalamnya terdapat code untuk me-load middleware kita hapus, karena method index sudah dimasukkan ke dalam group middleware auth di route web.php.

Buka file routes/api.php, kemudian definisikan route /chart:

Route::get('/chart', 'HomeController@getChart');

Buat file dashboard.js di dalam folder resources/assets/js, kemudian tambahkan code berikut:

import Vue from 'vue';
import axios from 'axios';
import Chart from 'chart.js';
​
new Vue({
    el: '#dw',
    data: {
        //FORMAT DATA YANG AKAN DIGUNAKAN KE CHART.JS
        dwChartData: {
            //TYPE CHARTNYA line
            type: 'line',
            data: {
                //YANG PERLU DIPERHATIKAN BAGIAN LABEL INI NILAINYA DINAMIS
                labels: [],
                datasets: [
                    {
                        label: 'Total Penjualan',
                        //DAN NILAI DATA JUGA DINAMIS TERGANTUNG DATA YANG DITERIMA DARI SERVER
                        data: [],
                        backgroundColor: [
                            'rgba(71, 183,132,.5)',
                            'rgba(71, 183,132,.5)',
                            'rgba(71, 183,132,.5)',
                            'rgba(71, 183,132,.5)',
                            'rgba(71, 183,132,.5)',
                            'rgba(71, 183,132,.5)',
                            'rgba(71, 183,132,.5)'
                        ],
                        borderColor: [
                            '#47b784',
                            '#47b784',
                            '#47b784',
                            '#47b784',
                            '#47b784',
                            '#47b784',
                            '#47b784'
                        ],
                        borderWidth: 3
                    }
                ]
            },
            options: {
                responsive: true,
                lineTension: 1,
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true,
                            padding: 25,
                        }
                    }]
                }
            }
        }
    },
    mounted() {
        //KETIKA APLIKASI DI-LOAD MAKA AKAN MENJALANKAN METHOD getData()
        this.getData();
        //DAN METHOD createChart() DENGAN PARAMETER 'dw-chart' DAN FORMAT DARI dwChartData
        this.createChart('dw-chart', this.dwChartData);
    },
    methods: {
        //METHOD createChart DENGAN PERMINTAAN 2 PARAMETER
        createChart(chartId, chartData) {
            //MENCARI ELEMEN DENGAN ID SESUAI DARI PARAMETER chartId
            const ctx = document.getElementById(chartId);
            //MENDEFINISIKAN CHART.JS
            const myChart = new Chart(ctx, {
                type: chartData.type,
                data: chartData.data,
                options: chartData.options,
            });
        },
        //METHOD getData() UNTUK MEMINTA DATA DARI SERVER
        getData() {
            //MENGIRIMKAN PERMINTAAN DENGAN ENDPOINT /api/chart
            axios.get('/api/chart')
            //KEMUDIAN RESPONSE NYA
            .then((response) => {
                //DILOOPING DENGAN MEMISAHKAN KEY DAN VALUE
                Object.entries(response.data).forEach(
                    ([key, value]) => {
                        //DIMANA KEY (BACA: DALAM HAL INI INDEX DATA ADALAH TANGGAL)
                        //KITA MASUKKAN KEDALAM dwChartData > data > labels
                        this.dwChartData.data.labels.push(key);
                        //KEMUDIAN VALUE DALAM HAL INI TOTAL PESANAN
                        //KITA MASUKKAN KE DALAM dwChartData > data > datasets[0] > data
                        this.dwChartData.data.datasets[0].data.push(value);
                    }
                );
            })
        }
    }
})

Sedangkan untuk view, buka file resources/views/home.blade.php, kemudian modifikasi menjadi:

@extends('layouts.master')
​
@section('title')
    <title>Dashboard</title>
@endsection
​
@section('content')
    <div class="content-wrapper">
        <div class="content-header">
            <div class="container-fluid">
                <div class="row mb-2">
                    <div class="col-sm-6">
                        <h1 class="m-0 text-dark">Dashboard</h1>
                    </div>
                    <div class="col-sm-6">
                        <ol class="breadcrumb float-sm-right">
                            <li class="breadcrumb-item"><a href="{{ route('home') }}">Home</a></li>
                            <li class="breadcrumb-item active">Dashboard</li>
                        </ol>
                    </div>
                </div>
            </div>
        </div>
​
        <!-- Main content -->
        <section class="content" id="dw">
            <div class="container-fluid">
                
                <!-- ABAIKAN DULU LINE INI KARENA AKAN DI MODIFIKASI SELANJUTNYA -->
                <div class="row">
                    <div class="col-lg-3 col-6">
                        <div class="small-box bg-info">
                            <div class="inner">
                                <h3>0</h3>
                                <p>Produk</p>
                            </div>
                            <div class="icon">
                                <i class="ion ion-bag"></i>
                            </div>
                            
                        </div>
                    </div>
​
                    <div class="col-lg-3 col-6">
                        <div class="small-box bg-success">
                            <div class="inner">
                                <h3>0</h3>
                                <p>Pesanan</p>
                            </div>
                            <div class="icon">
                                <i class="ion ion-stats-bars"></i>
                            </div>
                            
                        </div>
                    </div>
                    <div class="col-lg-3 col-6">
                        <div class="small-box bg-warning">
                            <div class="inner">
                                <h3>0</h3>
                                <p>Pelanggan</p>
                            </div>
                            <div class="icon">
                                <i class="ion ion-person-add"></i>
                            </div>
                        </div>
                    </div>
                    <div class="col-lg-3 col-6">
                        <div class="small-box bg-danger">
                            <div class="inner">
                                <h3>0</h3>
                                <p>Karyawan</p>
                            </div>
                            <div class="icon">
                                <i class="ion ion-pie-graph"></i>
                            </div>
                        </div>
                    </div>
                </div>
                <!-- SAMPAI LINE INI -->
                
                <!-- YANG PERLU DIPERHATIKAN ADALAH LINE DIBAWAH -->
                <div class="row">
                    <!-- CHART.JS MEMINTA ELEMENT YANG MEMILIKI ID dw-chart -->
                    <canvas id="dw-chart"></canvas>
                </div>
            </div>
        </section>
    </div>
@endsection
​
@section('js')
    <!-- LOAD FILE dashboard.js -->
    <script src="{{ asset('js/dashboard.js') }}"></script>
@endsection

Terakhir, buka file webpack.mix.js dan tambahkan line untuk me-load dashboard.js agar bisa di-compile oleh Laravel Mix.

mix.js('resources/assets/js/dashboard.js', 'public/js');

Ditutup dengan menjalankan command untuk men-compile file js yang telah dibuat:

npm run dev

Baca Juga: Membuat Aplikasi Pos (Point of Sales) Laravel 5.6 - Laporan

Membuat Fitur Akumulasi Data

Jika kamu memperhatikan gambar yang terlampir pada pendahuluan, terdapat 4 widget yang berisi informasi akumulasi data dari masing-masing widget. Bagaimana cara membuatnya? Sebenarnya sangat mudah tanpa mengikuti panduan ini juga saya pastikan teman-teman sudah bisa jika mengikuti setiap part dari artikel seri Membuat Aplikasi POS (Point of Sales) ini, karena data tersebut hanya count dari masing-masing table yang terkait.

Buka file HomeController.php, pada method index, modifikasi menjadi:

public function index()
{
    $product = Product::count();
    $order = Order::count();
    $customer = Customer::count();
    $user = User::count();
    return view('home', compact('product', 'order', 'customer', 'user'));
}

Jangan lupa tambahkan use statement:

use App\Product;
use App\Customer;
use App\User;

Terakhir, buka file home.blade.php kemudian masukkan masing-masing variable ke dalam masing-masing widget yang terkait:

<div class="row">
    <div class="col-lg-3 col-6">
        <div class="small-box bg-info">
            <div class="inner">
                <h3>{{ $product }}</h3>
                <p>Produk</p>
            </div>
            <div class="icon">
                <i class="ion ion-bag"></i>
            </div>
​
        </div>
    </div>
​
    <div class="col-lg-3 col-6">
        <div class="small-box bg-success">
            <div class="inner">
                <h3>{{ $order }}</h3>
                <p>Pesanan</p>
            </div>
            <div class="icon">
                <i class="ion ion-stats-bars"></i>
            </div>
​
        </div>
    </div>
    <div class="col-lg-3 col-6">
        <div class="small-box bg-warning">
            <div class="inner">
                <h3>{{ $customer }}</h3>
                <p>Pelanggan</p>
            </div>
            <div class="icon">
                <i class="ion ion-person-add"></i>
            </div>
        </div>
    </div>
    <div class="col-lg-3 col-6">
        <div class="small-box bg-danger">
            <div class="inner">
                <h3>{{ $user }}</h3>
                <p>Karyawan</p>
            </div>
            <div class="icon">
                <i class="ion ion-pie-graph"></i>
            </div>
        </div>
    </div>
</div>

Note: Code diatas sudah ada pada sub topik sebelumnya, hanya saja saya pindahkan kembali untuk memperlihatkan dimana tempat untuk menyimpan variable tersebut. Hanya mengganti angka 0 dengan mencetak masing-masing variable yang telah menampung total data.

Kesimpulan

Dalam membuat program, jangan hanya terpaku pada bahasa pemrograman yang sedang digunakan sehingga kita menyulitkan diri sendiri. Kita dapat menggunakan apa yang sudah ada untuk kemudian dirangkai dan digunakan sehingga mencapai tujuan yang di-inginkan. Misalnya saja Chartjs yang merupakan library Javascript dapat kita integrasikan dengan Laravel dan Vue.js.

Artikel ini merupakan penutup dari seri Membuat Aplikasi POS (Point of Sales), karena penulis akan berpindah ke case yang lain. Namun, bukan berarti artikel ini sudah benar-benar berakhir, jika teman-teman punya saran dan masukan untuk menghadirkan fitur apa saja yang perlu ditambahkan, maka jangan sungkan untuk meninggalkannya dikomentar.

Ohya, dokumentasi project ini dapat kamu lihat di Github.

Category:
Share:

Comments