# Sistem Nomor Bukti Otomatis dengan Preview Real-time

## 🎯 Fitur Unggulan

Nomor bukti **OTOMATIS ditampilkan** di form bahkan sebelum disimpan!

### 📋 Format Nomor Bukti
```
BB + YYMMDD + XXX
```
**Contoh**: `BB260424001`
- `BB` - Kode fixed (Bukti Benur)
- `260424` - Tanggal (YYMMDD)
- `001` - Nomor urut (3 digit, auto-increment per tanggal)

## ✨ Cara Kerja Sistem

### 1. Preview Real-time di Form
Saat user memilih tanggal tebar, sistem langsung menampilkan preview nomor bukti:

```
User pilih tanggal: 2026-04-24
↓
Sistem generate preview: BB260424001
↓
Tampil di form: [BB260424001] (readonly)
```

### 2. Alur Generate No Bukti

#### A. Saat Create (Tebar Baru)
1. User buka form "Tebar Baru"
2. User pilih tanggal tebar
3. **Sistem generate preview real-time**:
   ```javascript
   GET /tebar/get-last-sequence/2026-04-24
   Response: { next_sequence: 1, next_no_bukti: "BB260424001" }
   ```
4. Field no_bukti langsung terisi: `BB260424001`
5. User klik "Simpan"
6. Database trigger memfinalisasi no_bukti

#### B. Saat Edit
1. User klik tombol edit
2. Field no_bukti berisi nilai yang sudah ada (readonly)
3. Help text menampilkan: `✅ No Bukti: BB260424001`

### 3. Auto-Reset per Tanggal
```
Tanggal 2026-04-24:
- BB260424001 (record 1)
- BB260424002 (record 2)
- BB260424003 (record 3)

Tanggal 2026-04-25:
- BB260425001 (RESET ke 001! ✨)
- BB260425002 (record 2)
- BB260425003 (record 3)
```

## 🔧 Teknis Implementasi

### A. Frontend (JavaScript)

#### 1. Fungsi Generate Preview
```javascript
function generateNoBuktiPreview(tanggal) {
    if (!tanggal) {
        $('#no_bukti').val('');
        $('#no_bukti_help').text('Pilih tanggal untuk generate nomor bukti otomatis');
        return;
    }

    // Generate tanggal part (YYMMDD)
    const dateObj = new Date(tanggal);
    const yy = dateObj.getFullYear().toString().slice(-2);
    const mm = String(dateObj.getMonth() + 1).padStart(2, '0');
    const dd = String(dateObj.getDate()).padStart(2, '0');
    const tanggalPart = yy + mm + dd;

    // Tampilkan preview sementara
    $('#no_bukti').val('BB' + tanggalPart + 'XXX');
    $('#no_bukti_help').html('Preview: Nomor urut akan ditambahkan otomatis saat simpan');

    // Ambil nomor urut terakhir dari database
    $.ajax({
        url: '/tebar/get-last-sequence/' + tanggal,
        method: 'GET',
        success: function(response) {
            const nextSequence = response.next_sequence;
            const noBuktiPreview = 'BB' + tanggalPart + String(nextSequence).padStart(3, '0');
            $('#no_bukti').val(noBuktiPreview);
            $('#no_bukti_help').html('✅ No Bukti: <strong>' + noBuktiPreview + '</strong>');
        }
    });
}
```

#### 2. Event Listener Tanggal
```javascript
$('#tanggal_tebar').on('change', function() {
    const tanggal = $(this).val();
    generateNoBuktiPreview(tanggal);
});
```

### B. Backend (Controller)

#### 1. Method: getLastSequence
```php
public function getLastSequence($tanggal)
{
    // Generate tanggal part (YYMMDD)
    $tanggalPart = date('ymd', strtotime($tanggal));

    // Cari nomor urut terakhir untuk tanggal yang sama
    $lastTebar = TTebar::where('no_bukti', 'like', 'BB' . $tanggalPart . '%')
        ->orderBy('no_bukti', 'desc')
        ->first();

    $nextSequence = 1;
    if ($lastTebar) {
        // Extract 3 digit terakhir dari no_bukti
        $lastSequence = (int)substr($lastTebar->no_bukti, -3);
        $nextSequence = $lastSequence + 1;
    }

    return response()->json([
        'last_no_bukti' => $lastTebar ? $lastTebar->no_bukti : null,
        'next_sequence' => $nextSequence,
        'next_no_bukti' => 'BB' . $tanggalPart . str_pad($nextSequence, 3, '0')
    ]);
}
```

### C. Database Trigger

Trigger tetap digunakan untuk finalisasi saat INSERT:
```sql
CREATE TRIGGER ttebar_before_insert
BEFORE INSERT ON ttebar
FOR EACH ROW
BEGIN
    DECLARE tanggal_part VARCHAR(6);
    DECLARE nomor_urut INT;

    SET tanggal_part = DATE_FORMAT(NEW.tanggal_tebar, '%y%m%d');

    SELECT COALESCE(MAX(CAST(SUBSTRING(no_bukti, -3) AS UNSIGNED)), 0) + 1
    INTO nomor_urut
    FROM ttebar
    WHERE no_bukti LIKE CONCAT('BB', tanggal_part, '%')
    AND deleted_at IS NULL;

    SET NEW.no_bukti = CONCAT('BB', tanggal_part, LPAD(nomor_urut, 3, '0'));
END
```

