Aplikasi Laundry (Laravel 5.8 - Vue.js - SPA) #11: Modul Transaksi Part 3

Aplikasi Laundry (Laravel 5.8 - Vue.js - SPA) #11: Modul Transaksi Part 3

Pendahuluan

Titipan cerita dari part sebelumnya dimana terdapat bug tentang waktu yang dibutuhkan untuk mengerjakan pesanan sesuai layanan yang digunakan oleh pelanggan. Selain itu, kita juga akan menyelesaikan fitur add transaction dengan melengkapi beberapa bagian yang diperlukan, diantaranya: informasi lama pengerjaan untuk masing-masing item sesuai yang telah disinggung diawal kalimat, tombol create transaction hanya bisa diklik ketika terdapat minimal 1 item yang telah dipilih paket apa yang akan digunakan, tombol tambah item akan ditampilkan ketika semua item layanan telah di-set paket-nya masing-masing dan yang terakhir adalah sebuah tombol untuk me-reset form transaksi agar user dapat membuat transaksi baru.

Baca Juga: Aplikasi Laundry (Laravel 5.8 - Vue.js - SPA) #10: Modul Transaksi Part 2

Modify Transactions Table

Bagian pertama yang akan kita kerjakan adalah membuat migration baru untuk memanipulasi table transactions dan detail_transactions. Pada command line, jalankan perintah:

php artisan make:migration remove_service_date_to_transactions_table

Buka file migration yang telah di-generate dan modifikasi menjadi

<?php

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

class RemoveServiceDateToTransactionsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('transactions', function (Blueprint $table) {
            //KARENA TUGAS KITA ADALAH MENGHAPUS KEDUA FIELD TERSEBUT DARI TABLE TRANSACTIONS
            //MAKA PADA METHOD UP(), KITA GUNAKAN DROPCOLUMN()
            $table->dropColumn('start_date');
            $table->dropColumn('end_date');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('transactions', function (Blueprint $table) {
            //SEDANGKAN PADA METHOD DOWN KITA BUAT LAGI FIELD TERSEBUT UNTUK MENGANTISIPASI ERROR JIKA SUATU SAAT KITA MELAKUKAN ROLLBACK
            $table->datetime('start_date')->nullable()->after('amount');
            $table->datetime('end_date')->nullable()->after('start_date');
        });
    }
}

Satu lagi adalah dengan menambahkan field yang telah dihapus pada table detail_transaction, pada command line jalankan perintah:

php artisan make:migration add_service_date_to_detail_transactions_table

dan modifikasi migration-nya menjadi:

<?php

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

class AddServiceDateToDetailTransactionsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('detail_transactions', function (Blueprint $table) {
            //TAMBAHKAN FIELD BARU KE DALAM TABLE DETAIL_TRANSACTION
            $table->datetime('start_date')->nullable()->after('laundry_type_id');
            $table->datetime('end_date')->nullable()->after('start_date');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('detail_transactions', function (Blueprint $table) {
            $table->dropColumn('start_date');
            $table->dropColumn('end_date');
        });
    }
}

Terakhir, jangan lupa untuk menjalankan command:

php artisan migrate

Button Validation

Membuat validasi sebagai bentuk reaksi atas segala tindakan pengguna adalah bagian yang akan kita kerjakan kali ini. Pertama adalah membuat tombol Clear Form yang berfungsi untuk me-reset form transaksi, buka file resources/js/pages/transaction/Add.vue dan modifikasi bagian berikut:

<div class="form-group">
    <button class="btn btn-primary btn-sm btn-flat" @click.prevent="submit">
        <i class="fa fa-save"></i> Create Transaction
    </button>
  	
  	<!-- TAMBAHKAN TOMBOL INI -->
    <button class="btn btn-danger btn-sm btn-flat" @click.prevent="clearForm">
        Clear Form
    </button>
    <!-- TAMBAHKAN TOMBOL INI -->
</div>

Masih dengan file yang sama, buat method clearForm() pada bagian property method:

methods: {
  //[.. CODE SEBELUMNYA ..]
	clearForm() {
    this.$refs.form.resetForm()
  }
}

Penjelasan: Code diatas akan menjalan method resetForm() yang berada pada file Form.vue di dalam folder transaction.

Buka file /pages/transaction/Form.vue dan tambahkan method resetForm():

methods: {
  //[.. CODE SEBELUMNYA ..]
	resetForm() {
      this.transactions = {
          customer_id: null,
          detail: [
              { laundry_price: null, qty: 1, price: 0, subtotal: 0 }
          ]
      }
  }
}

Fungsi tombol Clear Form sudah selesai, sekarang saatnya untuk mengerjakan tombol Create Transaction, dimana tombol tersebut berfungsi ketika memiliki minimal 1 item yang sudah di-set paket-nya. Masih dengan file Form.vue, modifikasi method submit() menjadi:

submit() {
    this.isSuccess = false
    //FILTER DATANYA DENGAN KONDISI LAUNDRY_PRICE != NULL
    let filter = _.filter(this.transactions.detail, function(item) {
        return item.laundry_price != null
    })

    //KEMUDIAN DIHITUNG, JIKA JUMLAH DATA YANG SUDAH DIFILTER LEBIH DARI 0
    if (filter.length > 0) {
        //MAKA INSTRUKSI UNTUK MEMBUAT TRANSAKSI DIJALANKAN
        this.createTransaction(this.transactions).then(() => this.isSuccess = true)
    }
},

