Work in Progress
Feature details in this document may change during investigation, discussion, design, and implementation phases.
Product / Sản phẩm
Product catalog management for your business.
Overview
| Attribute | Value |
|---|---|
| Module ID | CORE-06 |
| Phase | Phase 1 (Basic), Phase 2 (Variants/Fare), Phase 3 (Campaign/BOM) |
| Priority | HIGH |
| Dependencies | Merchant |
The Product module manages the complete product catalog. A Product defines the item that can be sold. Each Product has ProductVariant (SaleItem) which is what we actually sell. Each ProductVariant has Fare for pricing. Campaigns allow seasonal/promotional pricing with Sale Quotation to limit quantities.
Entity Definitions
| Entity | Vietnamese | Description |
|---|---|---|
| Product | Sản phẩm | Base item definition (not including quotation) |
| ProductVariant | Biến thể sản phẩm | Sellable unit (SaleItem) - what we actually sell |
| Fare | Giá | Pricing for each ProductVariant |
| Campaign | Chiến dịch | Promotional/seasonal configuration |
| Sale Quotation | Hạn mức bán | Quantity limit for campaign pricing |
| Category | Danh mục | Product organization |
┌─────────────────────────────────────────────────────────────────┐
│ PRODUCT STRUCTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ CATEGORY │ │
│ │ (e.g., Beverages) │ │
│ └─────────────────────┬───────────────────────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ PRODUCT │ │ PRODUCT │ │ PRODUCT │ │
│ │ (Coffee) │ │ (Tea) │ │ (Juice) │ │
│ └─────┬─────┘ └───────────┘ └───────────┘ │
│ │ │
│ ┌─────┴─────────────────┐ PRODUCT VARIANT (SaleItem) │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ VARIANT │ │ VARIANT │ │
│ │ Hot Coffee │ │ Iced Coffee │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ FARE (Pricing) │
│ ┌────┴────┐ ┌────┴────┐ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ Fare │ │ Fare │ │ Fare │ │ Fare │ │
│ │Base │ │Promo │ │Base │ │Promo │ │
│ │30,000│ │25,000│ │35,000│ │30,000│ │
│ └──────┘ └──────┘ └──────┘ └──────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ CAMPAIGN STRUCTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ CAMPAIGN │ │
│ │ (e.g., Summer Sale 2025) │ │
│ │ Start: 01/06 | End: 31/08 │ │
│ └─────────────────────┬───────────────────────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ SALE │ │ SALE │ │ SALE │ │
│ │ QUOTATION │ │ QUOTATION │ │ QUOTATION │ │
│ │ │ │ │ │ │ │
│ │ Variant A │ │ Variant B │ │ Variant C │ │
│ │ Qty: 100 │ │ Qty: 50 │ │ Qty: 200 │ │
│ │ Price: 25k│ │ Price: 30k│ │ Price: 20k│ │
│ └───────────┘ └───────────┘ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘User Stories
Phase 1 - Product & Category
| ID | As a... | I want to... | So that... |
|---|---|---|---|
| US-01 | Business owner | Create product categories | Products are organized |
| US-02 | Business owner | Add products | I define items that can be sold |
| US-03 | Business owner | Set tax rates per product | Invoices have correct VAT |
| US-04 | Business owner | Add product images | Customers can identify items |
| US-05 | Business owner | Set product barcodes | I can scan products at checkout |
| US-06 | Cashier | Search products by name | I find products quickly |
| US-07 | Cashier | Scan product barcode | Products add to cart instantly |
Phase 2 - ProductVariant & Fare
| ID | As a... | I want to... | So that... |
|---|---|---|---|
| US-08 | Business owner | Create product variants (SaleItems) | I sell size/color/flavor options |
| US-09 | Business owner | Set fare per variant | Different variants have different prices |
| US-10 | Business owner | Create multiple fares per variant | I have base price and promotional prices |
| US-11 | Business owner | Track inventory per variant | Stock is accurate per sellable item |
| US-12 | Business owner | Import products from CSV | I can bulk upload catalog |
| US-13 | Business owner | Set variants available per store | Different stores sell different items |
Phase 3 - Campaign & Sale Quotation
| ID | As a... | I want to... | So that... |
|---|---|---|---|
| US-14 | Business owner | Create campaigns | I run seasonal/promotional sales |
| US-15 | Business owner | Set campaign date range | Promotions are time-limited |
| US-16 | Business owner | Configure sale quotation | I limit how many items can be sold at promo price |
| US-17 | Business owner | Track quotation usage | I know remaining promotional inventory |
| US-18 | Business owner | Auto-switch to base fare | System uses base price when quota exhausted |
Phase 3 - Manufacturing & BOM
| ID | As a... | I want to... | So that... |
|---|---|---|---|
| US-19 | Business owner | Create combo products | I sell bundles at special prices |
| US-20 | Business owner | Define recipes (BOM) | Ingredients are auto-deducted |
| US-21 | Business owner | Set unit conversions | I buy in bulk, sell in units |
| US-22 | Business owner | Track production batches | I know which batch was sold |
Feature Matrix
Product & Category Features
| Feature | P1 | P2 | P3 | Description |
|---|---|---|---|---|
| Product CRUD | ✓ | Create, read, update, delete products | ||
| Categories | ✓ | Organize products in categories | ||
| Tax rates | ✓ | Assign VAT rate per product | ||
| Product images | ✓ | Upload product photos | ||
| Barcode/SKU | ✓ | Product identifiers | ||
| Units of measure | ✓ | Selling unit (piece, kg, etc.) | ||
| Bulk import | ✓ | CSV/Excel import |
ProductVariant (SaleItem) Features
| Feature | P1 | P2 | P3 | Description |
|---|---|---|---|---|
| Default variant | ✓ | Every product has at least one variant | ||
| Multiple variants | ✓ | Size, color, flavor options | ||
| Variant SKU | ✓ | Unique SKU per variant | ||
| Variant barcode | ✓ | Unique barcode per variant | ||
| Store availability | ✓ | Variants available per store | ||
| Inventory per variant | ✓ | Stock tracked per variant |
Fare (Pricing) Features
| Feature | P1 | P2 | P3 | Description |
|---|---|---|---|---|
| Base fare | ✓ | Default price per variant | ||
| Multiple fares | ✓ | Multiple price tiers per variant | ||
| Fare validity | ✓ | Date range for fare applicability | ||
| Fare priority | ✓ | Which fare applies when multiple valid |
Campaign & Sale Quotation Features
| Feature | P1 | P2 | P3 | Description |
|---|---|---|---|---|
| Campaign creation | ✓ | Create promotional campaigns | ||
| Campaign date range | ✓ | Start/end dates for campaign | ||
| Sale quotation | ✓ | Quantity limits at promotional price | ||
| Quotation tracking | ✓ | Track remaining quota | ||
| Auto-fallback | ✓ | Switch to base fare when quota exhausted | ||
| Campaign reporting | ✓ | Campaign performance analytics |
Manufacturing & BOM Features
| Feature | P1 | P2 | P3 | Description |
|---|---|---|---|---|
| Composite products | ✓ | Bundle products together | ||
| Bill of Materials | ✓ | Recipe/ingredient tracking | ||
| Unit conversions | ✓ | Box → Units conversion | ||
| Batch/lot tracking | ✓ | Production batch management |
Product Types
┌─────────────────────────────────────────────────────────────────┐
│ PRODUCT TYPES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ TYPE USE CASE EXAMPLE │
│ ───────────────────────────────────────────────────────────── │
│ │ │
│ ├── STANDARD Regular items T-shirt, Book │
│ │ │
│ ├── SERVICE Non-inventory items Haircut, Repair │
│ │ │
│ ├── COMPOSITE Bundle of products Combo meal │
│ │ │
│ └── RAW_MATERIAL Manufacturing input Flour, Sugar │
│ │
└─────────────────────────────────────────────────────────────────┘Fare Types
┌─────────────────────────────────────────────────────────────────┐
│ FARE TYPES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ TYPE USE CASE PRIORITY │
│ ───────────────────────────────────────────────────────────── │
│ │ │
│ ├── BASE Default price Lowest (1) │
│ │ Always available │
│ │ │
│ ├── PROMOTIONAL Time-limited discount Medium (2) │
│ │ Date range based │
│ │ │
│ ├── CAMPAIGN Campaign-specific Highest (3) │
│ │ Quota-limited │
│ │ │
│ └── MEMBER Customer tier price Custom │
│ Loyalty-based │
│ │
│ Resolution: Higher priority wins when multiple fares valid │
│ │
└─────────────────────────────────────────────────────────────────┘Campaign & Sale Quotation
┌─────────────────────────────────────────────────────────────────┐
│ CAMPAIGN STRUCTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ CAMPAIGN │
│ ├── Name: Summer Sale 2025 │
│ ├── Start Date: 2025-06-01 │
│ ├── End Date: 2025-08-31 │
│ ├── Status: ACTIVE / SCHEDULED / ENDED │
│ │ │
│ └── SALE QUOTATIONS │
│ │ │
│ ├── ProductVariant: Iced Coffee (Large) │
│ │ ├── Campaign Price: 25,000 VND │
│ │ ├── Quota: 100 units │
│ │ ├── Sold: 45 units │
│ │ └── Remaining: 55 units │
│ │ │
│ └── ProductVariant: Green Tea (Medium) │
│ ├── Campaign Price: 20,000 VND │
│ ├── Quota: 50 units │
│ ├── Sold: 50 units │
│ └── Remaining: 0 (EXHAUSTED → use base fare) │
│ │
└─────────────────────────────────────────────────────────────────┘Sale Quotation Behavior
| Scenario | Behavior |
|---|---|
| Quota available | Use campaign fare |
| Quota exhausted | Fallback to base fare |
| Campaign not started | Use base fare |
| Campaign ended | Use base fare |
| Multiple campaigns | Use highest priority campaign |
Key Flows
Product Creation Flow
ProductVariant Creation Flow
Fare Configuration Flow
Campaign & Sale Quotation Flow
Fare Resolution Flow (at Sale)
Product Search Flow
Category Management Flow
BOM/Recipe Creation Flow (Phase 3)
Business Rules
Product Rules
| Rule ID | Rule | Description |
|---|---|---|
| BR-PRD-01 | Name required | Product name is mandatory |
| BR-PRD-02 | Category required | Every product must belong to a category |
| BR-PRD-03 | Tax rate valid | Tax rate must be valid Vietnam VAT (0, 5, 8, 10%) |
| BR-PRD-04 | Unit required | Every product must have a selling unit |
| BR-PRD-05 | Soft delete | Products can only be deactivated, not deleted |
| BR-PRD-06 | Store scope | Products are scoped to organization |
| BR-PRD-07 | Image format | Images must be JPG, PNG, or WebP |
ProductVariant (SaleItem) Rules
| Rule ID | Rule | Description |
|---|---|---|
| BR-VAR-01 | Default variant | Every product has at least one default variant |
| BR-VAR-02 | Unique SKU | Variant SKU must be unique within organization |
| BR-VAR-03 | Unique barcode | Variant barcode must be unique within organization |
| BR-VAR-04 | Inherit product | Variants inherit parent product's category & tax |
| BR-VAR-05 | Require fare | Every variant must have at least one fare (base) |
| BR-VAR-06 | Soft delete | Variants can only be deactivated, not deleted |
Fare Rules
| Rule ID | Rule | Description |
|---|---|---|
| BR-FAR-01 | Price positive | Fare price must be >= 0 |
| BR-FAR-02 | Base required | Every variant must have a BASE fare |
| BR-FAR-03 | Valid dates | Promotional fares must have valid date range |
| BR-FAR-04 | Priority order | Higher priority fare wins when multiple valid |
| BR-FAR-05 | Fallback to base | Always fallback to BASE fare if no other valid |
Campaign & Sale Quotation Rules
| Rule ID | Rule | Description |
|---|---|---|
| BR-CMP-01 | Date required | Campaign must have start and end dates |
| BR-CMP-02 | Valid range | End date must be after start date |
| BR-CMP-03 | Quota positive | Sale quotation quantity must be > 0 |
| BR-CMP-04 | Quota tracking | System tracks remaining quota in real-time |
| BR-CMP-05 | Auto-fallback | When quota exhausted, use base fare |
| BR-CMP-06 | No oversell | Cannot sell more than quota at campaign price |
BOM Rules
| Rule ID | Rule | Description |
|---|---|---|
| BR-BOM-01 | Min components | BOM must have at least 1 component |
| BR-BOM-02 | No circular | BOM cannot reference itself |
| BR-BOM-03 | Component exists | All BOM components must be valid variants |
Acceptance Criteria
Product Acceptance Criteria
AC-PRD-01: Product Creation
GIVEN an owner on the Products page
WHEN they create a new product with required fields
THEN - Product is saved to database
- Default ProductVariant is created
- Base Fare is created for variant
- Product appears in catalog
- Product is searchable by nameAC-PRD-02: Category Organization
GIVEN a category hierarchy
WHEN viewing products
THEN - Products can be filtered by category
- Subcategories inherit parent visibility
- Category order matches display order
- Empty categories are hideableProductVariant Acceptance Criteria
AC-VAR-01: Variant Creation
GIVEN a product
WHEN owner creates variants (e.g., Size: S, M, L)
THEN - Each variant has unique SKU
- Each variant requires base fare
- Each variant tracks separate inventory
- POS shows variant selection on addAC-VAR-02: Variant Barcode Scan
GIVEN a variant with barcode assigned
WHEN cashier scans the barcode
THEN - Variant is found instantly
- Variant is added to cart
- Applicable fare is displayed
- Stock level is shown (if tracked)AC-VAR-03: Variant Search
GIVEN a product catalog
WHEN user searches for products
THEN - Search by product name (partial match)
- Search by variant SKU (exact match)
- Search by variant barcode (exact match)
- Results show variants with faresFare Acceptance Criteria
AC-FAR-01: Fare Configuration
GIVEN a ProductVariant
WHEN owner configures fares
THEN - Base fare is required
- Multiple fares can be added
- Each fare has type and price
- Promotional fares have date rangeAC-FAR-02: Fare Resolution
GIVEN a variant with multiple fares
WHEN adding to cart
THEN - System selects highest priority valid fare
- Campaign fare used if quota available
- Falls back to base fare if no other valid
- Displayed price matches selected fareCampaign Acceptance Criteria
AC-CMP-01: Campaign Creation
GIVEN an owner on the Campaigns page
WHEN they create a new campaign
THEN - Campaign has name, start/end dates
- Campaign status is SCHEDULED/ACTIVE/ENDED
- Sale quotations can be added
- Campaign appears in campaign listAC-CMP-02: Sale Quotation
GIVEN an active campaign
WHEN owner adds sale quotation
THEN - ProductVariant can be selected
- Quota quantity is set
- Campaign price is set
- Remaining quota is trackedAC-CMP-03: Quota Exhaustion
GIVEN a sale quotation with quota = 100
WHEN 100 units are sold at campaign price
THEN - Quota remaining = 0
- Subsequent sales use base fare
- Customer sees base price
- Campaign stats show 100% utilizedBOM Acceptance Criteria (Phase 3)
AC-BOM-01: Bill of Materials
GIVEN a combo product with BOM
WHEN the combo is sold
THEN - All component variants are deducted from inventory
- Component costs are tracked
- Production cost is calculated
- Profit margin is accurateDependencies
Product
├── Requires: Merchant (Store)
├── Required by: Inventory, Orders, Tax & Invoice
└── Integrates: None (internal catalog)
Entity Relationships:
├── Product → ProductVariant (1:N)
├── ProductVariant → Fare (1:N)
├── Campaign → SaleQuotation (1:N)
└── SaleQuotation → ProductVariant (N:1)| Module | Relationship |
|---|---|
| Merchant | Products scoped to organization/store |
| Inventory | Stock levels per ProductVariant |
| Orders | ProductVariants sold in orders |
| Tax & Invoice | Tax rates applied to products |
| Reports | Product/Campaign sales reports |
Integration Points
Barcode Standards
┌─────────────────────────────────────────────────────────────────┐
│ BARCODE SUPPORT │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Supported Formats: │
│ ├── EAN-13 (13 digits) - International standard │
│ ├── EAN-8 (8 digits) - Small products │
│ ├── UPC-A (12 digits) - US standard │
│ ├── Code 128 (variable) - Industrial/logistics │
│ └── QR Code - Quick lookup, promotions │
│ │
│ Auto-detection: │
│ ├── Scanner sends barcode to app │
│ ├── App detects format automatically │
│ └── Product lookup by barcode │
│ │
└─────────────────────────────────────────────────────────────────┘Image Storage
┌─────────────────────────────────────────────────────────────────┐
│ IMAGE MANAGEMENT │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Requirements: │
│ ├── Max file size: 5MB │
│ ├── Formats: JPG, PNG, WebP │
│ ├── Auto-resize to multiple sizes │
│ └── CDN delivery for fast loading │
│ │
│ Generated Sizes: │
│ ├── Thumbnail: 150x150px │
│ ├── Small: 300x300px │
│ ├── Medium: 600x600px │
│ └── Large: 1200x1200px │
│ │
└─────────────────────────────────────────────────────────────────┘Screenshots
Screenshots
Screenshots will be added after UI implementation.
Related Modules
- Merchant - Store/sale point configuration
- Inventory - Stock per ProductVariant
- Orders - Selling ProductVariants
- Tax & Invoice - Tax rates per product
- Reports - Product/Campaign performance