~ We are changing the world with technology. ~

Matt Mullenweg

Aplikasi E-Commerce Laravel 6 #13: Membuat Faktur PDF

Aplikasi E-Commerce Laravel 6 #13: Membuat Faktur PDF

1450 Dilihat

Pendahuluan

Setelah sekian lama vakum dalam membahas seri membuat Aplikasi E-commerce Laravel 6, melalui artikel ini kita akan berjalan sedikit demi sedikit untuk menyelesaikan case yang telah dimulai. Seri kali ini akan membahas bagaimana Membuat file PDF dengan Laravel 6 dengan case membuat faktur PDF untuk setiap pesanan yang ada.

Artikel ini terbilang cukup singkat tapi tetap memberikan informasi baru bagi teman teman yang baru saja belajar Laravel dan hasil yang akan dipoleh dari file PDF ini akan terlihat seperti gambar di bawah ini.

membuat pdf di laravel 6

Baca Juga: Aplikasi E-Commerce Laravel 6 #12: Authorization & Customer Profile

[Issue] Validasi Pembayaran

Ada sedikit kesalahan ketika proses pembayaran dilakukan, dimana customer bisa melakukan konfirmasi pembayaran kurang dari total tagihannya. Berangkat dari kesalahan tersebut, kita akan melakukan sedikit validasi dimana pembayaran yang dikonfirmasi harus sesuai dengan tagihannya.

Awalnya saya ingin customer bisa mengirimkan informasi pembayaran lebih besar dari total tagihan karena sisanya akan dimasukkan ke dalam deposit, tapi melihat kembali bahwa materi ini sudah ada diseri ke-13 dan masih banyak seri yang belum selesai, maka fitur deposit akan dihilangkan saja.

Untuk perbaikan dari validasinya, buka file Ecommerce/OrderController.php dan modifikasi method storePayment() dengan menambahkan code berikut setelah query untuk mengambil detail order.

