# 360 Credit Union Bot - Hướng dẫn sử dụng

Bot Discord quản lý credit, item (thẻ bài), reward, lương chức vụ. Prefix lệnh: `!`. Ví dụ tham số: `@user` là mention người dùng, `@Role` là mention role, `#channel` là mention kênh, `<key>` là mã do người dùng đặt.

## 1. Phân quyền

| Nhóm | Là ai | Làm được gì |
|---|---|---|
| Member | Mọi người trong server | Tra số dư, xem túi, redeem, tip, xem bảng xếp hạng, lãnh lương |
| Support | Role được thêm bằng `!supportrole add` | Mọi quyền Member + react emoji tặng credit + `!pay`, `!fine`, `!flee`, `!report` |
| Valid Role | Role được thêm bằng `!validrole add` | Mọi quyền Support + `!remove`, `!rw`, `!luong`, `!redeem cancel`. Không hiển thị trên `!top` / `!toptop` |
| Admin | Có quyền Administrator của Discord (hiện tại role Moderator đang có quyền Administrator nên cũng thuộc nhóm này) | Duyệt redeem, cấu hình bot, renew, clear role, tagrole |

- Chưa set `!validrole` thì các lệnh Valid Role bị chặn. Admin cần set trước: `!validrole add @Role`.
- Bot kiểm tra quyền Administrator của Discord, không kiểm tra tên role. Moderator dùng được toàn bộ lệnh Admin.
- Trong Discord: `!help` (member), `!help support`, `!help admin`, `!help <tên lệnh>`. `!help admin` và `!help support` chỉ hiện với người có quyền.

## 2. Credit và Item

| Key | Loại | Alias gõ lệnh | Giới hạn nhận qua react / tuần |
|---|---|---|---|
| coin | Credit | `coin`, `coins`, `c` | 30 |
| gem | Credit | `gem`, `gems`, `g` | 15 |
| mpking | Item (thẻ bài) | `mpking` | Không giới hạn |
| tapolice | Item (thẻ bài) | `tapolice` | Không giới hạn |
| fpqueen | Item (thẻ bài) | `fpqueen` | Không giới hạn |
| obprince | Item (thẻ bài) | `obprince` | Không giới hạn |

Credit hiển thị ở `!money`, `!top`. Item hiển thị ở `!bag`, `!toptop`.

## 3. Lệnh dành cho Member

### !money
Xem số dư credit của bạn hoặc người khác.
```
!money
!money @TA-Police
```

### !bag
Xem toàn bộ credit và item trong Túi Càn Khôn.
```
!bag
!bag @TA-Police
```

### !reward
Xem danh sách reward hiện có và giá đổi.
```
!reward
```

### !redeem
Mở bảng reward với các nút bấm. Chọn reward, chọn cách thanh toán (nếu có nhiều lựa chọn), bot tạo request trạng thái PENDING chờ admin duyệt. Tiền chỉ bị trừ khi admin approve.
```
!redeem
```
- Nên xem `!reward` trước để biết giá.
- Giá OR: chọn 1 trong các loại tiền. Giá AND: phải trả đủ tất cả.
- Reward có giá ưu đãi cho Server Tag 360: bật Server Tag trong Discord để được tính giá thấp hơn.
- Reward tài liệu (Google Drive): bot hỏi File ID và email, sau khi duyệt bot tự cấp quyền xem file cho email đó.
- Reward có thanh toán Zelle: xem `!zelle`.

### !zelle
Hiện mã QR Zelle để thanh toán USD trực tiếp. Sau khi chuyển tiền, bấm Xác nhận và nhập tên Zelle của bạn để admin đối chiếu. Tên này chỉ admin nhìn thấy.
```
!zelle
```

### !tip
Tặng credit hoặc item của bạn cho member khác. Số lượng phải là số nguyên dương, bạn phải đủ số dư, không thể tip cho chính mình.
```
!tip @TA-Police 3 coin
!tip @TA-Police 3 mpking
```

### !top và !toptop
`!top`: bảng xếp hạng credit. `!toptop`: bảng xếp hạng item. Valid Role không xuất hiện trong bảng.
```
!top
!toptop
```

