Aplikasi E-Commerce Laravel 6 #20: Auto Upload Produk Marketplace

Aplikasi E-Commerce Laravel 6 #20: Auto Upload Produk Marketplace

Pendahuluan

Dewasa ini, marketplace menjadi platform untuk jual-beli yang banyak digemari baik bagi penjual maupun pembeli karena banyaknya promo yang diberikan oleh platform tersebut. Sehingga, data produk biasanya lebih banyak atau lebih dahulu diunggah ke marketplace.

Beberapa saat kemudian, sebagai penjual, kita ingin memiliki platform sendiri untuk bertransaksi. Gunanya adalah untuk mengamankan aset digital secara perlahan dan dalam rangka mempersiapkan kemungkinan, jikalau marketplace sudah kehilangan pamornya.

Ketika penjual sudah memiliki platform sendiri, masalah berikutnya yang akan ditemukan adalah perlunya ketersediaan waktu untuk mengunggah kembali produk yang dimiliki ke dalam platform baru tersebut. Sehingga, melalui artikel ini, kita akan membahas bagiamana cara memindahkan data yang ada di marketplace ke dalam aplikasi kita sendiri dengan memanfaatkan API yang sudah disediakan oleh RuangAPI.

fitur auto upload product laravel

Baca Juga: Cara Membuat Sistem Komentar Dengan Laravel 7

Auto Upload Produk

Pada tahapan sebelumnya yang membahas terkait bagaimana cara menerapkan fitur ongkos kirim pada aplikasi Ecommerce menggunakan Laravel 6, kita sudah memiliki akun atau API Key yang bisa digunakan untuk membuat fitur auto upload produk dari marketplace.

Langkah pertama yang akan dilakukan adalah membuat form untuk memilih marketplace yang diinginkan dan memasukkan username dari toko Anda atau toko yang ingin disalin data produknya. Buka file bulk.blade.php dari folder resources/views/products dan modifikasi menjadi

@extends('layouts.admin')

@section('title')
    <title>Mass Upload</title>
@endsection

@section('content')
<main class="main">
    <ol class="breadcrumb">
        <li class="breadcrumb-item">Home</li>
        <li class="breadcrumb-item active">Product</li>
    </ol>
    <div class="container-fluid">
        <div class="animated fadeIn">
            <div class="row">
                <div class="col-md-12">
                    @if (session('success'))
                        <div class="alert alert-success">{{ session('success') }}</div>
                    @endif
                </div>
                <div class="col-md-6">
                    <div class="card">
                        <div class="card-header">
                            <h4 class="card-title">Upload Via Excel</h4>
                        </div>
                        <div class="card-body">
                            <form action="{{ route('product.saveBulk') }}" method="post" enctype="multipart/form-data" >
                                @csrf
                                <div class="form-group">
                                    <label for="category_id">Kategori</label>
                                    <select name="category_id" class="form-control">
                                        <option value="">Pilih</option>
                                        @foreach ($category as $row)
                                        <option value="{{ $row->id }}" {{ old('category_id') == $row->id ? 'selected':'' }}>{{ $row->name }}</option>
                                        @endforeach
                                    </select>
                                    <p class="text-danger">{{ $errors->first('category_id') }}</p>
                                </div>
                                <div class="form-group">
                                    <label for="file">File Excel</label>
                                    <input type="file" name="file" class="form-control" value="{{ old('file') }}" required>
                                    <p class="text-danger">{{ $errors->first('file') }}</p>
                                </div>
                                <div class="form-group">
                                    <button class="btn btn-primary btn-sm">Upload</button>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="card">
                        <div class="card-header">
                            <h4 class="card-title">Upload Via Marketplace</h4>
                        </div>
                        <div class="card-body">
                            <form action="{{ route('product.marketplace') }}" method="post">
                                @csrf
                                <div class="form-group">
                                    <label for="">Marketplace</label>
                                    <select name="marketplace" class="form-control" required>
                                        <option value="">Pilih</option>
                                        <option value="shopee">Shopee</option>
                                    </select>
                                    <p class="text-danger">{{ $errors->first('marketplace') }}</p>
                                </div>
                                <div class="form-group">
                                    <label for="">Username</label>
                                    <input type="text" name="username" class="form-control" required>
                                    <p class="text-danger">{{ $errors->first('username') }}</p>
                                </div>
                                <button class="btn btn-primary btn-sm">Jadwalkan</button>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</main>
@endsection

Jadi kita memanfaatkan form yang sudah ada, yakni fitur mass upload menggunakan file Excel, dimana pada halaman tersebut, kita hanya perlu menambahkan form lanjutan untuk menjadwalkan auto upload dari marketplace.

Proses yang akan digunakan adalah menjadwalkan kegiatan tersebut ke dalam queue agar berjalan di background process. Tujuannya adalah untuk mempercepat loadTime bagi user, karena proses ini akan membutuhkan waktu tergantung seberapa cepat response yang diterima. Buka file ProductController.php dan tambahkan method

public function uploadViaMarketplace(Request $request)
{
    //VALIDASI INPUTAN 
    $this->validate($request, [
        'marketplace' => 'required|string',
        'username' => 'required|string'
    ]);

    MarketplaceJob::dispatch($request->username, 10); //BUAT JOBS QUEUE
    //PARAMETER PERTAMA ADALAH USERNAME TOKO PADA MARKETPLACE
    //PARAMETER KEDUA ADALAH JUMLAH PRODUK YANG AKAN AMBIL DALAM SEKALI PROSES
    //SAYA SARANKAN MENGGUNAKAN VALUE 10 UNTUK MEMPERCEPAT PROSES
    return redirect()->back()->with(['success' => 'Produk Dalam Antrian']);
}