Bagian terakhir adalah validasi untuk tombol Tambah yang berada tepat diatas table service atau item yang di-order. Dengan file yang sama, modifikasi method addProduct() menjadi:

addProduct() {
    if (this.filterProduct.length == 0) {
        this.transactions.detail.push({ laundry_price: null, qty: null, price: 0, subtotal: 0 })
    }
},

filterProduct berasal dari computed property, maka tambahkan baris berikut ke dalam computed property:

computed: {
  //[.. CODE SEBELUMNYA ..]
	filterProduct() {
      return _.filter(this.transactions.detail, function(item) {
          return item.laundry_price == null
      })
  }
}

//[.. CODE SETELAHNYA ..]

Terakhir adalah modifikasi tag button Tambah dengan menambahkan v-if di dalamnya untuk mengecek jika filterProduct sama dengan 0 maka tombol tersebut ditampilkan:

<button class="btn btn-warning btn-sm" style="margin-bottom: 10px" v-if="filterProduct.length == 0" @click="addProduct">Tambah</button>

Finishing Create Transaction

Melengkapi alur ataupun proses yang berjalan ketika user membuat transaksi dimana bagian yang kurang adalah setiap detail transaksi harus di-set secara otomatis start_date dan end_date sesuai service yang digunakan, serta terjadi kesalahan dalam perhitungan subtotal pada bagian backend.

Bagian pertama yang akan kita kerjakan adalah dari sisi backend, buka file TransactionController.php dan modifikasi method store() menjadi

public function store(Request $request)
{
    $this->validate($request, [
        'customer_id' => 'required',
        'detail' => 'required'
    ]);

    DB::beginTransaction();
    try {
        $user = $request->user();
        $transaction = Transaction::create([
            'customer_id' => $request->customer_id['id'],
            'user_id' => $user->id,
            'amount' => 0
        ]);

        $amount = 0; //TAMBAHKAN BAGIAN INI UNTUK DI CALCULATE SEBAGAI AMOUNT TOTAL TRANSAKSI
        foreach ($request->detail as $row) {
            if (!is_null($row['laundry_price'])) {
                $subtotal = $row['laundry_price']['price'] * $row['qty'];
                if ($row['laundry_price']['unit_type'] == 'Kilogram') {
                    $subtotal = ($row['laundry_price']['price'] * $row['qty']) / 1000; //MODIFIKASI BAGIAN INI KARENA HARUSNYA /1000 SEBAB SATUANNYA KILOGRAM
                }

                $start_date = Carbon::now(); //DEFINISIKAN UNTUK START DATE-NYA
                $end_date = Carbon::now()->addHours($row['laundry_price']['service']); //DEFAULTNYA KITA DEFINISIKAN END DATE MENGGUNAKAN ADDHOURS
                if ($row['laundry_price']['service_type'] == 'Hari') {
                    //AKAN TETAPI, JIKA SERVICENYA ADALAH HARI MAKA END_DATE AKAN DI-REPLACE DENGAN ADDDAYS()
                    $end_date = Carbon::now()->addDays($row['laundry_price']['service']);
                }

                DetailTransaction::create([
                    'transaction_id' => $transaction->id,
                    'laundry_price_id' => $row['laundry_price']['id'],
                    'laundry_type_id' => $row['laundry_price']['laundry_type_id'],
                  
                    //SIMPAN INFORMASINYA KE DATABASE
                    'start_date' => $start_date->format('Y-m-d H:i:s'),
                    'end_date' => $end_date->format('Y-m-d H:i:s'),
                  
                    'qty' => $row['qty'],
                    'price' => $row['laundry_price']['price'],
                    'subtotal' => $subtotal
                ]);

                $amount += $subtotal; //KALKULASIKAN AMOUNT UNTUK SETIAP LOOPINGNYA
            }
        }
        $transaction->update(['amount' => $amount]); //UPDATE INFORMASI PADA TABLE TRANSACTIONS
        DB::commit();
        return response()->json(['status' => 'success']);
    } catch (\Exception $e) {
        DB::rollback();
        return response()->json(['status' => 'error', 'data' => $e->getMessage()]);
    }
}

Kemudian setuhan terakhir adalah pada bagian client (Vue.js-nya), buka file resources/js/pages/transaction/Form.vue dan cukup modifikasi computed property, tepatnya pada property total().

total() {
    return _.sumBy(this.transactions.detail, function(o) {
        return parseFloat(o.subtotal) //TAMBAHKAN parseFloat() UNTUK MEMASTIKAN VALUE YANG DI SUM BUKAN STRING.
    })
},

Baca Juga: Aplikasi Laundry (Laravel 5.8 - Vue.js - SPA) #9: Modul Transaksi Part 1

Kesimpulan

Pada bagian ke-3 dari seri Aplikasi Laundry Laravel 5.8 & Vue.js yang membahas modus transaksi, kita telah menyelesaikan fitur create transactions. Sehingga pada artikel selanjutnya, pembahasannya akan berpindah pada fitur lainnya yang masih mencakup modul transactions. Fitur tersebut adalah untuk melihat detail data transaksi dimana user bisa mengatur status item yang sudah diambil oleh pemiliknya dan juga user bisa meng-input nominal pembayaran pelanggan, serta memiliki pilihan untuk menyimpan kembaliannya sebagai deposit atau memberikannya secara tunai.

Bagian lainnya yang kurang adalah fitur untuk menampilkan semua list transaksi yang telah dilakukan. Adapun dokumentasi code dari artikel ini bisa dilihat di Github.

Category:
Share:

Comments