Pendahuluan
Evaluasi usaha menjadi bagian penting untuk menentukan strategi lanjutan agar transaksi selalu bertambah dari waktu ke waktu. Pada seri Membuat Aplikasi Laundry Laravel 5.8 & Vue.js, dimana kita telah memasuki bagian ke-14 yang membahas Chart & Laporan. Dengan memanfaatkan library ChartJS yang telah dibuat kembali dengan versi Vue.js, maka kita akan men-generate laporan transaksi selama sebulan trakhir serta menampilkan rekap pendapatan hariannya.
Tidak hanya sebulan trakhir, akan tetapi akan disediakan fitur filter berdasarkan bulan dan tahun sehingga pengguna dapat melihat informasi berdasarkan waktu yang diinginkan. Mengunduh informasi ke local komputer juga tersedia dalam bentuk file Excel yang dapat digunakan sebagai salinan laporan untuk pemilik usaha.
Artikel ini juga sekaligus sebagai penutup karena ada banyak permintaan untuk membahas Laravel 6, sehingga kita akan menggunakan case baru untuk membahas versi Laravel terbaru ini.
Baca Juga: Aplikasi Laundry (Laravel 5.8 - Vue.js - SPA) #13: List Transaksi
Chart Transaksi Harian
Sebelum proses development dimulai, langkah pertama adalah dengan meng-install library yang diperlukan. Pada command line, jalankan perintah:
npm install vue-chartjs chart.js --save
Kemudian buat component LineChart.vue
di dalam folder resources/js/components
dan tambahkan code berikut
<script>
import { Line } from 'vue-chartjs'
export default {
extends: Line,
props: ['data', 'options', 'labels'], //KETIKA COMPONENT INI DIGUNAKAN, AKAN MEMINTA DATA SEBAGAI PROPS
mounted() {
this.lineRenderChart() //KETIKA COMPONENT DI-LOAD JALANKAN METHOD INI
},
watch: {
//KETIKA TERJADI PERUBAHAN VALUE DARI PROPS DATA
data: {
handler() {
this._data._chart.destroy() //MAKA HAPUS CHART
this.lineRenderChart() //DAN RENDER KEMBALI DENGAN DATA YANG BARU
},
deep: true
}
},
methods: {
lineRenderChart() {
//FUNGSI UNTUK MERENDER CHART
this.renderChart({
labels: this.labels, //LABELS NYA BERDASARKAN PROPS LABELS (VALUENYA AKAN KITA ISI LIST TANGGAL SELAMA 1 BULAN)
datasets: [{
label: 'Data Transaksi',
data: this.data, //DATA YANG AKAN MENJADI CHART (TOTAL TRANSAKSI PERHARI)
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
],
borderWidth: 1
}]
}, this.options)
}
}
}
</script>
Saatnya memodifikasi halaman Home/Dashboard, buka file Home.vue
yang berada di dalam folder js/pages
dan modifikasi menjadi
<template>
<div class="container">
<section class="content-header">
<h1>
Dashboard
</h1>
<ol class="breadcrumb">
<li><router-link :to="'/'"><i class="fa fa-dashboard"></i> Home</router-link></li>
<li><a href="#">Dashboard</a></li>
</ol>
</section>
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="panel">
<div class="panel-heading">
<div class="row">
<!-- FORM FILTER BERDASARKAN BULAN DAN TAHUN -->
<div class="col-md-5">
<div class="form-group">
<label for="">Bulan</label>
<select v-model="month" class="form-control">
<option value="01">Januari</option>
<option value="02">Februari</option>
<option value="03">Maret</option>
<option value="04">April</option>
<option value="05">Mei</option>
<option value="06">Juni</option>
<option value="07">Juli</option>
<option value="08">Agustus</option>
<option value="09">September</option>
<option value="10">Oktober</option>
<option value="11">November</option>
<option value="12">Desember</option>
</select>
</div>
</div>
<div class="col-md-5">
<div class="form-group">
<label for="">Tahun</label>
<select v-model="year" class="form-control">
<option v-for="(y, i) in years" :key="i" :value="y">{{ y }}</option>
</select>
</div>
</div>
<!-- FORM FILTER BERDASARKAN BULAN DAN TAHUN -->
<!-- TOMBOL UNTUK EXPORT DATA KE EXCEL -->
<div class="col-md-2">
<button class="btn btn-primary btn-sm pull-right" @click="exportData">Export</button>
</div>
<!-- TOMBOL UNTUK EXPORT DATA KE EXCEL -->
</div>
</div>
<div class="panel-body">
<!-- TAMPILKAN CHART DARI COMPONENT YANG SEBELUMNYA DIBUAT -->
<!-- DENGAN MENGIRIMKAN DATA, OPTIONS DAN LABELS SEBAGAI PROPS -->
<line-chart v-if="transactions.length > 0" :data="transaction_data" :options="chartOptions" :labels="labels"/>
</div>
</div>
</div>
</div>
</section>
</div>
</template>
<script>
import moment from 'moment'
import _ from 'lodash'
import LineChart from '../components/LineChart.vue' //IMPORT COMPONENT CHART
import { mapActions, mapState } from 'vuex'
export default {
created() {
//KETIKA HALAMAN INI DI-LOAD MAKA AKAN MEMINTA DATA KE SERVER
//DAN MENGIRIMKAN PARAMETER BULAN DAN TAHUN YANG AKTIF
this.getChartData({
month: this.month,
year: this.year
})
},
data() {
return {
chartOptions: {
responsive: true,
maintainAspectRatio: false
},
month: moment().format('MM'), //DEFAULT BULAN YG AKTIF BERDASARKAN BULAN SAAT INI
year: moment().format('Y') // //DEFAULT TAHUN YG AKTIF BERDASARKAN TAHUN SAAT INI
}
},
watch: {
//KETIKA VALUE BULAN BERUBAH, MAKA KITA REQUEST DATA BARU
month() {
this.getChartData({
month: this.month,
year: this.year
})
},
//KETIKA VALUE TAHUN BERUBAH, MAKA KITA REQUEST DATA BARU
year() {
this.getChartData({
month: this.month,
year: this.year
})
}
},
computed: {
...mapState('dashboard', {
transactions: state => state.transactions //AMBIL DATA DARI STATE
}),
//LIST TAHUN DARI 2010 SAMPAI TAHUN SAAT INI UNTUK DILOOPING DI FILTER TAG
years() {
return _.range(2010, moment().add(1, 'years').format('Y'))
},
//DATA LABELS YANG DITERIMA DARI SERVER
labels() {
//KARENA FORMAT DATANYA BERISI TOTAL DAN DATE, MAKA KITA FILTER HANYA AKAN MENGAMBIL DATENYA SAJA
return _.map(this.transactions, function(o) {
return moment(o.date).format('DD')
});
},
//DATA TOTAL TRANSAKSI YANG DITERIMA DARI SERVER
transaction_data() {
//KITA FILTER KARENA HANYA AKAN MENGAMBIL TOTAL VALUENYA SAJA
return _.map(this.transactions, function(o) {
return o.total
});
}
},
methods: {
...mapActions('dashboard', ['getChartData']),
//FUNGSI EXPORT DATA INI AKAN KITA KERJAKAN KEMUDIAN
exportData() {
}
},
components: { 'line-chart': LineChart }, //DEFINISIKAN CUSTOM TAG UNTUK COMPONENT YANG DIBUAT SEBELUMNYA
}
</script>
Membuat module Vuex untuk meng-handle request dan menyimpan state data yang diterima dari server, buat file dashboard.js
dan tempatkan di dalam folder /js/stores
import $axios from '../api.js'
const state = () => ({
transactions: [], //STATE UNTUK MENYIMPAN DATA TRANSAKSI
})
const mutations = {
//MUTATION UNTUK MEMANIPULASI DATA STATE TRANSAKSI
ASSIGN_DATA_TRANSACTION(state, payload) {
state.transactions = payload
}
}
const actions = {
//ACTION UNTUK MENG-HANDLE REQUEST KE SERVER
getChartData({ commit }, payload) {
return new Promise((resolve, reject) => {
//MINTA DATA CHART TRANSAKSI KE SERVER BERDASARKAN BULAN DAN TAHUN
$axios.get(`/chart?month=${payload.month}&year=${payload.year}`)
.then((response) => {
//KEMUDIAN KIRIM DATA NYA KE MUTATION UNTUK KEMUDIAN DISIMPAN KE STATE
commit('ASSIGN_DATA_TRANSACTION', response.data)
resolve(response.data)
})
})
},
}
export default {
namespaced: true,
state,
actions,
mutations
}
Agar module diatas dapat digunakan maka kita perlu me-register nya terlebih dahulu, buka file /js/store.js
dan tambahkan beberapa bagian code berikut
modules: {
auth,
outlet,
courier,
product,
user,
expenses,
notification,
customer,
transaction,
dashboard //TAMBAHKAN BAGIAN INI
},
Masih dengan file yang sama, tambahkan code berikut pada import statement:
import dashboard from './stores/dashboard.js'
Langkah terakhir adalah dengan menyediakan API untuk meng-handle request data transaksi yang akan ditampilkan sebagai chart, pada command line, buat controller baru dengan command:
php artisan make:controller API/DashboardController
Kemudian buka file DashboardController.php
dan tambahkan code berikut:
<?php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Carbon\Carbon;
use App\Transaction;
use DB;
class DashboardController extends Controller
{
public function chart()
{
$filter = request()->year . '-' . request()->month; //GET DATA BULAN & TAHUN YANG DIKIRIMKAN SEBAGAI PARAMETER
$parse = Carbon::parse($filter); //UBAH FORMATNYA MENJADI FORMAT CARBON
//BUAT RANGE TANGGAL PADA BULAN TERKAIT
$array_date = range($parse->startOfMonth()->format('d'), $parse->endOfMonth()->format('d'));
//GET DATA TRANSAKSI BERDASARKAN BULAN & TANGGAL YANG DIMINTA.
//GROUP / KELOMPOKKAN BERDASARKAN TANGGALNYA
//SUM DATA AMOUNT DAN SIMPAN KE NAMA BARU YAKNI TOTAL
$transaction = Transaction::select(DB::raw('date(created_at) as date,sum(amount) as total'))
->where('created_at', 'LIKE', '%' . $filter . '%')
->groupBy(DB::raw('date(created_at)'))->get();
$data = [];
//LOOPING RANGE TANGGAL BULAN SAAT INI
foreach ($array_date as $row) {
//KITA CEK TANGGALNYA, JIKA HANYA 1 ANGKA (1-9) MAKA TAMBAHKAN 0 DIDEPANNYA
$f_date = strlen($row) == 1 ? 0 . $row:$row;
//BUAT FORMAT TANGGAL YYYY-MM-DD
$date = $filter . '-' . $f_date;
//CARI DATA BERDASARKAN $DATE PADA COLLECTION HASIL QUERY
$total = $transaction->firstWhere('date', $date);
//SIMPAN DATANYA KE DALAM VARIABLE $DATA
$data[] = [
'date' =>$date,
'total' => $total ? $total->total:0
];
}
return $data;
}
}
Buat routing untuk meng-handle controller diatas, buka file routes/api.php
dan tambahkan code:
Route::get('chart', 'API\DashboardController@chart');
Export Laporan Harian
Laporan transaksinya serupa dengan chart hanya saja kita masukkan ke dalam file excel yang secara otomatis akan disimpan ke dalam komputer pengguna. Install package Laravel Excel dengan command
composer require maatwebsite/excel
Kemudian generate class TranscationExport
dengan command
php artisan make:export TransactionExport --model=Transaction
Buka file app/Exports/TransactionExport.php
dan modifikasi menjadi
<?php
namespace App\Exports;
use App\Transaction;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
class TransactionExport implements FromView, ShouldAutoSize
{
protected $transaction;
protected $month;
protected $year;
//KITA MEMINTA DATA TRANSAKSI, DATA BULAN DAN TAHUN YANG DI REQUEST
public function __construct($transaction, $month, $year)
{
$this->transaction = $transaction;
$this->month = $month;
$this->year = $year;
}
public function view(): View
{
//LOAD VIEW transaction.blade.php DAN PASSING DATA YANG DIMINTA DIATAS
return view('exports.transaction', [
'transaction' => $this->transaction,
'month' => $this->month,
'year' => $this->year
]);
}
}
Buat file transactions.blade.php
di dalam folder resources/views/exports
dan tambahkan code html dibawah ini
<table>
<thead>
<tr>
<th colspan="2"><strong>Laporan Transaksi {{ $month }} - {{ $year }}</strong></th>
</tr>
<tr>
<th colspan="2"></th>
</tr>
<tr>
<th>Tanggal</th>
<th>Pemasukan</th>
</tr>
</thead>
<tbody>
@foreach($transaction as $row)
<tr>
<td>{{ $row['date'] }}</td>
<td>Rp {{ number_format($row['total']) }}</td>
</tr>
@endforeach
</tbody>
</table>
Note: Code diatas hanya HTML dimana terdapat tag table dan didalamnya ada looping untuk menampilkan data transaksi.
Buka file DashboardController.php
dan tambahkan method berikut untuk meng-handle request export laporan
public function exportData(Request $request)
{
$transaction = $this->chart(); //KARENA QUERYNYA SAMA, MAKA KITA AMBIL DATA DARI METHOD CHART() SAJA SEHINGGA KITA TIDAK PERLU MEMBUAT CODE YANG SAMA
//REQUEST UNTUK MENDOWNLOAD FILE EXCEL
//MENGGUNAKAN TRANSACTIONEXPORT() DAN MENGIRIMKAN 3 BUAH DATA
//DATA TRANSAKSI, DATA BULAN DAN TAHUN YANG DIMINTA
//DAN NAMA FILE YANG DIHASILKAN ADALAH transaction.xlsx
return Excel::download(new TransactionExport($transaction, request()->month, request()->year), 'transaction.xlsx');
}
Jangan lupa untuk mendefinisikan routing-nya, buka file routes/api.php
dan tambahkan route berikut
Route::get('export', 'API\DashboardController@exportData');
Sentuhan terakhir adalah dengan modifikasi method exportData()
, buka file /pages/Home.vue
dan modifikasi method tersebut
exportData() {
window.open(`/api/export?api_token=${this.token}&month=${this.month}&year=${this.year}`)
}
Baca Juga: Aplikasi Qur'an Digital & Play Audio Menggunakan Flutter
Kesimpulan
Sebagai materi penutup maka kita belajar banyak hal diantaranya bagaimana menggunakan library ChartJS untuk menampilkan data transaksi dengan mode chart, selain itu juga terdapat fitur export data ke excel sehingga cara menggunakan package Laravel Excel juga sudah dibahas.
Tentu saja di dalam materi ini masih banyak kekurangan yang perlu dilengkapi, tapi saya merasa dengan semua teknik dan method yang digunakan maka teman-teman sudah bisa dengan mandiri menambahkan fitur lainnya yang terlewatkan.
Adapun dokumentasi code dari artikel ini bisa kamu lihat di Github.
Comments