### D. Routes
```php
Route::get('/get-last-sequence/{tanggal}', [TebarController::class, 'getLastSequence'])->name('tebar.get-last-sequence');
```

## 📊 Tampilan di Form

### Saat Form Pertama Dibuka
```
Nomor Bukti: [__________________]
            ↓
Help: "Pilih tanggal untuk generate nomor bukti otomatis"
```

### Saat Tanggal Dipilih (24 April 2026)
```
Nomor Bukti: [BB260424005] ✓ (readonly, background hijau muda)
            ↓
Help: "✅ No Bukti: BB260424005"
```

### Saat Edit Data
```
Nomor Bukti: [BB260424003] ✓ (readonly, background hijau muda)
            ↓
Help: "✅ No Bukti: BB260424003"
```

## 🎨 Styling CSS yang Disarankan

```css
#no_bukti {
    background-color: #d4edda;
    border-color: #c3e6cb;
    font-weight: 600;
    color: #155724;
}

#no_bukti:focus {
    background-color: #c3e6cb;
    border-color: #28a745;
    box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);
}

#no_bukti_help {
    color: #28a745;
    font-weight: 500;
}
```

## 🔍 Validasi & Error Handling

### Frontend Validation
- Tanggal harus dipilih sebelum no_bukti muncul
- AJAX error handling dengan fallback

### Backend Validation
- Tanggal harus valid date format
- Nomor urut dihitung dari database

### Error Handling
```javascript
error: function() {
    $('#no_bukti_help').html('Preview: Nomor urut akan ditambahkan otomatis saat simpan');
}
```

## 📈 Contoh Scenarios

### Scenario 1: First Record of the Day
```
Tanggal: 2026-04-24
Preview: BB260424001
Last sequence: None
Next sequence: 1
```

### Scenario 2: Multiple Records Same Day
```
Record 1: BB260424001
Record 2: BB260424002
Record 3: BB260424003
Preview for next: BB260424004
```

### Scenario 3: Different Date
```
Record terakhir 24 April: BB260424003
Tanggal baru: 2026-04-25
Preview: BB260425001 (RESET! ✨)
```

## ⚡ Keuntungan Sistem

### 1. User Experience
- ✅ User tahu nomor bukti sebelum simpan
- ✅ Tidak ada kejutan nomor
- ✅ Transparan dan predictable

### 2. Data Consistency
- ✅ Preview = Final result (terjamin sama)
- ✅ Tidak ada duplikasi
- ✅ Atomic operation

### 3. Performance
- ✅ Query cepat (indexed)
- ✅ AJAX response cepat
- ✅ Tidak perlu reload halaman

### 4. Reliability
- ✅ 2 layer protection (frontend + database)
- ✅ Trigger menjamin finalisasi yang benar
- ✅ Handle concurrent request

## 🧪 Testing

### Test 1: Preview dengan Data Kosong
```bash
GET /tebar/get-last-sequence/2026-04-26
Expected: { next_sequence: 1, next_no_bukti: "BB260426001" }
```

### Test 2: Preview dengan Data Ada
```bash
# Ada BB260424001
GET /tebar/get-last-sequence/2026-04-24
Expected: { next_sequence: 2, next_no_bukti: "BB260424002" }
```

### Test 3: Insert Final
```sql
INSERT INTO ttebar (tanggal_tebar, kolam_id, sumber_benih, jml_bibit, created_by)
VALUES ('2026-04-24', 1, 'Test', 1000, 1);

SELECT no_bukti FROM ttebar WHERE id = LAST_INSERT_ID();
Expected: BB260424001 (atau next available)
```

## 🔄 Timeline Alur Kerja

```
1. User buka form "Tebar Baru"
   ↓
2. Field no_bukti: [__________________]
   Help: "Pilih tanggal untuk generate..."
   ↓
3. User pilih tanggal: 2026-04-24
   ↓
4. AJAX Request: GET /tebar/get-last-sequence/2026-04-24
   ↓
5. Server Response: { next_sequence: 5, next_no_bukti: "BB260424005" }
   ↓
6. Field no_bukti: [BB260424005] ✓
   Help: "✅ No Bukti: BB260424005"
   ↓
7. User lengkapi field lain
   ↓
8. User klik "Simpan"
   ↓
9. Database trigger finalisasi no_bukti
   ↓
10. Data tersimpan dengan no_bukti: BB260424005 ✓
```

## 🎯 Hasil Akhir

### Form dengan Preview
```
┌─────────────────────────────────┐
│ Nomor Bukti                      │
│ ┌─────────────────────────────┐ │
│ │ BB260424005                 │ │ ← Preview real-time!
│ └─────────────────────────────┘ │
│ ✅ No Bukti: BB260424005        │ ← Help text konfirmasi
└─────────────────────────────────┘
```

### User Tahu Persis Sebelum Simpan
- ✅ Nomor bukti apa yang akan didapat
- ✅ Tidak ada kejutan
- ✅ Bisa rencanana dengan nomor bukti tersebut

---

**Versi**: 2.0 ( dengan Preview Real-time)  
**Last Updated**: 24 April 2026  
**Files**:
- `resources/views/tebar/index.blade.php`
- `app/Http/Controllers/Web/TebarController.php`
- `routes/web.php`
- `database/migrations/2026_04_24_043249_create_auto_no_bukti_system_for_ttebar.php`