//CODE SEBELUMNYA
DB::beginTransaction();
  try {
      $order = Order::where('invoice', $request->invoice)->first();
      if ($order->subtotal != $request->amount) return redirect()->back()->with(['error' => 'Error, Pembayaran Harus Sama Dengan Tagihan']); //HANYA TAMBAHKAN CODE INI
    
    //CODE SETELAHNYA

Sekalian saja kita buat menu navigasi menuju ke halaman dashboard sehingga lebih mudah mengaksesnya, buka file resources/views/layouts/ecommerce.blade.php dan cari code berikut .

<!-- CARI CODE INI -->
<li><a href="">My Account</a></li>

<!-- DAN UBAH MENJADI -->
<li><a href="{{ route('customer.dashboard') }}">My Account</a></li>

Membuat Faktur PDF

Dalam proses pembuatan PDF-nya maka kita memerlukan bantuan dari pihak ketiga, dalam hal ini yang akan digunakan adalah Laravel Dompdf. Install package-nya dengan command

composer require barryvdh/laravel-dompdf

Kemudian lakukan proses query menggunakan ELoquent untuk mengambil dari orders berdasarkan InvoiceID dan kirim data tersebut untuk di-generate menjadi sebuah file PDF. Buka file Ecommerce/OrderController.php dan tambahkan method.

public function pdf($invoice)
{
    //GET DATA ORDER BERDASRKAN INVOICE
    $order = Order::with(['district.city.province', 'details', 'details.product', 'payment'])
        ->where('invoice', $invoice)->first();
    //MENCEGAH DIRECT AKSES OLEH USER, SEHINGGA HANYA PEMILIKINYA YANG BISA MELIHAT FAKTURNYA
    if (!\Gate::forUser(auth()->guard('customer')->user())->allows('order-view', $order)) {
        return redirect(route('customer.view_order', $order->invoice));
    }

    //JIKA DIA ADALAH PEMILIKNYA, MAKA LOAD VIEW BERIKUT DAN PASSING DATA ORDERS
    $pdf = PDF::loadView('ecommerce.orders.pdf', compact('order'));
    //KEMUDIAN BUKA FILE PDFNYA DI BROWSER
    return $pdf->stream();
}

Jangan lupa untuk menambahkan use statement:

use PDF;

Tak ada beda-nya dengan view lainnya, PDF akan dikonversi dari dari HTML code maka kita akan membuat file tersendiri yang meng-handle style pdf ini sehingga kita tidak perlu me-load atau meng-extends style yang ada di layouts. Buat file pdf.blade.php di dalam folder resources/views/ecommerce/orders dan tambahkan code berikut

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Invoice #{{ $order->invoice }}</title>
    
    <style>
    .invoice-box {
        max-width: 800px;
        margin: auto;
        padding: 30px;
        border: 1px solid #eee;
        box-shadow: 0 0 10px rgba(0, 0, 0, .15);
        font-size: 16px;
        line-height: 24px;
        font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
        color: #555;
    }
    
    .invoice-box table {
        width: 100%;
        line-height: normal; /* inherit */
        text-align: left;
    }
    
    .invoice-box table td {
        padding: 5px;
        vertical-align: top;
    }
    
    .invoice-box table tr td:nth-child(2) {
        text-align: right;
    }
    
    .invoice-box table tr.top table td {
        padding-bottom: 20px;
    }
    
    .invoice-box table tr.top table td.title {
        font-size: 45px;
        line-height: 45px;
        color: #333;
    }
    
    .invoice-box table tr.information table td {
        padding-bottom: 40px;
    }
    
    .invoice-box table tr.heading td {
        background: #eee;
        border-bottom: 1px solid #ddd;
        font-weight: bold;
    }
    
    .invoice-box table tr.details td {
        padding-bottom: 20px;
    }
    
    .invoice-box table tr.item td{
        border-bottom: 1px solid #eee;
    }
    
    .invoice-box table tr.item.last td {
        border-bottom: none;
    }
    
    .invoice-box table tr.total td:nth-child(2) {
        border-top: 2px solid #eee;
        font-weight: bold;
    }
    
    @media only screen and (max-width: 600px) {
        .invoice-box table tr.top table td {
            width: 100%;
            display: block;
            text-align: center;
        }
        
        .invoice-box table tr.information table td {
            width: 100%;
            display: block;
            text-align: center;
        }
    }
    
    /** RTL **/
    .rtl {
        direction: rtl;
        font-family: Tahoma, 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
    }
    
    .rtl table {
        text-align: right;
    }
    
    .rtl table tr td:nth-child(2) {
        text-align: left;
    }
    </style>
</head>

<body>
    <div class="invoice-box">
        <table cellpadding="0" cellspacing="0">
            <tr class="top">
                <td colspan="2">
                    <table>
                        <tr>
                            <td class="title">
                                <img src="https://daengweb.id/front/dw-theme/images/logo-head.png" width="150px">
                            </td>
                            
                            <td>
                                Invoice : <strong>#{{ $order->invoice }}</strong><br>
                                {{ $order->created_at }}<br>
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
            
            <tr class="information">
                <td colspan="2">
                    <table>
                        <tr>
                            <td>
                                <strong>PENERIMA</strong><br>
                                {{ $order->customer_name }}<br>
                                {{ $order->customer_phone }}<br>
                                {{ $order->customer_address }}<br>
                                {{ $order->district->name }}, {{ $order->district->city->name }} {{ $order->postal_code }}<br>
                                {{ $order->district->city->province->name }}
                            </td>
                            
                            <td>
                                <strong>PENGIRIM</strong><br>
                                Daengweb<br>
                                085343966997<br>
                                Jl Sultan Hasanuddin<br>
                                Somba Opu, Kab Gowa<br>
                                Sulawesi Selatan
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
            
            <tr class="heading">
                <td>Produk</td>
                <td>Subtotal</td>
            </tr>
            
            @foreach ($order->details as $row)
            <tr class="item">
                <td>
                    {{ $row->product->name }}<br>
                    <strong>Harga</strong>: Rp {{ number_format($row->price) }} x {{ $row->qty }}
                </td>
                <td>Rp {{ number_format($row->price * $row->qty) }}</td>
            </tr>
            @endforeach
            
            <tr class="total">
                <td></td>
                <td>
                   Subtotal: Rp {{ number_format($order->subtotal) }}
                </td>
            </tr>
            
            @if ($order->payment)
            <tr class="total">
                <td></td>
                <td>
                   Pembayaran: Rp -{{ number_format($order->payment->amount) }}
                </td>
            </tr>
            <tr>
                <td><strong>Detail Pembayaran</strong></td>
                <td></td>
            </tr>
            <tr>
                <td>Pengirim: {{ $order->payment->name }}</td>
                <td></td>
            </tr>
            <tr>
                <td>Transfer ke: {{ $order->payment->transfer_to }}</td>
                <td></td>
            </tr>
            <tr>
                <td>Tanggal: {{ $order->payment->transfer_date  }}</td>
                <td></td>
            </tr>
            @endif
        </table>
    </div>
</body>
</html>

Note: Tidak ada yang perlu dijelaskan dari code di atas karena hanya tag html dimana berisi informasi data apa saja yang ingin ditampilkan.

Pastinya route untuk mengakses file PDF ini harus didefinisikan, buka file routes/web.php dan tambahkan code berikut di dalam route yang menggunakan middleware customer

//CODE SEBELUMNYA
Route::get('orders/{invoice}', '[email protected]')->name('customer.view_order');
//TAMBAHKAN CODE INI
Route::get('orders/pdf/{invoice}', '[email protected]')->name('customer.order_pdf');

Adapun tombol atau link untuk mengarahkan ke halaman faktur tersebut akan ditambahkan ketika customer mengakses detail pesanan masing-masing. Sebuah tombol atau link yang diletakkan pada informasi data pelanggan, buka file resources/views/ecommerce/orders/view.blade.php dan tambahkan code berikut tepat di atas nama pelanggan.

<!-- TAMBAHKAN CODE INI -->
<tr>
    <td width="30%">InvoiceID</td>
    <td width="5%">:</td>
    <th><a href="{{ route('customer.order_pdf', $order->invoice) }}" target="_blank"><strong>{{ $order->invoice }}</strong></a></th>
</tr>
<!-- TAMBAHKAN CODE INI -->

<tr>
    <td>Nama Lengkap</td>
    <td width="5%">:</td>
    <th>{{ $order->customer_name }}</th>
</tr>

Baca Juga: Aplikasi E-Commerce Laravel 6 #11: Dashboard & Management Orders

Kesimpulan

Singkat tapi masih tetap berisi, begitulah menggambarkan artikel ini dimana kita telah belajar bagaimana membuat file PDF dengan Laravel 6, adapun case-nya adalah informasi terkait faktur pesanan dalam seri membuat Aplikasi Ecommerce Laravel 6.

Dokumentasi code dari artikel ini bisa dilihat di Github.

Full Stack Developer & Remote Worker salah satu perusahaan asal Australia. Senang dengan teknologi baru. Laravel addict yang tidak fanatik. Merekam jejak dengan menulis

Laravel Multiple Database MySql & MongoDB Laravel

Laravel Multiple Database MySql & MongoD...

Mengelola lebih dari satu database di Laravel akan menjadi bahan pembahasan kita dimana engine database yang akan digunakan adalah MySQL dan MongoDB, persoalannya adalah bagaimana menggunakan kedua da...

Mengenal & Mengimplementasikan Laravel Airlock Laravel

Mengenal & Mengimplementasikan Laravel A...

Salah satu fitur yang menarik perhatian dari Laravel 7 adalah Airlock. Fitur ini melengkapi sederet fitur lainnya yang serupa dalam menciptakan fungsi authentication, sebut saja yang lebih dahulu dike...

Authorization Using Gates Laravel 7 Laravel

Authorization Using Gates Laravel 7

Membedakan antara authentication dan authorization sering kali menjadi sebuah masalah baru karena keduanya hampir dianggap sama tapi memiliki fungsi yang berbeda, dimana authentication biasanya diguna...

Komentar