Manage Product › Add Product
🎬 Simulate: Recoverable · AF-5B Reset

Add Product

Basic info
₭
Link selection

Select the items this product covers — at least 1 item must be selected in total (from Courses + Special Programs + Tags).

Select central courses…
One or more selected central courses are no longer active in the LMS.
Select institute courses…
Institute-only course offerings · Lazy-loaded from LMS Core API · Active only
Select special programs…
Lazy-loaded from LMS Core API · Active special programs only
Select tags…
Lazy-loaded from LMS Core API · Grouped by tag category · Select group header to select all tags in group
📝 Spec notes — UC-BIL.07 / SCR-BIL.09 (fields, actions, requirements)
Identity
  • Screen: SCR-BIL.09 — Product Form
  • Use case: UC-BIL.07 — Manage Product
  • Primary actor: Sale Admin (ACT-12)
Brief description

Form for creating or editing a Product in the Billing catalog — mode determined by URL parameter (create | edit). Three core fields (name, type, price) plus four multi-select pickers (Central Courses, Institute Courses, Special Programs, Tags) that lazy-load from LMS Core API; at least 1 item must be selected in total. Tags picker displays tags grouped by TagGroup with group-level select/deselect and autocomplete. In edit mode a Status field (active/inactive) is also shown. When editing a Product that has active subscriptions, a blocking dialog requests confirmation before save. Validation errors shown inline per field.

Fields
  • product_name "Product Name" — text · Product.name · required · min 1 / max 255 chars · fallback ""
  • product_type "Type" — enum (lifetime / period) · Product.type · required · fallback ""
  • price "Price (LAK)" — number · Product.price · required · min 1 · fallback ""
  • product_status "Status" — enum (active / inactive) · Product.status · required when mode == edit · visible when mode == edit · fallback: active
  • linked_central_courses "Central Courses" — multi-select · Product.linked_central_courses · lazy-loaded from LMS Core API · shared-visibility active InstituteCourses only · fallback []
  • linked_institute_courses "Institute Courses" — multi-select · Product.linked_institute_courses · lazy-loaded from LMS Core API · institute-only active InstituteCourses only · fallback []
  • linked_special_programs "Covered Special Programs" — multi-select · Product.linked_special_programs · lazy-loaded from LMS Core API · active special programs only · fallback [] (SpecialProgram entity pending /analyze-entities)
  • linked_tags "Covered Tags" — multi-select · Product.linked_tags · lazy-loaded from LMS Core API · grouped by TagGroup · fallback [] (TagGroup entity pending /analyze-entities)
  • lms_load_status "LMS load status" — enum (loading / loaded) · computed on screen load · read-only · drives the loading indicator while pickers lazy-load
  • active_subs_warning_message "Edit warning message" — computed text · visible when mode == edit && save_triggered && active_subs_count > 0 · read-only · "This product has N active Subscriptions. Changes will not affect existing subscriptions."
Actions
  • save "Save" — enabled when required_fields_valid && lms_load_status == loaded && (linked_courses + linked_special_programs + linked_tags).length > 0 · triggers UC-BIL.07-M-4 (create) or UC-BIL.07-A-2A-3 (edit)
  • confirm_edit "Confirm" — always enabled (in edit warning dialog) · triggers UC-BIL.07-A-2A-5 · visible only when active_subs_warning_message dialog is shown
  • cancel "Cancel" — always enabled · returns to SCR-BIL.08 (Product List)
Additional requirements
  1. Validation errors shown inline beneath each invalid field immediately — do not use page-level banner for field errors. (AF-5A) [refs: NFR-04]
  2. LMS pickers show a loading indicator during lazy-load. [refs: NFR-02]
  3. Edit warning dialog (active_subs_warning_message) is a blocking modal — focus trapped inside; backdrop click does not dismiss; exit via "Confirm" or "Cancel" only. [refs: NFR-09]
  4. AF-5B (LMS items invalid): highlight each invalid item inside its picker with a per-item error message — do not use separate error list outside the picker. [refs: —]
  5. Covered Tags picker displays tags grouped by TagGroup; selecting a group header auto-selects all tags in that group; deselecting group header deselects all; autocomplete searches both group name and tag name. [refs: —]
⚠ UC open issues
  • Product schema (multi-link lists) conflicts with entities.puml and UC-BIL.01 data_touched (old link_type/link_ref single-link) — awaiting /analyze-entities reconcile.
  • SpecialProgram + Tag entities not yet registered in LMS Core entities.puml — /analyze-entities must add them.
  • Price/type change on a Product with active Subscriptions — current design: "no impact (snapshot pricing stored in Transaction)" — awaiting DTVE confirmation.