Skip to content

Day 17 โ€” Logika Pengembalian Aset & Update Stok Otomatis โ€‹

Fase: 2 โ€” Mini Project Asset Management | Minggu: 4 | Hari: Selasa


๐ŸŽฏ Tujuan Hari Ini โ€‹

Peserta mengimplementasikan fitur pengembalian aset: saat tombol "Kembalikan" diklik, status pinjaman berubah menjadi dikembalikan dan stok aset bertambah kembali secara otomatis.


๐Ÿ“‹ Task Wajib โ€‹

1. Rancang Alur Pengembalian โ€‹

Sebelum coding, pahami alurnya:

User klik tombol "Kembalikan" di halaman detail/list pinjaman
    โ†“
Kirim request POST ke route /loans/{id}/return
    โ†“
Controller: cek apakah status masih 'dipinjam'
    โ†“ ya
Jalankan DB::transaction():
    โ”œโ”€โ”€ Update loans: status = 'dikembalikan', actual_return_date = hari ini
    โ””โ”€โ”€ Increment asset stock sebesar quantity yang dikembalikan
    โ†“
Redirect ke halaman list dengan pesan sukses

2. Tambahkan Route Pengembalian (Custom Route) โ€‹

Di routes/web.php, tambahkan di luar Route::resource:

php
// Custom route untuk aksi pengembalian
Route::post('loans/{loan}/return', [LoanController::class, 'returnAsset'])
     ->name('loans.return');

3. Buat Method returnAsset() di LoanController โ€‹

php
public function returnAsset(Loan $loan)
{
    // Validasi: pastikan status masih 'dipinjam'
    if ($loan->status !== 'dipinjam') {
        return redirect()->route('loans.index')
            ->with('error', "Aset ini sudah dikembalikan sebelumnya!");
    }

    DB::transaction(function () use ($loan) {
        // 1. Update record pinjaman
        $loan->update([
            'status'             => 'dikembalikan',
            'actual_return_date' => now()->toDateString(),
        ]);

        // 2. Tambah kembali stok aset
        $loan->asset->increment('stock', $loan->quantity);
    });

    return redirect()->route('loans.index')
        ->with('success', "Aset '{$loan->asset->name}' ({$loan->quantity} unit) berhasil dikembalikan. Stok diperbarui!");
}

public function show(Loan $loan)
{
    $loan->load('asset.category');
    return view('loans.show', compact('loan'));
}

4. Buat Halaman Detail Pinjaman (loans/show.blade.php) โ€‹

html
@extends('layouts.app')
@section('title', 'Detail Peminjaman')
@section('page-title', 'Detail Peminjaman')

@section('content')
<div style="margin-bottom:20px;">
    <a href="{{ route('loans.index') }}" style="color:#666; text-decoration:none;">โ† Kembali ke Daftar Pinjaman</a>
</div>

@include('partials.alert')

