# Debug: SALES_RECEIPT Terhenti Setelah Jam 10 (SALES_INVOICE Normal)

## Masalah

- ✅ **SALES_INVOICE** masih normal sampai sekarang
- ❌ **SALES_RECEIPT** terhenti setelah jam 10 (padahal transaksi sampai jam 17)
- ❌ Di database MySQL hanya **1 SALES_RECEIPT** terinput

Karena SALES_INVOICE masih normal, masalahnya **spesifik ke SALES_RECEIPT**, bukan di service/infrastruktur umum.

---

## Langkah Debugging (Fokus SALES_RECEIPT)

### 1. Bandingkan SALES_RECEIPT vs SALES_INVOICE di Queue

```bash
sqlite3 /opt/webhook-service/data/webhook.db "
SELECT 
    type,
    status,
    COUNT(*) as count,
    MIN(datetime(created_at)) as first,
    MAX(datetime(created_at)) as last
FROM webhook_queue 
WHERE datetime(created_at) >= '2026-02-02 00:00:00'
GROUP BY type, status
ORDER BY type, status;
"
```

**Yang dicari:**
- Apakah SALES_RECEIPT masih masuk ke `webhook_queue` setelah jam 10?
- Apakah status SALES_RECEIPT berbeda dengan SALES_INVOICE (mis. banyak failed)?

---

### 2. Cek Payload SALES_RECEIPT Setelah Jam 10 (Apakah Semua DFT?)

```bash
sqlite3 /opt/webhook-service/data/webhook.db "
SELECT 
    id,
    type,
    status,
    substr(payload, 
        instr(payload, '\"salesReceiptNo\"') + 18, 
        30
    ) AS receipt_no,
    datetime(created_at) as created
FROM webhook_queue 
WHERE type = 'SALES_RECEIPT'
    AND datetime(created_at) >= '2026-02-02 10:00:00'
ORDER BY id DESC
LIMIT 50;
"
```

**Yang dicari:**
- Apakah semua `receipt_no` dimulai dengan **"DFT"** (draft)?
- Jika semua DFT → receiver.php akan **skip semua** → tidak masuk database MySQL

**Ini adalah penyebab paling mungkin!**

---

### 3. Cek Error Forward SALES_RECEIPT ke Shared Hosting

```bash
# Cek log untuk error spesifik SALES_RECEIPT
sudo journalctl -u webhook-service --since "2026-02-02 10:00:00" | grep -i "receipt\|SALES_RECEIPT"
```

**Yang dicari:**
- `⚠️ [Queue X] Retry` untuk SALES_RECEIPT
- `shared hosting status 500` atau `timeout` saat forward SALES_RECEIPT
- `💀 [Queue X] Failed` untuk SALES_RECEIPT

**Jika ada error forward:** Cek apakah shared hosting **receiver.php** error spesifik untuk SALES_RECEIPT.

---

### 4. Cek Log Shared Hosting (receiver.php) untuk SALES_RECEIPT

**Di shared hosting (cPanel error log):**

Cari log dengan keyword: `[Receipt]`, `SALES_RECEIPT`, `Skipping Draft`

**Yang dicari:**
- `[Receipt] Skipping Draft: DFT.xxxxx` → banyak yang di-skip karena draft
- `[Receipt] API Error: ...` → API Accurate error saat ambil detail
- `[Receipt] No PO Number found` → detail invoice tidak punya PO Number
- `[Receipt] PO xxxxx not found in DB` → PO tidak ada di database
- `[Receipt] Skip: Duplicate` → sudah pernah diproses (idempotency)
- `[Receipt] DB Critical Error: ...` → error saat insert/update database

---

### 5. Bandingkan Struktur Payload SALES_RECEIPT vs SALES_INVOICE

```bash
# Lihat contoh payload SALES_RECEIPT yang masuk setelah jam 10
sqlite3 /opt/webhook-service/data/webhook.db "
SELECT payload 
FROM webhook_queue 
WHERE type = 'SALES_RECEIPT'
    AND datetime(created_at) >= '2026-02-02 10:00:00'
LIMIT 1;
" | jq .

# Bandingkan dengan SALES_INVOICE
sqlite3 /opt/webhook-service/data/webhook.db "
SELECT payload 
FROM webhook_queue 
WHERE type = 'SALES_INVOICE'
    AND datetime(created_at) >= '2026-02-02 10:00:00'
LIMIT 1;
" | jq .
```

**Yang dicari:**
- Apakah struktur payload berbeda?
- Apakah ada field yang hilang di SALES_RECEIPT?
- Apakah `action` berbeda? (mis. SALES_RECEIPT pakai "DELETE" bukan "WRITE")