Note: Inputan marketplace kita buat jadi selectbox, jika suatu saat tersedia API untuk marketplace lainnya.

Masih dengan file yang sama, tambahkan use statement

use App\Jobs\MarketplaceJob;

Buka file routes/web.php dan tambahkan route berikut di dalam route group yang menggunakan middleware auth

Route::post('/product/marketplace', 'ProductController@uploadViaMarketplace')->name('product.marketplace');

Tiba saatnya bagi kita untuk membuat class Job untuk meng-handle proses request ke API. Dari command line, jalankan command

php artisan make:job MarketplaceJob

Kemudian buka file, jobs/MarketplaceJob.php dan modifikasi menjadi

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Str;
use App\Product;
use App\Category;
use GuzzleHttp\Client;

class MarketplaceJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

  	//ADA DUA PARAMETER YANG DITERIMA OLEH CLASS INI
    protected $username; //PERTAMA ADALAH USERNAME
    protected $take; //DAN BAGIAN KEDUA ADALAH JUMLAH PRODUK YANG AKAN DIUNDUH
    public function __construct($username, $take)
    {
        $this->username = $username;
        $this->take = $take;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $url = 'https://ruangapi.com/api/v1/shopee';
        $client = new Client();
        //HIT API YANG SUDAH DISEDIAKAN OLEH RUANGAPI
        $response = $client->request('POST', $url, [
            'headers' => [
                'Authorization' => 'MASUKKAN API KEY ANDA DISINI'
            ],
            //DENGAN MENGIRIMKAN PARAMETER YANG DIMINTA
            'form_params' => [
                'username' => $this->username,
                'take' => $this->take
            ]
        ]);

        $body = json_decode($response->getBody(), true);
        //LOOPING YANG DITERIMA
        foreach ($body['data']['results'] as $row) {
            //UNDUH FILE GAMBAR DARI URL YANG TERSEDIA KE DALAM LOCAL STORAGENYA KITA
            $filename = Str::slug($row['title']) . '-' . time() . '.png';
            //MENGUGNAKAN FUNGSI FILE_PUT_CONTENTS
            file_put_contents(storage_path('app/public/products/' . $filename), file_get_contents($row['images'][0]));

            //JADI PASTIKAN ADA KATEGORI PADA TABLE CATEGORIES KARENA DATA PERTAMA AKAN KITA GUNAKAN SEBAGAI DEFAULT KATEGORI
            $category = Category::first();
            //JIKA DI API TERSEDIA DATA KATEGORINYA
            if (count($row['categories']) > 0) {
                //MAKA KITA TAMBAHKAN KE TABLE CATEGORIES
                $category = Category::firstOrCreate([
                    'name' => $row['categories'][0],
                    'slug' => Str::slug($row['categories'][0])
                ]);
            }
          
            //KEMUDIAN SIMPAN DATA PRODUK KE DALAM TABLE PRODUCTS
            //KITA MENGGUNAKAN FIRST OR CREATE UNTUK MENGHINDARI DATA YANG SAMA
            Product::firstOrCreate([
                'name' => $row['title'],
            ],
            [
                'slug' => Str::slug($row['title']),
                'category_id' => $category->id,
                'description' => $row['description'],
                'image' => $filename,
                'price' => $row['price'],
                'weight' => 600,
                'status' => 1
            ]);
        }

        //JIKA HASIL NYA MASIH LEBIH BESAR DARI 0
        //MAKA KEMUNGKINAN MASIH ADA DATA PADA PAGE SELANJUTNYA
        if (count($body['data']['results']) > 0) {
            //JADI KITA LOAD LAGI DATA BERIKUTNYA DENGAN MENAMBAHKAN NILAI 10 PADA TAKE SEBELUMNYA
          //JADI MISAL TAKE SEBELUMNYA ADALAH 10, MAKA PADA TAKE KEDUA ADALAH 20 DAN TAKE KETIGA ADALAH 30. BEGITU SETERUSNYA
            MarketplaceJob::dispatch($this->username, $this->take + 10)->delay(now()->addMinutes(5));
        }
    }
}

Ada satu kendala dimana marketplace yang saat ini tersedia API-nya tidak menyediakan data berat barang dari masing-masing produk, sehingga logikanya saya kembalikan kepada para pembaca. Beratnya kita set static dulu dan kemudian akan di-edit secara manual setelah proses upload berhasil.

Saatnya untuk melakukan uji coba dengan menjalankan queue yang sudah ada di database. Dari command line, jalankan perintah

php artisan queue:work

Baca Juga: Membuat Aplikasi Ekspedisi NuxtJS #4: Manage Categories

Kesimpulan

Pada materi ini kita sudah belajar bagaimana cara menggunakan Queue untuk memindahkan proses ke background, sehingga bebannya kita limpahkan ke server dan efeknya adalah load Time untuk proses auto upload bagi user menjadi lebih cepat.

Adapun dokumentasi code dari artikel ini bisa dilihat di Github

 

Category:
Share:

Comments