Subscription — Góc nhìn end-user
Hai vai chính: admin/staff (thiết lập & quản lý) và khách hàng (đăng ký & đặt chỗ). Dưới đây là hành trình của từng vai.
A. Admin/Staff thiết lập một gói
1. Tạo Subscription
Trang
Admin Portal → Setup → Subscription(/product-service/subscription).
- Bảng chia Current (chưa archive) và Archived.
- Tạo gói mới: chọn Site (một site), nhập Subscription Name, chọn loại (Billing Only hay mặc định BookingAndBilling).
- Cấu hình: giá (Price), ảnh, Booking Cut-Off (số ngày), rich text (Booking Info, Instructions, Discount Info, Payment Instructions, Important Notice), và quyền chọn period: Booking Start/End Selection (
Staff OnlyhoặcStaff & Customer).
2. Link với Term (kỳ học)
- Mở popup linked-term confirmation: chọn từng SubscriptionProduct (không có "Select All").
- Gói chưa có product → popup báo "hãy thêm sessions ở mục Program trước".
- API link-term tự validate tương thích product với term; thiếu → hiện danh sách product thiếu.
3. Quản lý qua Subscription Manager
Lọc theo Site/Subscription/Term/Account/Attendee/Status; đổi filter không tự reload — bấm Apply mới load (load đầu trang tự chạy; mutation thành công cũng refresh).
- Mỗi enrollment row: mở rộng để xem add-ons và discounts đang áp.
- Hành động: Manage Add-ons, Manage Discounts (chỉ theo các kỳ đã book của enrollment).
- Với Subscription Booking đã có
TermBooking, action Manage Enrichments mở danh sách occurrence theo ngày; surface này tách khỏi Manage Add-ons. - Manage Enrichments chỉ cho Enterprise Admin, BU Admin hoặc Staff có scope phù hợp; customer scope không cấp quyền admin. Dòng đã qua ngày, invoiced, credited, attended hoặc bị Booking lock là read-only.
- View (row action) → drawer Booked Periods read-only: liệt kê Enrollment Schedules đã book
- link View Calendar (chỉ kỳ active, không cancelled). Drawer không có sửa/hủy/thanh toán.
- Enrollment id hiển thị
SBK-{id}(thaySUB-); cột ngày đặt tên Booking Range. - Terminate Enrollment: ngày kết thúc chỉ từ
BookingEndcủa kỳ đã book; backend reject nếu không khớp. - Confirm/Terminate/Cancel đều có confirmation kèm Mute Notifications (mặc định tắt) — bỏ qua email đáng lẽ gửi, lifecycle vẫn chạy.
- Notes hiển thị 2 khối read-only: Admin Notes (admin-only) và Notes (customer-facing).
Ví dụ thực tế: Admin terminate gói của An. → Tránh terminate sai mốc. → Mở View → drawer Booked Periods (SBK-101047); dropdown chỉ liệt kê BookingEnd của kỳ đã book, chọn ngày khác → backend từ chối.
Ví dụ thực tế: Staff thấy một occurrence Enrichment tương lai chưa invoice. → Mở Manage Enrichments, chọn ngày cần thêm/bỏ. → Hệ thống cập nhật đúng Booking line và giữ nguyên các ngày khác; occurrence đã invoice bị khóa.
4. Billing Details: thao tác trên hóa đơn
Trang Subscription Billing Details hiển thị theo hóa đơn (một dòng/invoice), không hiện log nội bộ.
Ba hành động chính, đều tác động lên invoice:
| Hành động | Kết quả |
|---|---|
| Schedule | Tạo InvoiceScheduler cho mỗi invoice; ScheduledOn = Invoice.Date (UTC). |
| Approve | Đổi invoice sang Approved + tạo scheduler ngay (ScheduledOn = UtcNow). |
| Skip | Hủy scheduler đang chạy + reset invoice về Initialised (0). |
- Drill-down: chỉ vào từ Billing Manager qua nút View (có sẵn context site/subscription/ term); mở thẳng thiếu context → redirect về trang an toàn.
- Khi mở: nếu có
EnrollmentBillingScheduleactive của đúng schedule đang xem chưa invoice → modal Generate Billing Required (không đóng được), bắt buộc Generate Billing trước khi thao tác. Period không thuộc schedule hiện tại không được tính vào gate.
Ví dụ thực tế: Admin bấm View schedule còn thiếu hóa đơn. → Sinh đủ hóa đơn trước khi schedule/approve. → Modal "Generate Billing Required" (không đóng được); bấm Generate Billing rồi mới thao tác.
5. Subscription Billing Manager
Sidebar finance Subscription Billing mở trang Subscription Billing Manager; trang Billing Details chỉ mở từ nút View của một row.
- Filter Site + Subscription (bắt buộc, single-select) + Term (tùy chọn; trống = tất cả term của subscription); bấm Apply để load bảng.
- Options của filter Subscription lấy từ
/Subscription/WithTerms(không dùng/Subscription/List; không đọcPeriods). - Mỗi row = một
SubscriptionTermBillingSchedule(term archivedStatusId=600vẫn hiện): Term, Period (PeriodStart→PeriodEnd), Invoice Date, Due Date, Stats, Action. - Stats
generated/expected(đã sinh / kỳ vọng theo enrollment active-approved); thiếu → icon info "There are x more invoices to be generated, please click "View" button to proceed." - View → redirect sang Billing Details với context site/subscription/term.
- Non-SuperAdmin (
BusinessUnit.TypeId ≠ 99): manager read-only — approve/skip/generate chỉ ở detail page; bảng không có column filters. - SuperAdmin (
TypeId = 99): row thêm link Calculate → drawer summary (GET /api/subscription-billing/ScheduleSummary/{id}) + nút Generate Subscription Booking (POST /api/ConsumerEnrollment/BillingEnrollment/{scheduleId}); đóng drawer → refresh grid.
Ví dụ thực tế: Finance xem tiến độ sinh hóa đơn học kỳ. → Tổng quan theo schedule, không dò từng invoice. → Chọn Site + Subscription, để Term trống, bấm Apply; row generated < expected → icon info → bấm View xử lý ở detail.
6. Setup đã publish và các thao tác mở rộng
- Khi Subscription đã publish/bookable, các control Price, Billing Settings, Linked Term, Billing Schedule và Add-on bị khóa ở Setup; API cũng reject request có field locked. Muốn đổi phải Unpublish trước. Name, description, image, rich text, price info, cut-off và quyền chọn start/end vẫn sửa được; Discount không nằm trong nhóm bị khóa.
- Flyer chỉ upload ở màn hình edit: một PDF tối đa 5 trang/10 MB hoặc tối đa 5 ảnh JPEG/PNG, ảnh tối đa 2 MB. Admin có thể reorder/remove; Step 1 chỉ hiển thị manifest hợp lệ theo đúng thứ tự.
- Duplicate chỉ copy cấu hình đã chọn sang Site khác trong cùng BU và tạo gói Unpublished/ Unbookable; không copy enrollment, booking, invoice hay payment. Rollover không tạo gói mới, chỉ chuyển enrollment đủ điều kiện sang linked Term.
Billing Generation = Autotạo job tại ngày invoice chưa sinh sớm nhất và tự lập lịch kỳ kế tiếp; chuyển về Manual hoặc unpublish sẽ hủy job pending.Manuallà mặc định.
Ví dụ thực tế: Gói đã bán cho Term 2 cần đổi giá. → Không làm thay đổi cam kết đã book. → Admin unpublish, sửa Price, rồi publish lại; nếu chỉ đổi mô tả thì sửa trực tiếp không cần unpublish.
B. Khách hàng đăng ký & đặt chỗ
1. Duyệt & chọn gói (Course List)
- Card hiển thị: tiêu đề, giá (chỉ khi có), lịch theo thứ trong tuần (Mon–Sun), mô tả, ảnh, thông tin site (popup bản đồ).
2. Subscription Booking (Step 1 → Step 2)
Step 1 — chọn gói & range (public, không cần login để xem):
- Hiển thị: title cấu hình, site (icon bản đồ), giá/frequency, weekday indicators, requirements, ảnh/share; không khung Basic Info.
- Program Details: mỗi row = Program + session, time range, weekly pattern; header có View Calendar (derive từ Term Planner × TermProducts của term, loại closure days).
- Chọn range theo quyền Booking Start/End Selection của gói:
Staff Only→ khách không chọn: mọi schedule hiện đã chọn, checkbox disabled.Staff & Customer→ khách chọn; range liên tục (start→hết / đầu→end / chọn start rồi chọn end trong modal); hiển thịSelected {x}/{total}; > 12 rows → View More Schedules.
- Cut-off: schedule không chọn được nếu
BookingStart< hiện tại +CutOffMinute(anchor làBookingStart, không phảiPeriodStart). - Bottom toolbar:
Total Fee per Attendee+ Next (enabled khi range hợp lệ). Anonymous bấm Next → popup login (giữ range) → popup T&C (nếu có cấu hình). - Preview mode
?isPreview=true: hiển thị đầy đủ nhưng read-only, không submit/book.
Admin Mode Step 1 — Booking Rule Options (chỉ staff, hiện trước Program Details):
- Panel Booking Cut-off (khi
CutOffMinute > 0) + toggle từng requirement (Age/School Year/ Level/Height/Weight/Swimming — khi Product có bound và<Reference>_Enabled = true). - Toggle transient (không persist), mặc định ON; OFF → bỏ qua dimension đó khi chọn/submit.
- Khách không thấy panel và không bypass được (client bypass flag bị bỏ qua).
Yêu cầu từ Product: attendee phải đạt yêu cầu Product của term đã chọn (age/school year/level/ height/weight/swimming); không đạt → chặn chọn schedule (Step 1) + reject submit (Step 2, backend revalidate). Chi tiết: Khái niệm.
Step 2 — Booking Details (cần đăng nhập):
- Booking Summary: site, subscription name, program/session + weekly pattern; nút View Calendar.
- Booking Range: read-only (phải quay lại Step 1); mỗi row hiện Booking/Add-on/Enrichment/Total, tổng
Total Count,View Calendartừng schedule. - Account Holder: khách → preload account của mình; admin → phải Select an Account hoặc chọn attendee trước (không preload từ route context).
- Attendees: theo pattern Course Booking; attendee đã có enrollment cho gói này → link View Existing Booking → drawer Booked Periods read-only.
- Additional Info: comments (khách); Admin Booking Notes (chỉ admin).
- Add-ons: group
Normal Add-ons/Bus Service, unit price theo frequency (/ month,/ week,/ term); chọn → cập nhật toolbar + Booking Range Add-on amount. - Enrichment: bảng
Enrichments & Add-ons, mỗi dòng có checkbox Mon–Fri; không cóALL, Saturday hoặc Sunday. Chỉ hiện option đã qua Setup eligibility; zero-rate vẫn được chọn. Preview server trả occurrence count/amount theo từng schedule và toàn booking. - Khi preview đang loading, lỗi hoặc stale → không được tiếp tục submit; client không tự quyết định rate, count hay amount. Feature flag/dependency không sẵn sàng → ẩn section hoặc fail closed.
- Bottom toolbar:
Total Fee per Attendee(booking + add-on + enrichment); admin có Submit hoặc Submit & Confirm (khách chỉ Submit); cả hai có Mute Notifications (mặc định tắt).
3. Đặt chỗ được kiểm tra trùng lịch
Khi submit, hệ thống kiểm tra trùng lịch với các enrollment/booking đang có của attendee. Nếu trùng → cả request fail (không tạo state một phần).
4. Portal: My Subscriptions
Khách xem các subscription của mình ở Customer Portal → My Subscriptions.
5. Thông báo vòng đời booking
| Sự kiện | Template gửi |
|---|---|
| Submitted (còn pending) | New Subscription Booking (Client) → khách + New Subscription Booking (Staff) → staff/admin |
| Confirmed | Subscription Booking Confirmed (Client) → khách |
| Cancelled | Subscription Booking Cancelled (Client) → khách (kèm phone/email site) |
- Submit & Confirm → không gửi submitted/pending; chỉ gửi confirmed.
- Admin Mute Notifications (Submit/Submit & Confirm/Confirm/Terminate/Cancel) → bỏ qua email đáng lẽ gửi; lifecycle vẫn hoàn tất.
- Gửi sau khi trạng thái đã persist; side effect của notification không mutate lifecycle.
- Placeholders:
,,,,,,, v.v.
Ví dụ thực tế: Phụ huynh book gói từ portal. → Phụ huynh biết booking đang chờ xác nhận, staff biết có booking mới. → Khách nhận New Subscription Booking (Client), staff nhận (Staff); admin dùng Submit & Confirm → chỉ gửi Subscription Booking Confirmed (Client).
6. My Bookings: Extend và Rollover
- Khách có thể Extend ở đầu/cuối enrollment nếu setting của Subscription cho phép; chỉ chọn schedule liền kề, chưa qua ngày hiện tại, cùng Term và gửi ở trạng thái Pending. Khách không có quyền
Confirm. - Admin có thêm
Extendtrong Subscription Manager vớiSubmithoặcSubmit & Confirm. Phần mở rộng được lưu thành booking period riêng; booking/invoice cũ không bị tính lại. Nếu chạm schedule cuối của term cuối, flow có thể ghi lựa chọn rolloverAuto/None(admin có thêm Customer Confirmation).
Ví dụ thực tế: Bé An đã book đến tuần 4 và phụ huynh muốn học thêm tuần 5. → Giữ nguyên invoice tuần 1–4. → Bấm
Extend, chọn schedule liền kề tuần 5; hệ thống tạo period mới, không backdate và chỉ sinh billing cho phần mới.
Tóm lại
| Vai | Làm gì |
|---|---|
| Admin | Tạo/cấu hình gói, link term, quản lý enrollment (View/Booked Periods, terminate), theo dõi Billing Manager, thao tác invoice. |
| Staff | Manage add-ons/discounts theo kỳ đã book; Submit / Submit & Confirm với tùy chọn Mute Notifications. |
| Khách hàng | Duyệt gói, chọn range theo quyền, điền Step 2, submit booking (được check trùng), nhận thông báo vòng đời. |
Tiếp theo: Khái niệm cốt lõi.