---

### 6. Test Manual SALES_RECEIPT ke Receiver

**Dari VPS, test dengan payload SALES_RECEIPT:**

```bash
curl -X POST https://po.persadalab.com/webhook/receiver.php \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Secret: 8f7b2c5e4d1a9b0c3f5e9d8a7b6c5a4b3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a" \
  -H "X-Webhook-Type: SALES_RECEIPT" \
  -d '{
    "payload": {
      "databaseId": 1293289,
      "type": "SALES_RECEIPT",
      "data": [{
        "salesReceiptNo": "BK8-01.26-000691",
        "action": "WRITE"
      }]
    }
  }'
```

**Expected response:** `{"status":"success","message":"Processed"}`

**Jika error:** Cek error message untuk tahu masalahnya di mana.

---

## Kemungkinan Penyebab (Spesifik SALES_RECEIPT)

### A. Semua Payload DFT (Draft) - Paling Mungkin ✅

**Gejala:** Semua `salesReceiptNo` setelah jam 10 dimulai dengan **"DFT"**

**Penyebab:** Accurate hanya kirim webhook saat **buat draft** (DFT), bukan saat **validasi** (BKB)

**Solusi:** 
- Ini **normal behavior** Accurate untuk SALES_RECEIPT
- Receiver.php memang **skip DFT** (benar, karena belum nomor final)
- Untuk dapat BKB: tanya Accurate support apakah bisa kirim webhook saat **validasi**, atau push manual

**Cek dengan query di langkah 2 di atas.**

---

### B. API Accurate Error Saat Ambil Detail

**Gejala:** Log shared hosting ada `[Receipt] API Error: ...`

**Penyebab:** 
- API `sales-receipt/detail.do` error atau timeout
- Auth token expired atau invalid
- Receipt number tidak ditemukan di Accurate

**Solusi:**
- Cek log error di shared hosting
- Test manual API: `curl -X GET "https://iris.accurate.id/accurate/api/sales-receipt/detail.do?number=BK8-01.26-000691"` dengan header auth
- Pastikan `ACCURATE_AUTH_TOKEN` masih valid

---

### C. Tidak Ada PO Number di Detail Invoice

**Gejala:** Log shared hosting ada `[Receipt] No PO Number found in detail`

**Penyebab:** 
- Detail invoice dari Accurate tidak punya field `poNumber`
- Struktur response API berubah

**Solusi:**
- Cek response API Accurate untuk sales-receipt detail
- Mungkin perlu update logic di `receiver.php` untuk ambil PO Number dari field lain

---

### D. PO Tidak Ditemukan di Database

**Gejala:** Log shared hosting ada `[Receipt] PO xxxxx not found in DB`

**Penyebab:** 
- PO Number dari Accurate tidak match dengan nomor PO di database MySQL
- Format nomor berbeda (spasi, dash, dll)

**Solusi:**
- Cek apakah PO Number di Accurate match dengan `t_po.nomor` di database
- Mungkin perlu normalize (trim, uppercase, dll) sebelum query

---

### E. Duplicate (Idempotency)

**Gejala:** Log shared hosting ada `[Receipt] Skip: Duplicate`

**Penyebab:** 
- Receipt sudah pernah diproses sebelumnya
- Idempotency key sama

**Solusi:**
- Ini normal jika webhook dikirim ulang oleh Accurate
- Tidak perlu action, sudah benar di-skip

---

## Ringkasan Checklist (SALES_RECEIPT Only)

| No | Cek | Perintah |
|----|-----|----------|
| 1 | Bandingkan SALES_RECEIPT vs SALES_INVOICE | Query SQLite: `SELECT type, status, COUNT(*) ... GROUP BY type, status` |
| 2 | Apakah semua DFT? | Query SQLite: `SELECT substr(payload, ...) AS receipt_no ...` |
| 3 | Error forward? | `journalctl ... | grep -i "receipt"` |
| 4 | Log shared hosting? | cPanel error log → cari `[Receipt]` |
| 5 | Struktur payload berbeda? | `SELECT payload FROM ... WHERE type='SALES_RECEIPT'` |
| 6 | Test manual receiver? | `curl -X POST ...` dengan payload SALES_RECEIPT |

---

## Kesimpulan

Karena **SALES_INVOICE masih normal**, masalahnya pasti di:
1. ✅ **Payload SALES_RECEIPT semua DFT** (paling mungkin) → receiver skip semua
2. ✅ **Error spesifik di handleSalesReceipt()** → cek log shared hosting
3. ✅ **API Accurate error untuk sales-receipt** → cek log error

**Mulai dari langkah 2** (cek apakah semua DFT) - itu penyebab paling mungkin!