<div style="display:grid; grid-template-columns:2fr 1fr; gap:24px;">

    <!-- Info Peminjaman -->
    <div style="background:white; padding:30px; border-radius:10px; box-shadow:0 2px 8px rgba(0,0,0,0.07);">
        <h2 style="margin-bottom:20px; color:#1a1a2e;">๐Ÿ“‹ Informasi Peminjaman</h2>

        <table style="width:100%; border-collapse:collapse;">
            <tr style="border-bottom:1px solid #f0f0f0;">
                <td style="padding:12px 0; color:#666; width:40%;">Peminjam</td>
                <td style="padding:12px 0; font-weight:bold;">{{ $loan->borrower_name }}</td>
            </tr>
            <tr style="border-bottom:1px solid #f0f0f0;">
                <td style="padding:12px 0; color:#666;">Divisi</td>
                <td style="padding:12px 0;">{{ $loan->borrower_department ?? '-' }}</td>
            </tr>
            <tr style="border-bottom:1px solid #f0f0f0;">
                <td style="padding:12px 0; color:#666;">Aset</td>
                <td style="padding:12px 0;">
                    <strong>{{ $loan->asset->name }}</strong>
                    <span style="font-family:monospace; color:#4f46e5;"> ({{ $loan->asset->code }})</span>
                </td>
            </tr>
            <tr style="border-bottom:1px solid #f0f0f0;">
                <td style="padding:12px 0; color:#666;">Kategori</td>
                <td style="padding:12px 0;">{{ $loan->asset->category->name }}</td>
            </tr>
            <tr style="border-bottom:1px solid #f0f0f0;">
                <td style="padding:12px 0; color:#666;">Jumlah Dipinjam</td>
                <td style="padding:12px 0; font-weight:bold; font-size:18px; color:#1a1a2e;">{{ $loan->quantity }} unit</td>
            </tr>
            <tr style="border-bottom:1px solid #f0f0f0;">
                <td style="padding:12px 0; color:#666;">Tanggal Pinjam</td>
                <td style="padding:12px 0;">{{ $loan->borrow_date->format('d F Y') }}</td>
            </tr>
            <tr style="border-bottom:1px solid #f0f0f0;">
                <td style="padding:12px 0; color:#666;">Rencana Kembali</td>
                <td style="padding:12px 0;">
                    {{ $loan->expected_return_date->format('d F Y') }}
                    @if($loan->isTerlambat())
                        <span style="color:#dc3545; font-size:13px; margin-left:8px;">โš ๏ธ Terlambat!</span>
                    @endif
                </td>
            </tr>
            @if($loan->actual_return_date)
            <tr style="border-bottom:1px solid #f0f0f0;">
                <td style="padding:12px 0; color:#666;">Tgl Aktual Kembali</td>
                <td style="padding:12px 0; color:#28a745; font-weight:bold;">
                    โœ… {{ $loan->actual_return_date->format('d F Y') }}
                </td>
            </tr>
            @endif
            <tr>
                <td style="padding:12px 0; color:#666;">Catatan</td>
                <td style="padding:12px 0; font-style:italic; color:#666;">{{ $loan->notes ?? '-' }}</td>
            </tr>
        </table>
    </div>

    <!-- Status & Aksi -->
    <div>
        <!-- Status Card -->
        <div style="background:white; padding:24px; border-radius:10px; margin-bottom:16px; box-shadow:0 2px 8px rgba(0,0,0,0.07); text-align:center;">
            <p style="color:#999; font-size:13px; margin-bottom:12px;">STATUS PEMINJAMAN</p>
            @if($loan->status === 'dipinjam')
            <div style="background:#fff3cd; color:#856404; padding:16px; border-radius:8px; font-size:18px; font-weight:bold;">
                ๐Ÿ”„ Sedang Dipinjam
            </div>
            @else
            <div style="background:#d4edda; color:#155724; padding:16px; border-radius:8px; font-size:18px; font-weight:bold;">
                โœ… Sudah Dikembalikan
            </div>
            @endif
        </div>

        <!-- Tombol Kembalikan -->
        @if($loan->status === 'dipinjam')
        <div style="background:white; padding:24px; border-radius:10px; box-shadow:0 2px 8px rgba(0,0,0,0.07);">
            <h3 style="margin-bottom:12px; color:#1a1a2e;">Kembalikan Aset</h3>
            <p style="color:#666; font-size:13px; margin-bottom:16px;">
                Klik tombol di bawah untuk mengkonfirmasi pengembalian. 
                Stok aset akan bertambah <strong>{{ $loan->quantity }} unit</strong> secara otomatis.
            </p>
            <form action="{{ route('loans.return', $loan->id) }}" method="POST"
                  onsubmit="return confirm('Konfirmasi pengembalian {{ $loan->quantity }} unit dari {{ $loan->borrower_name }}?')">
                @csrf
                <button type="submit"
                        style="width:100%; background:#28a745; color:white; padding:14px; border:none; border-radius:8px; cursor:pointer; font-size:15px; font-weight:bold;">
                    โœ… Konfirmasi Pengembalian
                </button>
            </form>
        </div>
        @endif

        <!-- Info Stok Aset Saat Ini -->
        <div style="background:#eef2ff; padding:20px; border-radius:10px; margin-top:16px;">
            <p style="color:#4f46e5; font-size:13px; margin-bottom:6px; font-weight:bold;">STOK ASET SAAT INI</p>
            <p style="font-size:28px; font-weight:bold; color:#1a1a2e;">{{ $loan->asset->stock }} unit</p>
            <p style="color:#666; font-size:12px;">{{ $loan->asset->name }}</p>
        </div>
    </div>
</div>
@endsection

5. Tambahkan Tombol Detail di Halaman List โ€‹

Update loans/index.blade.php โ€” pastikan link "Detail" sudah mengarah ke loans.show:

html
<a href="{{ route('loans.show', $loan->id) }}" style="color:#0066cc; font-size:13px;">Detail</a>

6. Uji Skenario Pengembalian โ€‹

#SkenarioExpected
1Buka detail pinjaman yang masih 'dipinjam'Tampil tombol "Konfirmasi Pengembalian"
2Klik konfirmasi kembalikanRedirect ke list, pesan sukses muncul
3Cek halaman /assetsStok aset bertambah sesuai quantity
4Buka kembali detail pinjaman yang sudah dikembalikanStatus berubah jadi "Sudah Dikembalikan", tombol hilang
5Akses URL return langsung (sudah dikembalikan)Muncul pesan error "sudah dikembalikan"

๐Ÿ“ Laporan ke Mentor โ€‹

๐Ÿ“Œ LAPORAN HARIAN โ€” Day 17
Nama     : [Nama Lengkap]
Role     : [Role Kamu]

โœ… Yang saya kerjakan hari ini:
- [ ] Route POST loans/{loan}/return terdaftar
- [ ] Method returnAsset() di controller selesai
- [ ] Halaman loans/show.blade.php selesai
- [ ] Tombol "Konfirmasi Pengembalian" berfungsi
- [ ] Stok aset otomatis bertambah setelah pengembalian
- [ ] Semua skenario pengujian berhasil

๐Ÿ“ธ Screenshot Wajib:
1. Halaman detail pinjaman dengan status "Dipinjam" + tombol kembalikan
2. Halaman detail setelah dikembalikan (status berubah, tombol hilang)
3. Halaman /assets menunjukkan stok bertambah setelah pengembalian

๐Ÿงช QA Test:
| Skenario | PASS/FAIL |
|----------|-----------|
| Kembalikan aset โ†’ stok bertambah | |
| Klik kembalikan 2x (sudah dikembalikan) | |
| Detail pinjaman tampil info lengkap | |

โ“ Kendala:
[Tulis jika ada]

Catatan Mentor

Perkenalkan konsep idempotency secara sederhana: "Kenapa kita perlu cek if ($loan->status !== 'dipinjam') sebelum proses kembalikan?" Karena jika endpoint dipanggil dua kali (misal tombol diklik 2x), kita tidak mau stok bertambah 2 kali!

Program Magang SMK RPL โ€” Rekayasa Perangkat Lunak