feat: add percentage loyalti setting mode
This commit is contained in:
@@ -323,13 +323,13 @@ Pada kedua `PUT` setting, field yang tidak dikirim tetap memakai nilai sekarang;
|
||||
|
||||
```json
|
||||
{
|
||||
"point": { "enabled": true, "earn_per_amount": 100, "earn_value": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"coin": { "enabled": true, "earn_per_amount": 25000, "earn_value": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"point": { "enabled": true, "earn_mode": "PER_AMOUNT", "earn_per_amount": 100, "earn_value": 1, "earn_percent": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"coin": { "enabled": true, "earn_mode": "PER_AMOUNT", "earn_per_amount": 25000, "earn_value": 1, "earn_percent": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"point_payment": { "accept_payment": true, "min_payment_points": 1, "max_payment_percent": 100 }
|
||||
}
|
||||
```
|
||||
|
||||
Response menambahkan `outlet_id`, `point_value`, `point_cashback_percent` (default di atas = 1%), dan `changes` pada PUT. Validasi: `earn_per_amount > 0`, `earn_value ≥ 0`, `max_payment_percent` 0–100.
|
||||
Response menambahkan `outlet_id`, `point_value`, `point_cashback_percent` (default di atas = 1%), dan `changes` pada PUT. `earn_mode` adalah `PER_AMOUNT` (setiap `earn_per_amount` rupiah mendapat `earn_value`) atau `PERCENTAGE` (`earn_percent` persen dari basis). Validasi: `earn_per_amount > 0`, `earn_value ≥ 0`, `earn_percent` 0–100 dengan maks. 2 angka desimal, `max_payment_percent` 0–100.
|
||||
|
||||
### /marketing/loyalty-settings
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ Tiap outlet mengatur sendiri berapa EnakPoint dan EnakCoin yang didapat dari ord
|
||||
|
||||
```json
|
||||
{
|
||||
"point": { "enabled": true, "earn_per_amount": 100, "earn_value": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"coin": { "enabled": true, "earn_per_amount": 25000, "earn_value": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"point": { "enabled": true, "earn_mode": "PER_AMOUNT", "earn_per_amount": 100, "earn_value": 1, "earn_percent": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"coin": { "enabled": true, "earn_mode": "PER_AMOUNT", "earn_per_amount": 25000, "earn_value": 1, "earn_percent": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"point_payment": { "accept_payment": true, "min_payment_points": 1, "max_payment_percent": 100 }
|
||||
}
|
||||
```
|
||||
@@ -41,15 +41,19 @@ Tiap outlet mengatur sendiri berapa EnakPoint dan EnakCoin yang didapat dari ord
|
||||
| Field | Label usulan | Tipe | Default | Validasi |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `point.enabled` / `coin.enabled` | Beri EnakPoint / EnakCoin | toggle | mati | – |
|
||||
| `earn_per_amount` | Setiap belanja Rp … | Rp | 100 (point), 25.000 (coin) | > 0 |
|
||||
| `earn_value` | … mendapat | angka | 1 | ≥ 0 |
|
||||
| `earn_mode` | Cara hitung: per nominal / persentase | pilihan `PER_AMOUNT` / `PERCENTAGE` | `PER_AMOUNT` | salah satu dari keduanya |
|
||||
| `earn_per_amount` | Setiap belanja Rp … (mode `PER_AMOUNT`) | Rp | 100 (point), 25.000 (coin) | > 0 |
|
||||
| `earn_value` | … mendapat (mode `PER_AMOUNT`) | angka | 1 | ≥ 0 |
|
||||
| `earn_percent` | … % dari belanja (mode `PERCENTAGE`) | %, boleh desimal | 1 | 0–100, maks. 2 angka desimal |
|
||||
| `min_order_amount` | Minimal belanja | Rp | 0 | ≥ 0 |
|
||||
| `max_per_order` | Maksimal per order | angka, boleh kosong | kosong = tanpa batas | ≥ 0 |
|
||||
| `point_payment.accept_payment` | Terima pembayaran EnakPoint | toggle | mati | – |
|
||||
| `min_payment_points` | Minimal EnakPoint per pembayaran | angka | 1 | ≥ 1 |
|
||||
| `max_payment_percent` | Maksimal porsi order dibayar EnakPoint | % | 100 | 0–100 |
|
||||
|
||||
**Cashback efektif.** Response membawa `point_cashback_percent` dan `point_value`. Tampilkan persentase di samping field earning EnakPoint, mis. "setara cashback 1%", dan hitung ulang di sisi klien saat owner mengetik: `earn_value × point_value ÷ earn_per_amount × 100`. Tujuannya agar owner tidak salah membaca skala (1 per Rp 100 bukan 1 per Rp 1).
|
||||
**Cashback efektif.** Response membawa `point_cashback_percent` dan `point_value`. Tampilkan persentase di samping field earning EnakPoint, mis. "setara cashback 1%", dan hitung ulang di sisi klien saat owner mengetik: `earn_value × point_value ÷ earn_per_amount × 100`, atau pada mode `PERCENTAGE`: `earn_percent × point_value`. Tujuannya agar owner tidak salah membaca skala (1 per Rp 100 bukan 1 per Rp 1).
|
||||
|
||||
**Mode earning.** Tampilkan hanya field mode yang dipilih (`earn_per_amount` + `earn_value`, atau `earn_percent`). Field mode lain tetap tersimpan di server, jadi tidak perlu dikosongkan saat owner berpindah mode. Pada mode `PERCENTAGE` jumlah yang didapat adalah `floor(basis × earn_percent ÷ 100)`, mis. 2,5% dari Rp 87.500 = 2.187 EnakPoint.
|
||||
|
||||
**Contoh di bawah form.** "Belanja Rp 87.500 mendapat 875 EnakPoint dan 3 EnakCoin." Earning dihitung dari subtotal setelah diskon, sebelum pajak, dan bagian yang dibayar EnakPoint tidak ikut dihitung.
|
||||
|
||||
|
||||
@@ -516,15 +516,16 @@ Semua endpoint di bagian ini butuh login user dengan role Admin atau Manager.
|
||||
|
||||
```json
|
||||
{
|
||||
"point": { "enabled": true, "earn_per_amount": 100, "earn_value": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"coin": { "enabled": true, "earn_per_amount": 25000, "earn_value": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"point": { "enabled": true, "earn_mode": "PER_AMOUNT", "earn_per_amount": 100, "earn_value": 1, "earn_percent": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"coin": { "enabled": true, "earn_mode": "PER_AMOUNT", "earn_per_amount": 25000, "earn_value": 1, "earn_percent": 1, "min_order_amount": 0, "max_per_order": null },
|
||||
"point_payment": { "accept_payment": true, "min_payment_points": 1, "max_payment_percent": 100 }
|
||||
}
|
||||
```
|
||||
|
||||
Field yang tidak dikirim di `PUT` tetap memakai nilai sekarang. Response menambahkan
|
||||
`point_value` organisasi dan `point_cashback_percent`
|
||||
(`earn_value × point_value / earn_per_amount × 100`). **Tampilkan persentase ini di
|
||||
(`earn_value × point_value / earn_per_amount × 100`, atau `earn_percent × point_value`
|
||||
pada `earn_mode` `PERCENTAGE`). **Tampilkan persentase ini di
|
||||
samping setting** supaya owner tidak salah membaca skala: default di atas setara
|
||||
cashback 1%.
|
||||
|
||||
|
||||
+19
-5
@@ -197,20 +197,28 @@ Disimpan di `outlet_settings` (key–value, sudah ada).
|
||||
| Key | Tipe | Default | Arti |
|
||||
|---|---|---|---|
|
||||
| `loyalty.point.enabled` | bool | `false` | Outlet memberi EnakPoint |
|
||||
| `loyalty.point.earn_per_amount` | int (Rp) | `100` | Setiap kelipatan nominal ini… |
|
||||
| `loyalty.point.earn_mode` | `PER_AMOUNT` / `PERCENTAGE` | `PER_AMOUNT` | Cara menghitung earning |
|
||||
| `loyalty.point.earn_per_amount` | int (Rp) | `100` | `PER_AMOUNT`: setiap kelipatan nominal ini… |
|
||||
| `loyalty.point.earn_value` | int | `1` | …mendapat sekian EnakPoint |
|
||||
| `loyalty.point.earn_percent` | desimal (0–100, maks. 2 angka desimal) | `1` | `PERCENTAGE`: sekian persen dari basis menjadi EnakPoint |
|
||||
| `loyalty.point.min_order_amount` | int (Rp) | `0` | Basis minimal agar dapat EnakPoint |
|
||||
| `loyalty.point.max_per_order` | int, nullable | kosong | Batas atas EnakPoint per order |
|
||||
| `loyalty.coin.enabled` | bool | `false` | Outlet memberi EnakCoin |
|
||||
| `loyalty.coin.earn_mode` | `PER_AMOUNT` / `PERCENTAGE` | `PER_AMOUNT` | |
|
||||
| `loyalty.coin.earn_per_amount` | int (Rp) | `25000` | |
|
||||
| `loyalty.coin.earn_value` | int | `1` | |
|
||||
| `loyalty.coin.earn_percent` | desimal (0–100, maks. 2 angka desimal) | `1` | |
|
||||
| `loyalty.coin.min_order_amount` | int (Rp) | `0` | |
|
||||
| `loyalty.coin.max_per_order` | int, nullable | kosong | |
|
||||
|
||||
Dengan nilai EnakPoint default Rp 1, default earning 1 EnakPoint per Rp 100 setara
|
||||
**cashback 1%**. Dashboard selalu menampilkan persentase cashback efektif di samping
|
||||
setting ini: `earn_value × nilai EnakPoint / earn_per_amount`. Tujuannya supaya owner
|
||||
tidak salah mengira skala.
|
||||
setting ini: `earn_value × nilai EnakPoint / earn_per_amount`, atau pada mode
|
||||
`PERCENTAGE`: `earn_percent × nilai EnakPoint`. Tujuannya supaya owner tidak salah
|
||||
mengira skala.
|
||||
|
||||
Setting mode yang sedang tidak dipakai tetap tersimpan, sehingga berpindah mode tidak
|
||||
menghapus nilai mode sebelumnya.
|
||||
|
||||
**Pembayaran EnakPoint.** Hanya ada untuk EnakPoint, tidak ada padanannya untuk
|
||||
EnakCoin.
|
||||
@@ -226,7 +234,8 @@ EnakCoin.
|
||||
```
|
||||
basis = subtotal − discount_amount − dibayar_dengan_enakpoint
|
||||
jumlah = 0 jika basis < min_order_amount
|
||||
jumlah = floor(basis / earn_per_amount) × earn_value
|
||||
jumlah = floor(basis / earn_per_amount) × earn_value mode PER_AMOUNT
|
||||
jumlah = floor(basis × earn_percent / 100) mode PERCENTAGE
|
||||
jumlah = min(jumlah, max_per_order) jika max_per_order diisi
|
||||
```
|
||||
|
||||
@@ -240,7 +249,12 @@ jumlah = min(jumlah, max_per_order) jika max_per_order diisi
|
||||
EnakPoint** dan **3 EnakCoin**. Jika Rp 20.000 dari order itu dibayar dengan EnakPoint,
|
||||
basisnya menjadi Rp 67.500, sehingga customer mendapat 675 EnakPoint dan 2 EnakCoin.
|
||||
|
||||
Validasi: `earn_per_amount > 0`, `earn_value ≥ 0`, `min_order_amount ≥ 0`,
|
||||
Pada mode `PERCENTAGE`, `earn_percent` adalah persen dari basis yang menjadi
|
||||
**jumlah** EnakPoint/EnakCoin (bukan nilai rupiahnya): 2,5% dari basis Rp 87.500
|
||||
menghasilkan 2.187 EnakPoint.
|
||||
|
||||
Validasi: `earn_per_amount > 0`, `earn_value ≥ 0`, `0 ≤ earn_percent ≤ 100` dengan
|
||||
paling banyak dua angka desimal, `min_order_amount ≥ 0`,
|
||||
`max_per_order ≥ 0`, `0 ≤ max_payment_percent ≤ 100`. Hanya role Admin/Manager yang
|
||||
bisa mengubah.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user