### !lanhluong
Mở giao diện nút bấm để lãnh lương theo chức vụ.
- Chọn chức vụ (hoặc chọn nhóm trước nếu chức vụ nằm trong nhóm).
- Chọn kỳ lương: 1 buổi / 1 tuần / 1 tháng / 1 khóa (chỉ hiện kỳ đã được set giá).
- Yêu cầu ở trạng thái PENDING chờ admin duyệt.
```
!lanhluong
```

### !help
```
!help
!help redeem
!help support
!help admin
```

## 4. Nút bấm tương tác

Các nút bot tự gắn vào tin nhắn, không phải lệnh gõ. Mỗi nút ghi rõ nhóm được bấm (mặc định là Member).

### Nút Unsubscribe (Auto-renew role)
Với reward có bật gia hạn hàng tháng, bot đăng thông báo trong channel renew vào ngày 27 (9h sáng) và ngày 30 (3h sáng). Ngày 1 hàng tháng bot tự trừ tiền người đang giữ role. Nếu không muốn gia hạn, bấm Unsubscribe trong thông báo: tháng sau bạn bị gỡ role và không bị trừ tiền. Ai không đủ tiền sẽ bị gỡ role. Admin không bị trừ.

### Nút Calculate Position Size
Khi alerter đã được cấu hình đăng alert (ticker, entry, tp) trong channel, bot gắn nút Calculate Position Size. Bấm nút để tự tính số share nên mua theo vốn và mức rủi ro của bạn.

### Nút Approve / Reject (duyệt redeem) - Admin
Dưới mỗi thông báo request redeem (kể cả thanh toán bằng Zelle), bot gắn nút Approve và Reject. Admin bấm nút để duyệt hoặc từ chối ngay, không cần gõ `!approve` hay `!reject`. Chỉ người có quyền Administrator mới bấm được.

### Nút Xem tên Zelle - Admin
Khi member bấm Xác nhận và nhập tên Zelle (từ `!zelle` hoặc khi redeem trả bằng Zelle), thông báo gửi cho admin có nút Xem tên Zelle. Admin bấm nút thì tên hiện ra và chỉ riêng admin nhìn thấy. Dùng để đối chiếu với giao dịch Zelle trước khi duyệt.

## 5. Lệnh dành cho Support Role

Gồm mọi lệnh Member, cộng thêm:

### React Emoji
React emoji credit/item (🪙, 💎, các emoji thẻ bài) vào tin nhắn của member để tặng 1 credit/item cho tác giả tin nhắn.
- Mỗi tin nhắn chỉ được tặng tối đa 1 lần cho mỗi loại tiền.
- Người nhận bị giới hạn theo tuần (coin 30, gem 15). Quá giới hạn bot báo "Weekly Limit Reached".
- Không tặng cho bot.
- Bỏ react không tự trừ điểm. Nếu react nhầm, dùng `!remove` (Valid Role).

### !pay
Phát credit/item cho 1 member hoặc cho cả 1 role.
```
!pay @TA-Police 5 coin
!pay @TA-Police 5 mpking
!pay @MP 1 gem
```

### !fine
Phạt (trừ) credit của member. Chỉ dùng cho credit (coin, gem). Nếu số phạt lớn hơn số dư, bot chỉ trừ tối đa số đang có.
```
!fine @TA-Police 5 coin
```

### !flee
Phạt (trừ) thẻ bài của member. Chỉ dùng cho item.
```
!flee @TA-Police 5 mpking
```

### !report
Thống kê credit và item lưu thông trong tuần.

| Chỉ số | Ý nghĩa |
|---|---|
| Minted | Phát hành: react emoji, `!pay` |
| Burned | Tiêu thụ: redeem thành công, `!remove`, `!fine`, `!flee` |
| Total (Net) | Tổng đang lưu thông trong server |
| Active Holders | Số member đang giữ credit/item |
```
!report
```

## 6. Lệnh dành cho Valid Role

Gồm mọi lệnh Support, cộng thêm:

### !remove
Thu hồi credit/item. Dùng khi react nhầm vì bỏ react không tự trừ điểm.
```
!remove @TA-Police 2 coin
!remove @TA-Police 2 mpking
```

