17 KiB
17 KiB
📘 PROFILE VS PANEL - QUICK REFERENCE GUIDE
🎯 KONSEP DASAR
Profile (PR)
Definisi: Paket yang harga finalnya selalu sama dengan total harga item (summary/penjumlahan).
Karakteristik:
- ✅ Harga Paket = Total Harga Item (otomatis)
- ❌ Tidak bisa edit Harga Paket manual
- ❌ Tidak bisa edit diskon detail item
- ✅ Cocok untuk paket standar yang harganya adalah penjumlahan pemeriksaan
Use Case:
- Paket MCU Standard
- Paket Pemeriksaan Rutin
- Paket yang tidak perlu diskon khusus
Panel (PN)
Definisi: Paket yang harga finalnya bisa diatur custom dengan diskon/markup tertentu.
Karakteristik:
- ✅ Harga Paket bisa diatur manual (dengan lock mechanism)
- ✅ Bisa edit diskon detail per item
- ✅ Support 2 mode: Unlocked (auto-calculate) dan Locked (fixed price)
- ✅ Cocok untuk paket dengan harga paket spesial
Use Case:
- Paket MCU dengan harga korporat
- Paket promo dengan diskon khusus
- Paket custom per perusahaan
📊 COMPARISON TABLE
| Feature | Profile (PR) | Panel (PN) |
|---|---|---|
| Harga Paket | Selalu = Total Harga | Bisa diatur manual |
| Edit Harga Paket | ❌ Tidak bisa | ✅ Bisa (dengan lock) |
| Edit Diskon Detail | ❌ Tidak bisa | ✅ Bisa |
| Disc % per Item | ❌ Tidak tersedia | ✅ Tersedia |
| Disc Rp per Item | ❌ Tidak tersedia | ✅ Tersedia |
| Auto-calculate | ✅ Selalu | ✅/❌ Tergantung state |
| Lock Mechanism | ❌ Tidak ada | ✅ Ada |
| Pro-rata Distribution | ❌ Tidak perlu | ✅ Saat edit harga |
| UI Indicator | Chip biru "Profile" | Chip orange "Dikunci" (jika locked) |
| Complexity | Simple | Advanced |
🔄 STATE DIAGRAM
Profile Packet Flow
[Create Profile]
↓
[Add Items] → [Total Harga ter-update]
↓
[Harga Paket = Total Harga (auto)]
↓
[Save]
↓
[DONE] ✅
Note:
- Tidak ada state "locked/unlocked"
- Harga selalu sama dengan total
- Tidak bisa edit harga atau diskon
Panel Packet Flow - Unlocked Mode
[Create Panel]
↓
[Add Items] → [Total Harga ter-update]
↓
[Harga Paket = Total Harga (auto)] ← UNLOCKED
↓
[Add/Remove Items] → [Harga Paket auto-update]
↓
[Save]
↓
[LOCKED] 🔒
↓
[Edit lagi] → [Harga tetap fixed]
Panel Packet Flow - Locked Mode
[Paket tersimpan di DB dengan harga custom]
↓
[Edit Paket]
↓
[LOCKED] 🔒
↓
[Add Items] → [Harga Paket TETAP]
[Remove Items] → [Harga Paket TETAP]
↓
[Untuk ubah harga:]
[Click icon Edit] → [Edit Harga] → [Click Save] → [Tetap LOCKED]
Panel Packet Flow - Edit Harga Manual
[Panel in Edit Mode]
↓
[Click icon "Edit" di field Harga Paket]
↓
[Field jadi editable]
↓
[Ubah harga: Rp 500k → Rp 400k]
↓
[Pro-rata distribution executed]
↓
[Disc % → 0, Disc Rp → distributed]
↓
[Click icon "Save"]
↓
[Harga LOCKED 🔒]
↓
[Add/remove items → Harga tetap Rp 400k]
💡 EXAMPLES
Example 1: Profile Packet
Paket MCU Executive (Profile)
Items:
1. Hemoglobin : Rp 25.000
2. Leukosit : Rp 25.000
3. Gula Darah : Rp 30.000
4. Kolesterol : Rp 40.000
5. SGOT : Rp 35.000
Total Harga : Rp 155.000
Harga Paket : Rp 155.000 ← (sama dengan total, auto)
Action:
- ❌ Tidak bisa ubah Harga Paket
- ❌ Tidak bisa edit Disc % atau Disc Rp
- ✅ Bisa add/remove items
- ✅ Harga Paket otomatis = Total
Example 2: Panel Packet - Unlocked (New)
Paket Diabetes Panel (Panel) - Baru dibuat
Items:
1. Gula Darah Puasa : Rp 30.000
2. Gula Darah 2j PP : Rp 30.000
3. HbA1c : Rp 120.000
4. Kolesterol : Rp 40.000
Total Harga : Rp 220.000
Harga Paket : Rp 220.000 ← (auto, karena UNLOCKED)
State: UNLOCKED (belum disimpan)
Action:
- ✅ Add item → Harga Paket otomatis update
- ✅ Remove item → Harga Paket otomatis update
- ✅ Bisa edit Harga Paket → Jadi LOCKED setelah save
- ✅ Bisa edit Disc % dan Disc Rp per item
Example 3: Panel Packet - Locked (Saved in DB)
Paket Diabetes Panel (Panel) - Sudah tersimpan dengan harga custom
Items:
1. Gula Darah Puasa : Rp 30.000 (Disc Rp: 5k) = Rp 25.000
2. Gula Darah 2j PP : Rp 30.000 (Disc Rp: 5k) = Rp 25.000
3. HbA1c : Rp 120.000 (Disc Rp: 20k) = Rp 100.000
4. Kolesterol : Rp 40.000 (Disc Rp: 10k) = Rp 30.000
Total Harga : Rp 180.000
Harga Paket : Rp 180.000 ← (fixed, LOCKED 🔒)
State: LOCKED (sudah tersimpan di database)
Action:
- ✅ Add item → Total update, tapi Harga Paket TETAP Rp 180k
- ✅ Remove item → Total update, tapi Harga Paket TETAP Rp 180k
- ✅ Untuk ubah harga → Klik icon Edit, ubah, klik Save
- ✅ Bisa edit Disc % dan Disc Rp per item
Example 4: Panel Packet - Edit Harga Manual
Paket Hepatitis Panel (Panel)
Initial:
1. HBsAg : Rp 80.000
2. Anti HBs : Rp 80.000
3. Anti HCV : Rp 120.000
4. SGOT : Rp 35.000
5. SGPT : Rp 35.000
Total Harga : Rp 350.000
Harga Paket (default) : Rp 350.000
User Action: Edit Harga Paket → Rp 300.000
System Action: Pro-rata distribution
Total Disc = 350k - 300k = Rp 50.000
Distribution:
1. HBsAg : Disc Rp = (80k/350k) × 50k = Rp 11.429 → Rp 68.571
2. Anti HBs : Disc Rp = (80k/350k) × 50k = Rp 11.429 → Rp 68.571
3. Anti HCV : Disc Rp = (120k/350k) × 50k = Rp 17.143 → Rp 102.857
4. SGOT : Disc Rp = (35k/350k) × 50k = Rp 5.000 → Rp 30.000
5. SGPT : Disc Rp = Remaining = Rp 4.999 → Rp 30.001
Total Harga Paket: Rp 300.000 ✅
State: LOCKED 🔒
Note:
- Semua Disc % di-set ke 0
- Disc Rp terdistribusi pro-rata
- Item terakhir dapat sisa untuk menghindari rounding error
🧪 TESTING SCENARIOS
Scenario A: Profile Basic Flow
✅ Test Steps:
1. Create paket "MCU Standard" tipe Profile
2. Add 5 items
3. Verify: Harga Paket = Total Harga
4. Try to edit Harga Paket → Should be disabled
5. Try to edit Disc % → Should not have edit button
6. Save paket
7. Verify: Data saved correctly
✅ Expected:
- Field Harga Paket disabled (Profile type)
- No edit buttons for discounts
- Chip "Profile" visible dengan info icon
- Alert info: "Profile: Harga paket adalah summary..."
Scenario B: Panel Unlocked Flow
✅ Test Steps:
1. Create paket "Diabetes Panel" tipe Panel
2. Add 3 items (total Rp 200k)
3. Verify: Harga Paket = Rp 200k (auto)
4. Add 1 more item (Rp 50k)
5. Verify: Harga Paket = Rp 250k (auto-update)
6. Remove 1 item
7. Verify: Harga Paket updates accordingly
8. Save paket
9. Re-edit paket
10. Verify: Now LOCKED
✅ Expected:
- Harga Paket auto-updates on add/remove (before save)
- No "Dikunci" chip before save
- After save and re-edit: "Dikunci" chip appears
- Console log: "Panel UNLOCKED - updating..."
Scenario C: Panel Locked Flow
✅ Test Steps:
1. Open existing Panel paket (saved in DB)
2. Verify: "Dikunci" chip visible
3. Add 1 item (Rp 50k)
4. Verify: Total Harga increases, Harga Paket STAYS SAME
5. Remove 1 item
6. Verify: Total Harga decreases, Harga Paket STAYS SAME
7. Console should log: "Panel LOCKED - NOT updating"
✅ Expected:
- "Dikunci" chip with lock icon visible
- Tooltip explains locked behavior
- Total Harga changes with add/remove
- Harga Paket remains fixed
- Console log: "Panel LOCKED - NOT updating packet price"
Scenario D: Panel Edit Harga Manual
✅ Test Steps:
1. Open Panel paket in edit mode (3 items, total Rp 300k)
2. Click icon "Edit" next to Harga Paket field
3. Verify: Field becomes editable, icon changes to "Save"
4. Change Harga Paket to Rp 250k
5. Verify: Pro-rata distribution happens automatically
6. Verify: All Disc % = 0
7. Verify: All Disc Rp updated proportionally
8. Verify: Sum of all item prices = Rp 250k
9. Click icon "Save"
10. Verify: Alert shows, chip "Dikunci" appears
11. Add new item
12. Verify: Harga Paket stays Rp 250k
✅ Expected:
- Edit/Save icon toggle works
- Pro-rata calculation correct
- All Disc % cleared to 0
- Disc Rp distributed proportionally
- After save: locked state
- Alert: "Harga paket dikonfirmasi dan dikunci..."
Scenario E: Panel Edit Diskon Detail
✅ Test Steps:
1. Open Panel paket in edit mode
2. Click "Edit Diskon Detail Paket"
3. Verify: Disc % and Disc Rp columns become input fields
4. Edit Item 1: Disc % = 10
5. Verify: Item 1 price updates (Bruto - 10% - Disc Rp)
6. Edit Item 2: Disc Rp = Rp 5.000
7. Verify: Item 2 price updates (Bruto - Disc% - 5k)
8. Verify: Total Harga updates
9. Verify: Harga Paket updates (if unlocked)
10. Click "Simpan Diskon Detail"
11. Verify: Edit mode closes, values preserved
✅ Expected:
- Input fields appear in table cells
- Real-time calculation on each change
- Formula: Price = Bruto - (Bruto × Disc%/100) - Disc Rp
- Total updates automatically
- Alert after save: "Diskon detail dikonfirmasi..."
🎨 UI/UX DIFFERENCES
Profile UI
┌─────────────────────────────────────────────┐
│ MCU Standard Profile (Profile) │
├─────────────────────────────────────────────┤
│ │
│ HARGA PAKET: Rp 500.000 [ℹ️ Profile] │
│ (Field disabled, read-only) │
│ │
│ TOTAL HARGA: Rp 500.000 │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ ℹ️ Profile: Harga paket adalah │ │
│ │ summary dari total detail. Tidak │ │
│ │ dapat mengubah harga paket atau │ │
│ │ diskon detail. │ │
│ └──────────────────────────────────────┘ │
│ │
│ [Kembali] [Simpan Paket] [Batal & Kembali] │
└─────────────────────────────────────────────┘
Table: (No edit disc buttons)
| Kode | Nama | Bruto | Disc % | Disc Rp | Harga | Act |
|------|------|-------|--------|---------|-------|-----|
| HB | Hemo | 25k | 0% | 0 | 25k | « |
(Disc columns are read-only, cannot edit)
Panel UI - Unlocked
┌─────────────────────────────────────────────┐
│ Diabetes Panel (Panel) │
├─────────────────────────────────────────────┤
│ │
│ HARGA PAKET: Rp 400.000 [✏️] │
│ (Can click edit icon) │
│ │
│ TOTAL HARGA: Rp 500.000 │
│ │
│ [Kembali] [Simpan Paket] [Batal & Kembali] │
│ │
│ [Edit Diskon Detail Paket] │
│ │
└─────────────────────────────────────────────┘
Table:
| Kode | Nama | Bruto | Disc % | Disc Rp | Harga | Act |
|------|------|-------|--------|---------|-------|-----|
| GDP | GDP | 30k | 0% | 0 | 30k | « |
(Normal display, can edit via button)
Panel UI - Locked
┌─────────────────────────────────────────────┐
│ Diabetes Panel (Panel) │
├─────────────────────────────────────────────┤
│ │
│ HARGA PAKET: Rp 400.000 [✏️] [🔒 Dikunci] │
│ Hint: Harga dikunci, tidak berubah otomatis │
│ │
│ TOTAL HARGA: Rp 500.000 │
│ │
│ [Kembali] [Simpan Paket] [Batal & Kembali] │
│ │
│ [Edit Diskon Detail Paket] │
│ │
└─────────────────────────────────────────────┘
Tooltip on 🔒 Dikunci:
"Harga paket dikunci. Tidak akan berubah
otomatis saat add/remove item.
Klik icon Edit Harga untuk mengubah."
Panel UI - Edit Diskon Mode
┌─────────────────────────────────────────────┐
│ [Batal Edit Diskon] │
│ ℹ️ Edit diskon persen (%) dan/atau diskon │
│ rupiah (Rp) untuk setiap item │
└─────────────────────────────────────────────┘
Table:
| Kode | Nama | Bruto | Disc % | Disc Rp | Harga | Act |
|------|------|-------|-----------|-----------|-------|-----|
| GDP | GDP | 30k | [ 10 ] | [ 5000 ] | 22k | « |
| └────┬────┘ └────┬────┘
| Input fields (editable)
🔍 DEBUGGING TIPS
Console Logs to Watch
Profile Packet
// Should NOT see these logs for Profile
❌ "Panel UNLOCKED - updating packet price"
❌ "Panel LOCKED - NOT updating"
❌ "PRO-RATA DISTRIBUTION"
Panel Unlocked
// Should see these logs
✅ "Panel UNLOCKED - updating packet price to X"
✅ "Calculated total: X"
✅ "Current packet price: X"
Panel Locked
// Should see these logs
✅ "Panel LOCKED - NOT updating packet price (stays fixed)"
✅ "Remove: Panel LOCKED - NOT updating packet price"
✅ "Data from DB: true Locked: true"
Panel Edit Harga
// Should see these logs
✅ "=== PRO-RATA DISTRIBUTION ==="
✅ "Packet Price: 400000"
✅ "Total Price: 500000"
✅ "Difference to distribute: 100000"
✅ "Item 1: ..."
✅ " - Bruto: 200000"
✅ " - Disc %: 0 (CLEARED)"
✅ " - Disc Rp: 40000"
✅ " - Final Price: 160000"
✅ "=== PRO-RATA COMPLETED ==="
📚 KEY FORMULAS
1. Detail Item Price Calculation
Price = Bruto - (Bruto × Disc% / 100) - DiscRp
Example:
Bruto = 100,000
Disc% = 10
DiscRp = 5,000
Price = 100,000 - (100,000 × 10/100) - 5,000
= 100,000 - 10,000 - 5,000
= 85,000
2. Pro-rata Distribution
TotalDisc = TotalPrice - PacketPrice
For each item:
ItemDisc = (ItemBruto / TotalBruto) × TotalDisc
ItemPrice = ItemBruto - ItemDisc
Last item: ItemDisc = TotalDisc - SumOfOtherDiscs (to avoid rounding error)
Example:
Item A: 200k, Item B: 200k, Item C: 100k
Total: 500k → Packet: 400k
TotalDisc = 100k
Item A: (200/500) × 100k = 40k → Price: 160k
Item B: (200/500) × 100k = 40k → Price: 160k
Item C: 100k - (40k+40k) = 20k → Price: 80k
Verify: 160k + 160k + 80k = 400k ✅
3. Total Price Calculation
TotalPrice = Σ(Item.Price)
Where Item.Price calculated per formula #1
4. Profile Packet Price
PacketPrice = TotalPrice (always, cannot be different)
5. Panel Packet Price
If Unlocked:
PacketPrice = TotalPrice (auto-update)
If Locked:
PacketPrice = Fixed value (doesn't change on add/remove)
✅ QUICK DECISION TREE
"Should I use Profile or Panel?"
START
│
├─ Harga paket = penjumlahan items?
│ │
│ ├─ YES → Use PROFILE
│ │
│ └─ NO → Harga paket ada diskon/markup khusus?
│ │
│ ├─ YES → Use PANEL
│ │ │
│ │ ├─ Need custom price → PANEL (edit harga manual)
│ │ └─ Need item discounts → PANEL (edit diskon detail)
│ │
│ └─ NO → Use PROFILE (keep it simple)
Examples:
- Profile: "Paket MCU Dasar" = Hemo + Leuko + GDP → Harga = sum
- Panel: "Paket MCU Korporat" = Paket diskon 20% untuk perusahaan
- Panel: "Paket Promo" = Harga spesial Rp 500k (dari total Rp 600k)
🎯 TESTING PRIORITY
Must Test (P0)
- ✅ Profile: Harga = Total (always)
- ✅ Panel Unlocked: Auto-update price
- ✅ Panel Locked: Fixed price
- ✅ Panel Edit Harga: Pro-rata distribution
- ✅ Save and reload: State persists
Should Test (P1)
- ✅ Profile: Cannot edit price/disc
- ✅ Panel: Can edit disc detail
- ✅ Lock state after save
- ✅ Unlock → Lock transition
Nice to Test (P2)
- ✅ UI indicators (chips, icons)
- ✅ Tooltips and hints
- ✅ Console logs
- ✅ Edge cases (0 items, large numbers)
Quick Reference Version: 1.0
Last Updated: 2026-01-22
For Full Testing Guide: See TESTING_GUIDE.md