### !rw (quản lý reward)
Label và mô tả phải đặt trong dấu ngoặc kép.

Thêm reward:
```
!rw add <key> "<label>" ["<mô tả>"] OR|AND <currency:amount> ...
!rw add chenthanh "👑 Chén thánh" "Bí kíp võ công" OR coin:200 gem:50 mpking:100
```
- `key`: mã reward, viết liền không dấu (workshop, livetrade...).
- `OR`: trả 1 trong các loại. `AND`: trả đủ tất cả.
- Giá: `coin:10 gem:4 mpking:5`.

Chỉnh sửa:
```
!rw set <key> label "<tên mới>"
!rw set <key> desc "<mô tả mới>"
!rw set <key> rule OR|AND
!rw set <key> cost coin:500 gem:500
```

Giá ưu đãi cho Server Tag 360:
```
!rw set <key> tagcost coin:10     (bật)
!rw set <key> tagcost off         (tắt)
```

Zelle (thanh toán USD):
```
!rw set <key> usd 25     (bật, giá 25 USD)
!rw set <key> usd 0      (tắt)
```

Tự cấp role khi approve (nếu bot không gán được role do thiếu quyền hoặc role cao hơn bot, redeem vẫn được approve, bot chỉ báo gán tay):
```
!rw set <key> role @Role     (hoặc dùng role ID)
!rw set <key> role off
```

Auto-renew hàng tháng (phải bật `role` trước):
```
!rw set <key> monthly on
!rw set <key> monthly off
```

Ẩn, khôi phục, liệt kê:
```
!rw del <key>        (ẩn khỏi danh sách)
!rw restore <key>    (khôi phục)
!rw list             (xem tất cả, kể cả đang ẩn)
```

### !luong (quản lý lương chức vụ)
Quản lý chức vụ và mức lương hiển thị trong `!lanhluong`. Kỳ lương: `buoi` (buổi), `tuan` (tuần), `thang` (tháng), `khoa` (khóa).
```
!luong list
!luong add <key> "<label>" [group "<tên nhóm>"]
!luong set <key> <buoi|tuan|thang|khoa> <currency:amount>
!luong set <key> <kỳ> clear
!luong group <key> "<nhóm mới>"
!luong group <key> none
!luong del <key>
!luong restore <key>
```
Ví dụ:
```
!luong add loptruong "Lớp trưởng" group "Ban cán sự"
!luong set loptruong buoi coin:30
!luong set loptruong khoa coin:100 mpking:5
```

### !redeem cancel
Huỷ request đang PENDING của member (chưa bị trừ tiền).
```
!redeem cancel @user             (huỷ tất cả pending của user)
!redeem cancel @user workshop    (chỉ huỷ reward workshop)
```

## 7. Lệnh dành cho Admin

Yêu cầu quyền Administrator của Discord.

### !approve
Duyệt request redeem đang PENDING. Bot trừ tiền member, tự cấp role (nếu reward có `role`) hoặc cấp quyền Google Drive (reward tài liệu).
```
!approve @user workshop
```

### !reject
Từ chối request redeem đang PENDING.
```
!reject @user workshop
```

### !validrole
Quản lý các role có quyền Valid Role.
```
!validrole list
!validrole add @Role
!validrole remove @Role
```

### !supportrole
Quản lý các role Support (react, pay, fine, flee, report).
```
!supportrole list
!supportrole add @Role
!supportrole remove @Role
```

### !setcreditchannel
Đặt channel nhận thông báo giao dịch (transaction log). Chỉ 1 channel, set lại sẽ lấy channel mới nhất.
```
!setcreditchannel #credit-log
```

### !setrenewchannel
Đặt channel đăng thông báo auto-renew ngày 27 (9h sáng) và ngày 30 (3h sáng) hàng tháng (kèm nút Unsubscribe), và channel admin nhận báo cáo kết quả renew ngày 1. Không thấy báo cáo ngày 1 nghĩa là bot không chạy, admin tự chạy `!renew <key>`.
```
!setrenewchannel #renew-reminder
!setrenewchannel log #admin-channel
```

### !renew
Trừ tiền gia hạn role của reward có bật `monthly`. Bot tự chạy lúc 03:00 ngày 1 hàng tháng, lệnh này để chạy tay.
```
!renew <key>                       (hoặc !renew @Role)
!renew <key> force                 (chạy lại dù tháng này đã renew, trừ tiền lần nữa)
!renew exempt add <key> @u1 @u2    (member ngoại lệ: giữ role, không bị trừ)
!renew exempt remove <key> @user
!renew exempt list <key>
```

### !tagrole
Gán/gỡ role hàng loạt theo việc member có bật Server Tag 360 hay không.
```
!tagrole add @Role       (gán cho người đang bật tag)
!tagrole remove @Role    (gỡ khỏi người đã tắt tag)
!tagrole sync @Role      (đồng bộ hai chiều)
!tagrole setrole @Role   (bot tự sync mỗi ngày lúc 00:00)
!tagrole status          (xem role auto-sync hiện tại)
```

### !clear
Gỡ 1 role khỏi toàn bộ member đang có role đó. Không áp dụng cho role Administrator hay role nằm trong Valid Role. Chỉ undo được đúng 1 bước gần nhất cho mỗi role; gỡ lần nữa trước khi undo thì bước cũ bị ghi đè.
```
!clear @Role
!clear undo @Role
```

### !alert
Cấu hình cặp (channel, alerter) mà bot theo dõi. Khi alerter đăng alert trong channel đã set, bot tự parse và gắn nút Calculate Position Size.
```
!alert list
!alert set #room-alert @Tulé
!alert remove #room-alert @Tulé
```

### !checkbot
Kiểm tra bot có đủ quyền trong channel (xem kênh, gửi tin, embed, gửi file, đọc lịch sử, thả reaction). Dùng khi bot im lặng hoặc không phản hồi.
```
!checkbot
!checkbot #channel
```

## 8. Quy trình thường gặp

### Redeem đổi thưởng
1. Member xem `!reward`, gõ `!redeem`, chọn reward và cách thanh toán.
2. Bot tạo request PENDING và báo admin.
3. Admin gõ `!approve @user <key>` (hoặc `!reject`). Valid Role có thể `!redeem cancel`.
4. Khi approve: bot trừ tiền, tự cấp role / quyền Drive nếu có.

### Auto-renew role hàng tháng
1. Tạo reward có role và bật monthly: `!rw set <key> role @Role` rồi `!rw set <key> monthly on`.
2. Set channel: `!setrenewchannel #renew-reminder` và `!setrenewchannel log #admin-channel`.
3. Ngày 27 (9h sáng) và ngày 30 (3h sáng): bot đăng thông báo kèm nút Unsubscribe.
4. 03:00 ngày 1: bot trừ tiền người đang giữ role.
   - Có Server Tag: trả `tagcost`. Không có tag: trả `cost`.
   - Không đủ tiền hoặc đã Unsubscribe: bị gỡ role.
   - Admin, bot và member trong danh sách `exempt`: không bị trừ, giữ role.
5. Admin xem báo cáo ở channel log. Nếu không có, chạy tay `!renew <key>`.

### Thiết lập bot lần đầu
1. `!validrole add @Role` và (tuỳ chọn) `!supportrole add @Role`
2. `!setcreditchannel #credit-log`
3. `!rw add ...` để tạo reward, `!luong add ...` để tạo chức vụ
4. `!checkbot` để chắc bot đủ quyền

## 9. Hỏi nhanh

- **Bot báo "không có quyền"?** Nhờ admin kiểm tra role của bạn bằng `!validrole list` / `!supportrole list`.
- **React nhầm thì sao?** Bỏ react không trừ điểm. Nhờ Valid Role dùng `!remove`.
- **Đã redeem nhưng chưa thấy trừ tiền?** Tiền chỉ trừ khi admin approve.
- **Bot không phản hồi?** Admin chạy `!checkbot` trong channel đó.
- **Tại sao tôi không thấy trên `!top`?** Valid Role được ẩn khỏi bảng xếp hạng.
