Feature #433
openUpdated by Redmine Admin 1 day ago
Menu Management System - Brief Explanation¶
Overview¶
The Menu Management system allows restaurants to organize their menu items hierarchically, manage recipes, and control which items are available at different stores through menu revisions.
Core Entities¶
1. Brand (Top Level)¶
- Purpose: Represents a restaurant chain/brand
- Example: "Pizza Palace" or "Curry House"
- Contains: Multiple stores, categories, menu items, recipes
2. Store (Location)¶
- Purpose: Physical restaurant location
- Example: "Pizza Palace - Downtown Branch"
- Contains: Can have different menu revisions activated
3. Category (Menu Grouping)¶
- Purpose: Groups menu items together (like "Main Courses", "Appetizers")
-
Fields:
-
Name: "Pizzas", "Indian Curries" -
Code: Optional identifier -
Order: Display order -
ImageUrl: Category image -
BackgroundColour/ForegroundColour: UI styling -
IsActive/IsHidden: Visibility control
-
-
Example:
- Category: "Pizzas" (contains all pizza items)
- Category: "Indian Main Courses" (contains butter chicken, etc.)
4. Recipe (Preparation Instructions)¶
- Purpose: Defines how to prepare a dish (for kitchen staff)
-
Fields:
-
Name: Recipe name -
BrandId: Which brand owns it
-
-
Example:
- Recipe: "Margherita Pizza Recipe"
- Recipe: "Butter Chicken Recipe"
5. MenuItem (The Actual Dish)¶
- Purpose: What customers see and order
-
Fields:
-
Name: "Margherita Pizza" or "Butter Chicken" -
Description: Customer-facing description -
CategoryId: Links to Category (e.g., "Pizzas") -
RecipeId: Links to Recipe (how to make it) -
PriceExcludingTaxes: Selling price -
PluCode: Product Look-Up code for POS -
ImageUrl: Product image -
KitchenDescription: Instructions for kitchen -
Order: Display order in menu -
IsOptional: Can have add-ons/modifiers -
IsOptionalAutoEnabled: Auto-enable optional items -
HideOnTransaction/HideOnInvoice: Visibility flags -
IsRoyaltyExempt: Financial flag -
BackgroundColour/ForegroundColour: UI styling
-
-
Example:
- MenuItem: "Margherita Pizza"
- Category: "Pizzas"
- Recipe: "Margherita Pizza Recipe"
- Price: $12.99
- MenuItem: "Butter Chicken"
- Category: "Indian Main Courses"
- Recipe: "Butter Chicken Recipe"
- Price: $15.99
- MenuItem: "Margherita Pizza"
6. MenuRevision (Menu Version Control)¶
- Purpose: Different versions of menus for different stores/profiles
-
Fields:
-
Name: "Summer Menu 2024", "Downtown Store Menu" -
Description: Notes about this revision -
BrandId: Which brand -
ProfileId: Links to a profile (store type, time period, etc.) -
DerivedFromMenuRevisionId: Can copy from another revision
-
-
Example:
- MenuRevision: "Downtown Store - Full Menu"
- MenuRevision: "Airport Store - Limited Menu" (fewer items)
7. Variant (Required Variations - e.g., Size, Crust Type)¶
- Purpose: Defines required variations that customers MUST choose (like pizza size or crust type)
-
Fields:
-
Name: "Size", "Crust Type", "Spice Level" -
Code: Optional identifier -
BrandId: Which brand owns this variant -
VariantOperationTypeId: Type of operation (Single Select, Multi Select, etc.) -
IsActive: Visibility control
-
-
Example:
- Variant: "Pizza Size" (for Pizza items)
- Variant: "Spice Level" (for Butter Chicken)
8. VariantValue (Specific Variant Options)¶
- Purpose: The actual choices for a Variant
-
Fields:
-
VariantId: Links to parent Variant -
Name: "Small", "Medium", "Large", "Thin Crust", "Thick Crust", "Mild", "Medium", "Hot" -
Code: Optional identifier -
Order: Display order -
IsActive: Visibility control
-
-
Example:
- VariantValue for "Pizza Size": "Small", "Medium", "Large"
- VariantValue for "Crust Type": "Thin Crust", "Thick Crust", "Stuffed Crust"
- VariantValue for "Spice Level": "Mild", "Medium", "Hot", "Extra Hot"
9. MenuItemVariant (Link Menu Item to Variant)¶
- Purpose: Connects a MenuItem to a Variant (makes the variant available for that item)
- Links: MenuItem ↔ Variant
10. MenuItemVariantValue (Link Menu Item to Specific Variant Values)¶
- Purpose: Defines which variant values are available for a menu item and their price adjustments
-
Fields:
-
MenuItemVariantId: Links to MenuItemVariant -
VariantValueId: Links to specific VariantValue -
PriceAdjustment: Additional cost (e.g., +$2.00 for Large size) -
IsDefault: Is this the default selection?
-
-
Example:
- MenuItem: "Margherita Pizza" + Variant: "Size" + Value: "Large" + PriceAdjustment: +$3.00
- MenuItem: "Butter Chicken" + Variant: "Spice Level" + Value: "Hot" + PriceAdjustment: $0.00
11. MenuItemRequiredVariant (Required Variant Selection)¶
- Purpose: Marks a variant as REQUIRED for a menu item (customer must choose)
-
Fields:
-
MenuItemId: Which menu item -
VariantId: Which variant is required -
IsRequired: Must be true (always required)
-
12. MenuItemRequiredVariantValue (Allowed Required Values)¶
- Purpose: Restricts which variant values are allowed for a required variant
- Links: MenuItemRequiredVariant ↔ VariantValue
13. Option (Optional Add-ons/Modifiers)¶
- Purpose: Defines optional add-ons that customers CAN choose (like toppings, sides)
-
Fields:
-
Name: "Pizza Toppings", "Extra Sides", "Beverages" -
Code: Optional identifier -
BrandId: Which brand owns this option -
OptionOperationTypeId: Type of operation (Single Select, Multi Select, etc.) -
PriceDisplayId: How to display prices (Show Price, Hide Price, etc.) -
IsActive: Visibility control
-
-
Example:
- Option: "Pizza Toppings" (for Pizza items)
- Option: "Extra Sides" (for Butter Chicken - naan, rice, etc.)
14. OptionItem (Specific Optional Items)¶
- Purpose: The actual optional items customers can add
-
Fields:
-
OptionId: Links to parent Option -
MenuItemId: Links to a MenuItem (the actual item being offered as an option) -
Name: Display name -
Code: Optional identifier -
Order: Display order -
IsAutoSelected: Should this be pre-selected? -
OverridePriceExcludingTaxes: Custom price for this option (overrides MenuItem price) -
OptionOperationTypeId: Operation type -
PriceDisplayId: Price display setting
-
-
Example:
- OptionItem: "Extra Cheese" (MenuItem: "Extra Cheese", Price: +$1.50)
- OptionItem: "Pepperoni" (MenuItem: "Pepperoni", Price: +$2.00)
- OptionItem: "Garlic Naan" (MenuItem: "Garlic Naan", Price: +$3.00)
- OptionItem: "Basmati Rice" (MenuItem: "Basmati Rice", Price: +$2.50)
15. MenuItemOptionMap (Link Menu Item to Option)¶
- Purpose: Connects a MenuItem to an Option (makes the option available for that item)
-
Fields:
-
MenuItemId: Which menu item -
OptionId: Which option group -
Order: Display order -
IsRequired: Must customer select at least one from this option?
-
-
Example:
- MenuItem: "Margherita Pizza" + Option: "Pizza Toppings" (IsRequired: false - optional)
- MenuItem: "Butter Chicken" + Option: "Extra Sides" (IsRequired: false - optional)
16. StoreOptionalItemMap (Store-Specific Optional Item Availability)¶
- Purpose: Controls which optional items/add-ons are available at specific stores
-
Fields:
-
StoreId: Which store -
MenuItemId: Which optional item (OptionItem) -
IsActive: Is this optional item available at this store?
-
- Links: Store ↔ MenuItem (optional items)
17. RecipeItem (Ingredients in Recipe)¶
- Purpose: Lists the ingredients/stock items needed for a recipe
-
Fields:
-
RecipeRevisionId: Links to RecipeRevision -
RecipeId: Links to Recipe -
StockItemId: Links to StockItem (the ingredient) -
Quantity: How much of this ingredient is needed
-
-
Example:
- Recipe: "Margherita Pizza Recipe"
- RecipeItem: "Flour" (StockItem) - Quantity: 500g
- RecipeItem: "Tomato Sauce" (StockItem) - Quantity: 100ml
- RecipeItem: "Mozzarella Cheese" (StockItem) - Quantity: 200g
- RecipeItem: "Fresh Basil" (StockItem) - Quantity: 10g
- Recipe: "Margherita Pizza Recipe"
18. StockItem (Inventory Items/Ingredients)¶
- Purpose: Represents physical inventory items used in recipes
-
Fields:
-
Name: "Flour", "Tomato Sauce", "Chicken Breast", "Butter" -
Code: SKU or barcode -
Description: Item description -
BrandId: Which brand owns this stock item -
StockCategoryId: Category (e.g., "Dairy", "Meat", "Vegetables") -
UnitOfMeasureId: Measurement unit (kg, g, ml, pieces, etc.) -
IsArchived: Soft delete flag
-
-
Example:
- StockItem: "Mozzarella Cheese" (Category: "Dairy", Unit: "kg")
- StockItem: "Chicken Breast" (Category: "Meat", Unit: "kg")
- StockItem: "Tomato Sauce" (Category: "Sauces", Unit: "ml")
19. StockCategory (Inventory Categories)¶
- Purpose: Groups stock items into categories
- Example: "Dairy", "Meat", "Vegetables", "Sauces", "Spices"
20. UnitOfMeasure (Measurement Units)¶
- Purpose: Defines units for measuring stock items
- Example: "kg", "g", "ml", "L", "pieces", "boxes"
21. MenuItemAvailabilityByDay (Day-Based Availability)¶
- Purpose: Controls when menu items are available (specific days/times)
-
Fields:
-
MenuItemId: Which menu item -
DayOfWeek: Monday, Tuesday, etc. -
StartTime: When item becomes available (e.g., 11:00 AM) -
EndTime: When item stops being available (e.g., 10:00 PM) -
IsAvailable: Is item available on this day?
-
-
Example:
- MenuItem: "Butter Chicken" available Monday-Friday, 11:00 AM - 10:00 PM
- MenuItem: "Weekend Special Pizza" available Saturday-Sunday only
22. MenuItemTaxRateMap (Tax Configuration)¶
- Purpose: Links menu items to tax rates
- Links: MenuItem ↔ TaxRate
23. MenuItemRoyaltyMap (Royalty Tracking)¶
- Purpose: Tracks royalty/franchise fees for menu items
- Links: MenuItem ↔ Royalty configuration
24. MenuItemProductionRoleMap (Kitchen Role Assignment)¶
- Purpose: Assigns which kitchen roles/stations can prepare this item
- Links: MenuItem ↔ Production Role
25. PriceDisplay (Price Display Options)¶
- Purpose: Controls how prices are displayed for options
- Example: "Show Price", "Hide Price", "Show as Percentage"
26. VariantOperationType (Variant Selection Type)¶
- Purpose: Defines how variants work (Single Select, Multi Select, etc.)
- Example: "Single Select" (choose one size), "Multi Select" (choose multiple)
27. OptionOperationType (Option Selection Type)¶
- Purpose: Defines how options work (Single Select, Multi Select, etc.)
- Example: "Multi Select" (choose multiple toppings), "Single Select" (choose one side)
28. StoreMenuNotificationStatus (Menu Update Tracking)¶
- Purpose: Tracks when stores need to be notified about menu changes
- Links: Store ↔ MenuRevision ↔ OrderType
Example Flow: Pizza & Butter Chicken¶
Scenario: "Pizza Palace" Brand with 2 Stores¶
Step 1: Create Categories¶
Category 1:
- Name: "Pizzas"
- Code: "PIZZA"
- Order: 1
- IsActive: true
Category 2:
- Name: "Indian Curries"
- Code: "CURRY"
- Order: 2
- IsActive: true
Step 2: Create Recipes¶
Recipe 1:
- Name: "Margherita Pizza Recipe"
- BrandId: Pizza Palace
Recipe 2:
- Name: "Butter Chicken Recipe"
- BrandId: Pizza Palace
Step 3: Create Variants (Required Choices)¶
Variant 1: "Pizza Size"
- Name: "Size"
- VariantOperationType: "Single Select" (customer must choose one)
- VariantValues:
- "Small" (10-inch) - Order: 1
- "Medium" (12-inch) - Order: 2
- "Large" (14-inch) - Order: 3
- "Extra Large" (16-inch) - Order: 4
Variant 2: "Crust Type"
- Name: "Crust Type"
- VariantOperationType: "Single Select"
- VariantValues:
- "Thin Crust" - Order: 1
- "Thick Crust" - Order: 2
- "Stuffed Crust" - Order: 3
Variant 3: "Spice Level"
- Name: "Spice Level"
- VariantOperationType: "Single Select"
- VariantValues:
- "Mild" - Order: 1
- "Medium" - Order: 2
- "Hot" - Order: 3
- "Extra Hot" - Order: 4
Step 4: Create Options (Optional Add-ons)¶
Option 1: "Pizza Toppings"
- Name: "Pizza Toppings"
- OptionOperationType: "Multi Select" (customer can choose multiple)
- PriceDisplay: "Show Price"
- OptionItems (these are MenuItems themselves):
- "Extra Cheese" (MenuItem) - Price: +$1.50
- "Pepperoni" (MenuItem) - Price: +$2.00
- "Mushrooms" (MenuItem) - Price: +$1.50
- "Olives" (MenuItem) - Price: +$1.00
- "Bell Peppers" (MenuItem) - Price: +$1.00
Option 2: "Extra Sides"
- Name: "Extra Sides"
- OptionOperationType: "Multi Select"
- PriceDisplay: "Show Price"
- OptionItems:
- "Garlic Naan" (MenuItem) - Price: +$3.00
- "Basmati Rice" (MenuItem) - Price: +$2.50
- "Raita" (MenuItem) - Price: +$1.50
Step 5: Create Stock Items (Ingredients)¶
StockItem 1: "Mozzarella Cheese"
- Category: "Dairy"
- Unit: "kg"
StockItem 2: "Chicken Breast"
- Category: "Meat"
- Unit: "kg"
StockItem 3: "Tomato Sauce"
- Category: "Sauces"
- Unit: "ml"
StockItem 4: "Flour"
- Category: "Baking"
- Unit: "kg"
StockItem 5: "Butter"
- Category: "Dairy"
- Unit: "kg"
StockItem 6: "Cream"
- Category: "Dairy"
- Unit: "ml"
Step 6: Create Recipe Items (Link Ingredients to Recipes)¶
Recipe: "Margherita Pizza Recipe"
- RecipeItem: "Flour" - Quantity: 500g
- RecipeItem: "Tomato Sauce" - Quantity: 100ml
- RecipeItem: "Mozzarella Cheese" - Quantity: 200g
- RecipeItem: "Fresh Basil" - Quantity: 10g
Recipe: "Butter Chicken Recipe"
- RecipeItem: "Chicken Breast" - Quantity: 300g
- RecipeItem: "Tomato Sauce" - Quantity: 200ml
- RecipeItem: "Butter" - Quantity: 50g
- RecipeItem: "Cream" - Quantity: 100ml
- RecipeItem: "Spices Mix" - Quantity: 20g
Step 7: Create Menu Items¶
MenuItem 1: "Margherita Pizza"
- CategoryId: "Pizzas" (Category 1)
- RecipeId: "Margherita Pizza Recipe" (Recipe 1)
- PriceExcludingTaxes: $12.99 (base price for Medium)
- Description: "Classic pizza with tomato, mozzarella, and basil"
- PluCode: "PIZ001"
- ImageUrl: "/images/margherita.jpg"
- KitchenDescription: "12-inch base, fresh mozzarella, basil garnish"
- Order: 1
- IsOptional: true (can add toppings)
MenuItem 2: "Butter Chicken"
- CategoryId: "Indian Curries" (Category 2)
- RecipeId: "Butter Chicken Recipe" (Recipe 2)
- PriceExcludingTaxes: $15.99
- Description: "Creamy tomato-based curry with tender chicken"
- PluCode: "CUR001"
- ImageUrl: "/images/butter-chicken.jpg"
- KitchenDescription: "Medium spice, serve with basmati rice"
- Order: 1
- IsOptional: true (can add sides)
Step 8: Link Variants to Menu Items¶
MenuItem: "Margherita Pizza"
- MenuItemVariant: "Pizza Size" (REQUIRED)
- MenuItemVariantValue: "Small" - PriceAdjustment: -$2.00 (total: $10.99)
- MenuItemVariantValue: "Medium" - PriceAdjustment: $0.00 (total: $12.99) [DEFAULT]
- MenuItemVariantValue: "Large" - PriceAdjustment: +$3.00 (total: $15.99)
- MenuItemVariantValue: "Extra Large" - PriceAdjustment: +$5.00 (total: $17.99)
- MenuItemVariant: "Crust Type" (REQUIRED)
- MenuItemVariantValue: "Thin Crust" - PriceAdjustment: $0.00 [DEFAULT]
- MenuItemVariantValue: "Thick Crust" - PriceAdjustment: +$1.00
- MenuItemVariantValue: "Stuffed Crust" - PriceAdjustment: +$2.50
MenuItem: "Butter Chicken"
- MenuItemVariant: "Spice Level" (REQUIRED)
- MenuItemVariantValue: "Mild" - PriceAdjustment: $0.00 [DEFAULT]
- MenuItemVariantValue: "Medium" - PriceAdjustment: $0.00
- MenuItemVariantValue: "Hot" - PriceAdjustment: $0.00
- MenuItemVariantValue: "Extra Hot" - PriceAdjustment: $0.00
Step 9: Link Options to Menu Items¶
MenuItem: "Margherita Pizza"
- MenuItemOptionMap: "Pizza Toppings" (OPTIONAL, IsRequired: false)
- Customer can add: Extra Cheese, Pepperoni, Mushrooms, Olives, Bell Peppers
- Each topping adds to the price
MenuItem: "Butter Chicken"
- MenuItemOptionMap: "Extra Sides" (OPTIONAL, IsRequired: false)
- Customer can add: Garlic Naan, Basmati Rice, Raita
- Each side adds to the price
Step 10: Set Store-Specific Optional Item Availability¶
Store: "Pizza Palace - Downtown"
- StoreOptionalItemMap: "Extra Cheese" - IsActive: true
- StoreOptionalItemMap: "Pepperoni" - IsActive: true
- StoreOptionalItemMap: "Garlic Naan" - IsActive: true
- StoreOptionalItemMap: "Basmati Rice" - IsActive: true
Store: "Pizza Palace - Airport" (smaller store)
- StoreOptionalItemMap: "Extra Cheese" - IsActive: true
- StoreOptionalItemMap: "Pepperoni" - IsActive: false (not available)
- StoreOptionalItemMap: "Garlic Naan" - IsActive: false (not available)
Step 11: Set Day-Based Availability¶
MenuItem: "Butter Chicken"
- MenuItemAvailabilityByDay:
- Monday: Available 11:00 AM - 10:00 PM
- Tuesday: Available 11:00 AM - 10:00 PM
- Wednesday: Available 11:00 AM - 10:00 PM
- Thursday: Available 11:00 AM - 10:00 PM
- Friday: Available 11:00 AM - 11:00 PM (extended hours)
- Saturday: Available 11:00 AM - 11:00 PM
- Sunday: Not Available (restaurant closed)
Step 12: Create Menu Revisions¶
MenuRevision 1: "Downtown Store - Full Menu"
- BrandId: Pizza Palace
- ProfileId: FullMenuProfile
- Contains: All items (Pizza + Butter Chicken)
MenuRevision 2: "Airport Store - Pizza Only"
- BrandId: Pizza Palace
- ProfileId: LimitedMenuProfile
- Contains: Only Pizza items (no Butter Chicken)
Step 13: Activate Menu at Stores¶
Store 1: "Pizza Palace - Downtown"
- Active MenuRevision: "Downtown Store - Full Menu"
- Customers see: Both Pizza and Butter Chicken
Store 2: "Pizza Palace - Airport"
- Active MenuRevision: "Airport Store - Pizza Only"
- Customers see: Only Pizza (Butter Chicken hidden)
Entity Relationships¶
Brand (1) ──→ (Many) Store
Brand (1) ──→ (Many) Category
Brand (1) ──→ (Many) Recipe
Brand (1) ──→ (Many) MenuItem
Brand (1) ──→ (Many) MenuRevision
Brand (1) ──→ (Many) Variant
Brand (1) ──→ (Many) Option
Brand (1) ──→ (Many) StockItem
Category (1) ──→ (Many) MenuItem
Recipe (1) ──→ (Many) MenuItem
StockCategory (1) ──→ (Many) StockItem
UnitOfMeasure (1) ──→ (Many) StockItem
Variant (1) ──→ (Many) VariantValue
VariantOperationType (1) ──→ (Many) Variant
MenuItem (1) ──→ (Many) MenuItemVariant
MenuItemVariant (1) ──→ (Many) MenuItemVariantValue
MenuItemVariantValue (1) ──→ (1) VariantValue
MenuItem (1) ──→ (Many) MenuItemRequiredVariant
MenuItemRequiredVariant (1) ──→ (Many) MenuItemRequiredVariantValue
MenuItemRequiredVariantValue (1) ──→ (1) VariantValue
Option (1) ──→ (Many) OptionItem
OptionOperationType (1) ──→ (Many) Option
PriceDisplay (1) ──→ (Many) Option
MenuItem (1) ──→ (Many) MenuItemOptionMap
MenuItemOptionMap (1) ──→ (1) Option
OptionItem (1) ──→ (1) MenuItem (the item being offered as an option)
Recipe (1) ──→ (Many) RecipeRevision
RecipeRevision (1) ──→ (Many) RecipeItem
RecipeItem (1) ──→ (1) StockItem
MenuItem (1) ──→ (Many) MenuItemAvailabilityByDay
MenuItem (1) ──→ (Many) MenuItemTaxRateMap
MenuItem (1) ──→ (Many) MenuItemRoyaltyMap
MenuItem (1) ──→ (Many) MenuItemProductionRoleMap
MenuRevision (1) ──→ (Many) StoreMenuNotificationStatus
Store (1) ──→ (Many) StoreMenuNotificationStatus
Store (1) ──→ (Many) StoreOptionalItemMap
MenuItem (1) ──→ (Many) StoreOptionalItemMap
Key Features¶
- Hierarchical Organization: Brand → Category → MenuItem
- Recipe Management: Separate recipes from menu items (one recipe can be used by multiple items)
- Menu Versioning: Different menu revisions for different stores/profiles
- Store-Specific Control: Each store can have different menu items available
- Variants (Required Choices): Menu items can have required variations (size, crust type, spice level) with price adjustments
- Options (Optional Add-ons): Menu items can have optional add-ons/modifiers (toppings, sides) with additional pricing
- Inventory Integration: Recipes link to stock items for ingredient tracking
- Pricing Flexibility: Base price + variant price adjustments + option prices
- Day-Based Availability: Control when items are available (specific days/times)
- Tax & Royalty Management: Link items to tax rates and royalty configurations
- Kitchen Role Assignment: Assign which kitchen stations can prepare items
- Visibility Control: Hide items on transactions/invoices if needed
- Ordering: Control display order of categories and items
Complete Workflow Example¶
- Admin creates Brand: "Pizza Palace"
- Admin creates Stock Items: Ingredients (flour, cheese, chicken, etc.)
- Admin creates Stock Categories: "Dairy", "Meat", "Sauces", etc.
- Admin creates Variants: "Pizza Size", "Crust Type", "Spice Level"
- Admin creates Variant Values: "Small/Medium/Large", "Thin/Thick/Stuffed", "Mild/Medium/Hot"
- Admin creates Options: "Pizza Toppings", "Extra Sides"
- Admin creates Option Items: "Extra Cheese", "Pepperoni", "Garlic Naan", etc. (these are MenuItems)
- Admin creates Categories: "Pizzas", "Indian Curries"
- Admin creates Recipes: "Margherita Recipe", "Butter Chicken Recipe"
- Admin creates Recipe Items: Links ingredients (StockItems) to recipes with quantities
- Admin creates Menu Items: Links items to categories and recipes, sets base prices
- Admin links Variants to Menu Items: Assigns required variants (size, crust) with price adjustments
- Admin links Options to Menu Items: Assigns optional add-ons (toppings, sides)
- Admin sets Store-Specific Availability: Controls which optional items are available at each store
- Admin sets Day-Based Availability: Controls when items are available
- Admin creates Menu Revisions: Different menu versions
- Admin assigns Menu Revisions to Stores: Each store gets appropriate menu
- Store activates Menu Revision: Menu goes live at that store
-
Customers order:
- Select menu item (e.g., "Margherita Pizza")
- MUST choose required variants (Size: Large, Crust: Thick) - price adjusts
- CAN choose optional add-ons (Toppings: Extra Cheese +$1.50, Pepperoni +$2.00)
- Final price = Base + Variant adjustments + Option prices
Complete Customer Order Example¶
Scenario: Customer Orders "Margherita Pizza" with Variants and Options¶
Step 1: Customer Selects Menu Item
- MenuItem: "Margherita Pizza"
- Base Price: $12.99 (for Medium size)
Step 2: Customer MUST Choose Required Variants
-
Variant: "Pizza Size" (REQUIRED - Single Select)
- Customer selects: "Large"
- Price Adjustment: +$3.00
- Running Total: $12.99 + $3.00 = $15.99
-
Variant: "Crust Type" (REQUIRED - Single Select)
- Customer selects: "Stuffed Crust"
- Price Adjustment: +$2.50
- Running Total: $15.99 + $2.50 = $18.49
Step 3: Customer CAN Choose Optional Options
-
Option: "Pizza Toppings" (OPTIONAL - Multi Select)
- Customer selects: "Extra Cheese" (+$1.50)
- Customer selects: "Pepperoni" (+$2.00)
- Running Total: $18.49 + $1.50 + $2.00 = $22.99
Final Order:
- Item: Margherita Pizza
- Size: Large (+$3.00)
- Crust: Stuffed Crust (+$2.50)
- Toppings: Extra Cheese (+$1.50), Pepperoni (+$2.00)
- Total Price: $22.99
Scenario: Customer Orders "Butter Chicken" with Variants and Options¶
Step 1: Customer Selects Menu Item
- MenuItem: "Butter Chicken"
- Base Price: $15.99
Step 2: Customer MUST Choose Required Variant
-
Variant: "Spice Level" (REQUIRED - Single Select)
- Customer selects: "Hot"
- Price Adjustment: $0.00 (no extra charge)
- Running Total: $15.99
Step 3: Customer CAN Choose Optional Options
-
Option: "Extra Sides" (OPTIONAL - Multi Select)
- Customer selects: "Garlic Naan" (+$3.00)
- Customer selects: "Basmati Rice" (+$2.50)
- Running Total: $15.99 + $3.00 + $2.50 = $21.49
Final Order:
- Item: Butter Chicken
- Spice Level: Hot
- Sides: Garlic Naan (+$3.00), Basmati Rice (+$2.50)
- Total Price: $21.49
Benefits¶
- Centralized Management: Manage all menu items at brand level
- Flexibility: Different stores can have different menus
- Consistency: Recipes ensure consistent preparation
- Scalability: Easy to add new items, categories, or stores
- Control: Fine-grained control over what's available where
- Variants System: Required choices (size, type) with price adjustments
- Options System: Optional add-ons (toppings, sides) with flexible pricing
- Inventory Integration: Track ingredients through recipes and stock items
- Pricing Flexibility: Base price + variant adjustments + option prices
- Time-Based Control: Day and time-based availability
Updated by Redmine Admin 1 day ago
Menu Management System - Brief Explanation¶
Overview¶
The Menu Management system allows restaurants to organize their menu items hierarchically, manage recipes, and control which items are available at different stores through menu revisions.
Core Entities¶
1. Brand (Top Level)¶
- Purpose: Represents a restaurant chain/brand
- Example: "Pizza Palace" or "Curry House"
- Contains: Multiple stores, categories, menu items, recipes
2. Store (Location)¶
- Purpose: Physical restaurant location
- Example: "Pizza Palace - Downtown Branch"
- Contains: Can have different menu revisions activated
3. Category (Menu Grouping)¶
- Purpose: Groups menu items together (like "Main Courses", "Appetizers")
-
Fields:
-
Name: "Pizzas", "Indian Curries" -
Code: Optional identifier -
Order: Display order -
ImageUrl: Category image -
BackgroundColour/ForegroundColour: UI styling -
IsActive/IsHidden: Visibility control
-
-
Example:
- Category: "Pizzas" (contains all pizza items)
- Category: "Indian Main Courses" (contains butter chicken, etc.)
4. Recipe (Preparation Instructions)¶
- Purpose: Defines how to prepare a dish (for kitchen staff)
-
Fields:
-
Name: Recipe name -
BrandId: Which brand owns it
-
-
Example:
- Recipe: "Margherita Pizza Recipe"
- Recipe: "Butter Chicken Recipe"
5. MenuItem (The Actual Dish)¶
- Purpose: What customers see and order
-
Fields:
-
Name: "Margherita Pizza" or "Butter Chicken" -
Description: Customer-facing description -
CategoryId: Links to Category (e.g., "Pizzas") -
RecipeId: Links to Recipe (how to make it) -
PriceExcludingTaxes: Selling price -
PluCode: Product Look-Up code for POS -
ImageUrl: Product image -
KitchenDescription: Instructions for kitchen -
Order: Display order in menu -
IsOptional: Can have add-ons/modifiers -
IsOptionalAutoEnabled: Auto-enable optional items -
HideOnTransaction/HideOnInvoice: Visibility flags -
IsRoyaltyExempt: Financial flag -
BackgroundColour/ForegroundColour: UI styling
-
-
Example:
- MenuItem: "Margherita Pizza"
- Category: "Pizzas"
- Recipe: "Margherita Pizza Recipe"
- Price: $12.99
- MenuItem: "Butter Chicken"
- Category: "Indian Main Courses"
- Recipe: "Butter Chicken Recipe"
- Price: $15.99
- MenuItem: "Margherita Pizza"
6. MenuRevision (Menu Version Control)¶
- Purpose: Different versions of menus for different stores/profiles
-
Fields:
-
Name: "Summer Menu 2024", "Downtown Store Menu" -
Description: Notes about this revision -
BrandId: Which brand -
ProfileId: Links to a profile (store type, time period, etc.) -
DerivedFromMenuRevisionId: Can copy from another revision
-
-
Example:
- MenuRevision: "Downtown Store - Full Menu"
- MenuRevision: "Airport Store - Limited Menu" (fewer items)
7. Variant (Required Variations - e.g., Size, Crust Type)¶
- Purpose: Defines required variations that customers MUST choose (like pizza size or crust type)
-
Fields:
-
Name: "Size", "Crust Type", "Spice Level" -
Code: Optional identifier -
BrandId: Which brand owns this variant -
VariantOperationTypeId: Type of operation (Single Select, Multi Select, etc.) -
IsActive: Visibility control
-
-
Example:
- Variant: "Pizza Size" (for Pizza items)
- Variant: "Spice Level" (for Butter Chicken)
8. VariantValue (Specific Variant Options)¶
- Purpose: The actual choices for a Variant
-
Fields:
-
VariantId: Links to parent Variant -
Name: "Small", "Medium", "Large", "Thin Crust", "Thick Crust", "Mild", "Medium", "Hot" -
Code: Optional identifier -
Order: Display order -
IsActive: Visibility control
-
-
Example:
- VariantValue for "Pizza Size": "Small", "Medium", "Large"
- VariantValue for "Crust Type": "Thin Crust", "Thick Crust", "Stuffed Crust"
- VariantValue for "Spice Level": "Mild", "Medium", "Hot", "Extra Hot"
9. MenuItemVariant (Link Menu Item to Variant)¶
- Purpose: Connects a MenuItem to a Variant (makes the variant available for that item)
- Links: MenuItem ↔ Variant
10. MenuItemVariantValue (Link Menu Item to Specific Variant Values)¶
- Purpose: Defines which variant values are available for a menu item and their price adjustments
-
Fields:
-
MenuItemVariantId: Links to MenuItemVariant -
VariantValueId: Links to specific VariantValue -
PriceAdjustment: Additional cost (e.g., +$2.00 for Large size) -
IsDefault: Is this the default selection?
-
-
Example:
- MenuItem: "Margherita Pizza" + Variant: "Size" + Value: "Large" + PriceAdjustment: +$3.00
- MenuItem: "Butter Chicken" + Variant: "Spice Level" + Value: "Hot" + PriceAdjustment: $0.00
11. MenuItemRequiredVariant (Required Variant Selection)¶
- Purpose: Marks a variant as REQUIRED for a menu item (customer must choose)
-
Fields:
-
MenuItemId: Which menu item -
VariantId: Which variant is required -
IsRequired: Must be true (always required)
-
12. MenuItemRequiredVariantValue (Allowed Required Values)¶
- Purpose: Restricts which variant values are allowed for a required variant
- Links: MenuItemRequiredVariant ↔ VariantValue
13. Option (Optional Add-ons/Modifiers)¶
- Purpose: Defines optional add-ons that customers CAN choose (like toppings, sides)
-
Fields:
-
Name: "Pizza Toppings", "Extra Sides", "Beverages" -
Code: Optional identifier -
BrandId: Which brand owns this option -
OptionOperationTypeId: Type of operation (Single Select, Multi Select, etc.) -
PriceDisplayId: How to display prices (Show Price, Hide Price, etc.) -
IsActive: Visibility control
-
-
Example:
- Option: "Pizza Toppings" (for Pizza items)
- Option: "Extra Sides" (for Butter Chicken - naan, rice, etc.)
14. OptionItem (Specific Optional Items)¶
- Purpose: The actual optional items customers can add
-
Fields:
-
OptionId: Links to parent Option -
MenuItemId: Links to a MenuItem (the actual item being offered as an option) -
Name: Display name -
Code: Optional identifier -
Order: Display order -
IsAutoSelected: Should this be pre-selected? -
OverridePriceExcludingTaxes: Custom price for this option (overrides MenuItem price) -
OptionOperationTypeId: Operation type -
PriceDisplayId: Price display setting
-
-
Example:
- OptionItem: "Extra Cheese" (MenuItem: "Extra Cheese", Price: +$1.50)
- OptionItem: "Pepperoni" (MenuItem: "Pepperoni", Price: +$2.00)
- OptionItem: "Garlic Naan" (MenuItem: "Garlic Naan", Price: +$3.00)
- OptionItem: "Basmati Rice" (MenuItem: "Basmati Rice", Price: +$2.50)
15. MenuItemOptionMap (Link Menu Item to Option)¶
- Purpose: Connects a MenuItem to an Option (makes the option available for that item)
-
Fields:
-
MenuItemId: Which menu item -
OptionId: Which option group -
Order: Display order -
IsRequired: Must customer select at least one from this option?
-
-
Example:
- MenuItem: "Margherita Pizza" + Option: "Pizza Toppings" (IsRequired: false - optional)
- MenuItem: "Butter Chicken" + Option: "Extra Sides" (IsRequired: false - optional)
16. StoreOptionalItemMap (Store-Specific Optional Item Availability)¶
- Purpose: Controls which optional items/add-ons are available at specific stores
-
Fields:
-
StoreId: Which store -
MenuItemId: Which optional item (OptionItem) -
IsActive: Is this optional item available at this store?
-
- Links: Store ↔ MenuItem (optional items)
17. RecipeItem (Ingredients in Recipe)¶
- Purpose: Lists the ingredients/stock items needed for a recipe
-
Fields:
-
RecipeRevisionId: Links to RecipeRevision -
RecipeId: Links to Recipe -
StockItemId: Links to StockItem (the ingredient) -
Quantity: How much of this ingredient is needed
-
-
Example:
- Recipe: "Margherita Pizza Recipe"
- RecipeItem: "Flour" (StockItem) - Quantity: 500g
- RecipeItem: "Tomato Sauce" (StockItem) - Quantity: 100ml
- RecipeItem: "Mozzarella Cheese" (StockItem) - Quantity: 200g
- RecipeItem: "Fresh Basil" (StockItem) - Quantity: 10g
- Recipe: "Margherita Pizza Recipe"
18. StockItem (Inventory Items/Ingredients)¶
- Purpose: Represents physical inventory items used in recipes
-
Fields:
-
Name: "Flour", "Tomato Sauce", "Chicken Breast", "Butter" -
Code: SKU or barcode -
Description: Item description -
BrandId: Which brand owns this stock item -
StockCategoryId: Category (e.g., "Dairy", "Meat", "Vegetables") -
UnitOfMeasureId: Measurement unit (kg, g, ml, pieces, etc.) -
IsArchived: Soft delete flag
-
-
Example:
- StockItem: "Mozzarella Cheese" (Category: "Dairy", Unit: "kg")
- StockItem: "Chicken Breast" (Category: "Meat", Unit: "kg")
- StockItem: "Tomato Sauce" (Category: "Sauces", Unit: "ml")
19. StockCategory (Inventory Categories)¶
- Purpose: Groups stock items into categories
- Example: "Dairy", "Meat", "Vegetables", "Sauces", "Spices"
20. UnitOfMeasure (Measurement Units)¶
- Purpose: Defines units for measuring stock items
- Example: "kg", "g", "ml", "L", "pieces", "boxes"
21. MenuItemAvailabilityByDay (Day-Based Availability)¶
- Purpose: Controls when menu items are available (specific days/times)
-
Fields:
-
MenuItemId: Which menu item -
DayOfWeek: Monday, Tuesday, etc. -
StartTime: When item becomes available (e.g., 11:00 AM) -
EndTime: When item stops being available (e.g., 10:00 PM) -
IsAvailable: Is item available on this day?
-
-
Example:
- MenuItem: "Butter Chicken" available Monday-Friday, 11:00 AM - 10:00 PM
- MenuItem: "Weekend Special Pizza" available Saturday-Sunday only
22. MenuItemTaxRateMap (Tax Configuration)¶
- Purpose: Links menu items to tax rates
- Links: MenuItem ↔ TaxRate
23. MenuItemRoyaltyMap (Royalty Tracking)¶
- Purpose: Tracks royalty/franchise fees for menu items
- Links: MenuItem ↔ Royalty configuration
24. MenuItemProductionRoleMap (Kitchen Role Assignment)¶
- Purpose: Assigns which kitchen roles/stations can prepare this item
- Links: MenuItem ↔ Production Role
25. PriceDisplay (Price Display Options)¶
- Purpose: Controls how prices are displayed for options
- Example: "Show Price", "Hide Price", "Show as Percentage"
26. VariantOperationType (Variant Selection Type)¶
- Purpose: Defines how variants work (Single Select, Multi Select, etc.)
- Example: "Single Select" (choose one size), "Multi Select" (choose multiple)
27. OptionOperationType (Option Selection Type)¶
- Purpose: Defines how options work (Single Select, Multi Select, etc.)
- Example: "Multi Select" (choose multiple toppings), "Single Select" (choose one side)
28. StoreMenuNotificationStatus (Menu Update Tracking)¶
- Purpose: Tracks when stores need to be notified about menu changes
- Links: Store ↔ MenuRevision ↔ OrderType
Example Flow: Pizza & Butter Chicken¶
Scenario: "Pizza Palace" Brand with 2 Stores¶
Step 1: Create Categories¶
Category 1:
- Name: "Pizzas"
- Code: "PIZZA"
- Order: 1
- IsActive: true
Category 2:
- Name: "Indian Curries"
- Code: "CURRY"
- Order: 2
- IsActive: true
Step 2: Create Recipes¶
Recipe 1:
- Name: "Margherita Pizza Recipe"
- BrandId: Pizza Palace
Recipe 2:
- Name: "Butter Chicken Recipe"
- BrandId: Pizza Palace
Step 3: Create Variants (Required Choices)¶
Variant 1: "Pizza Size"
- Name: "Size"
- VariantOperationType: "Single Select" (customer must choose one)
- VariantValues:
- "Small" (10-inch) - Order: 1
- "Medium" (12-inch) - Order: 2
- "Large" (14-inch) - Order: 3
- "Extra Large" (16-inch) - Order: 4
Variant 2: "Crust Type"
- Name: "Crust Type"
- VariantOperationType: "Single Select"
- VariantValues:
- "Thin Crust" - Order: 1
- "Thick Crust" - Order: 2
- "Stuffed Crust" - Order: 3
Variant 3: "Spice Level"
- Name: "Spice Level"
- VariantOperationType: "Single Select"
- VariantValues:
- "Mild" - Order: 1
- "Medium" - Order: 2
- "Hot" - Order: 3
- "Extra Hot" - Order: 4
Step 4: Create Options (Optional Add-ons)¶
Option 1: "Pizza Toppings"
- Name: "Pizza Toppings"
- OptionOperationType: "Multi Select" (customer can choose multiple)
- PriceDisplay: "Show Price"
- OptionItems (these are MenuItems themselves):
- "Extra Cheese" (MenuItem) - Price: +$1.50
- "Pepperoni" (MenuItem) - Price: +$2.00
- "Mushrooms" (MenuItem) - Price: +$1.50
- "Olives" (MenuItem) - Price: +$1.00
- "Bell Peppers" (MenuItem) - Price: +$1.00
Option 2: "Extra Sides"
- Name: "Extra Sides"
- OptionOperationType: "Multi Select"
- PriceDisplay: "Show Price"
- OptionItems:
- "Garlic Naan" (MenuItem) - Price: +$3.00
- "Basmati Rice" (MenuItem) - Price: +$2.50
- "Raita" (MenuItem) - Price: +$1.50
Step 5: Create Stock Items (Ingredients)¶
StockItem 1: "Mozzarella Cheese"
- Category: "Dairy"
- Unit: "kg"
StockItem 2: "Chicken Breast"
- Category: "Meat"
- Unit: "kg"
StockItem 3: "Tomato Sauce"
- Category: "Sauces"
- Unit: "ml"
StockItem 4: "Flour"
- Category: "Baking"
- Unit: "kg"
StockItem 5: "Butter"
- Category: "Dairy"
- Unit: "kg"
StockItem 6: "Cream"
- Category: "Dairy"
- Unit: "ml"
Step 6: Create Recipe Items (Link Ingredients to Recipes)¶
Recipe: "Margherita Pizza Recipe"
- RecipeItem: "Flour" - Quantity: 500g
- RecipeItem: "Tomato Sauce" - Quantity: 100ml
- RecipeItem: "Mozzarella Cheese" - Quantity: 200g
- RecipeItem: "Fresh Basil" - Quantity: 10g
Recipe: "Butter Chicken Recipe"
- RecipeItem: "Chicken Breast" - Quantity: 300g
- RecipeItem: "Tomato Sauce" - Quantity: 200ml
- RecipeItem: "Butter" - Quantity: 50g
- RecipeItem: "Cream" - Quantity: 100ml
- RecipeItem: "Spices Mix" - Quantity: 20g
Step 7: Create Menu Items¶
MenuItem 1: "Margherita Pizza"
- CategoryId: "Pizzas" (Category 1)
- RecipeId: "Margherita Pizza Recipe" (Recipe 1)
- PriceExcludingTaxes: $12.99 (base price for Medium)
- Description: "Classic pizza with tomato, mozzarella, and basil"
- PluCode: "PIZ001"
- ImageUrl: "/images/margherita.jpg"
- KitchenDescription: "12-inch base, fresh mozzarella, basil garnish"
- Order: 1
- IsOptional: true (can add toppings)
MenuItem 2: "Butter Chicken"
- CategoryId: "Indian Curries" (Category 2)
- RecipeId: "Butter Chicken Recipe" (Recipe 2)
- PriceExcludingTaxes: $15.99
- Description: "Creamy tomato-based curry with tender chicken"
- PluCode: "CUR001"
- ImageUrl: "/images/butter-chicken.jpg"
- KitchenDescription: "Medium spice, serve with basmati rice"
- Order: 1
- IsOptional: true (can add sides)
Step 8: Link Variants to Menu Items¶
MenuItem: "Margherita Pizza"
- MenuItemVariant: "Pizza Size" (REQUIRED)
- MenuItemVariantValue: "Small" - PriceAdjustment: -$2.00 (total: $10.99)
- MenuItemVariantValue: "Medium" - PriceAdjustment: $0.00 (total: $12.99) [DEFAULT]
- MenuItemVariantValue: "Large" - PriceAdjustment: +$3.00 (total: $15.99)
- MenuItemVariantValue: "Extra Large" - PriceAdjustment: +$5.00 (total: $17.99)
- MenuItemVariant: "Crust Type" (REQUIRED)
- MenuItemVariantValue: "Thin Crust" - PriceAdjustment: $0.00 [DEFAULT]
- MenuItemVariantValue: "Thick Crust" - PriceAdjustment: +$1.00
- MenuItemVariantValue: "Stuffed Crust" - PriceAdjustment: +$2.50
MenuItem: "Butter Chicken"
- MenuItemVariant: "Spice Level" (REQUIRED)
- MenuItemVariantValue: "Mild" - PriceAdjustment: $0.00 [DEFAULT]
- MenuItemVariantValue: "Medium" - PriceAdjustment: $0.00
- MenuItemVariantValue: "Hot" - PriceAdjustment: $0.00
- MenuItemVariantValue: "Extra Hot" - PriceAdjustment: $0.00
Step 9: Link Options to Menu Items¶
MenuItem: "Margherita Pizza"
- MenuItemOptionMap: "Pizza Toppings" (OPTIONAL, IsRequired: false)
- Customer can add: Extra Cheese, Pepperoni, Mushrooms, Olives, Bell Peppers
- Each topping adds to the price
MenuItem: "Butter Chicken"
- MenuItemOptionMap: "Extra Sides" (OPTIONAL, IsRequired: false)
- Customer can add: Garlic Naan, Basmati Rice, Raita
- Each side adds to the price
Step 10: Set Store-Specific Optional Item Availability¶
Store: "Pizza Palace - Downtown"
- StoreOptionalItemMap: "Extra Cheese" - IsActive: true
- StoreOptionalItemMap: "Pepperoni" - IsActive: true
- StoreOptionalItemMap: "Garlic Naan" - IsActive: true
- StoreOptionalItemMap: "Basmati Rice" - IsActive: true
Store: "Pizza Palace - Airport" (smaller store)
- StoreOptionalItemMap: "Extra Cheese" - IsActive: true
- StoreOptionalItemMap: "Pepperoni" - IsActive: false (not available)
- StoreOptionalItemMap: "Garlic Naan" - IsActive: false (not available)
Step 11: Set Day-Based Availability¶
MenuItem: "Butter Chicken"
- MenuItemAvailabilityByDay:
- Monday: Available 11:00 AM - 10:00 PM
- Tuesday: Available 11:00 AM - 10:00 PM
- Wednesday: Available 11:00 AM - 10:00 PM
- Thursday: Available 11:00 AM - 10:00 PM
- Friday: Available 11:00 AM - 11:00 PM (extended hours)
- Saturday: Available 11:00 AM - 11:00 PM
- Sunday: Not Available (restaurant closed)
Step 12: Create Menu Revisions¶
MenuRevision 1: "Downtown Store - Full Menu"
- BrandId: Pizza Palace
- ProfileId: FullMenuProfile
- Contains: All items (Pizza + Butter Chicken)
MenuRevision 2: "Airport Store - Pizza Only"
- BrandId: Pizza Palace
- ProfileId: LimitedMenuProfile
- Contains: Only Pizza items (no Butter Chicken)
Step 13: Activate Menu at Stores¶
Store 1: "Pizza Palace - Downtown"
- Active MenuRevision: "Downtown Store - Full Menu"
- Customers see: Both Pizza and Butter Chicken
Store 2: "Pizza Palace - Airport"
- Active MenuRevision: "Airport Store - Pizza Only"
- Customers see: Only Pizza (Butter Chicken hidden)
Entity Relationships¶
Brand (1) ──→ (Many) Store
Brand (1) ──→ (Many) Category
Brand (1) ──→ (Many) Recipe
Brand (1) ──→ (Many) MenuItem
Brand (1) ──→ (Many) MenuRevision
Brand (1) ──→ (Many) Variant
Brand (1) ──→ (Many) Option
Brand (1) ──→ (Many) StockItem
Category (1) ──→ (Many) MenuItem
Recipe (1) ──→ (Many) MenuItem
StockCategory (1) ──→ (Many) StockItem
UnitOfMeasure (1) ──→ (Many) StockItem
Variant (1) ──→ (Many) VariantValue
VariantOperationType (1) ──→ (Many) Variant
MenuItem (1) ──→ (Many) MenuItemVariant
MenuItemVariant (1) ──→ (Many) MenuItemVariantValue
MenuItemVariantValue (1) ──→ (1) VariantValue
MenuItem (1) ──→ (Many) MenuItemRequiredVariant
MenuItemRequiredVariant (1) ──→ (Many) MenuItemRequiredVariantValue
MenuItemRequiredVariantValue (1) ──→ (1) VariantValue
Option (1) ──→ (Many) OptionItem
OptionOperationType (1) ──→ (Many) Option
PriceDisplay (1) ──→ (Many) Option
MenuItem (1) ──→ (Many) MenuItemOptionMap
MenuItemOptionMap (1) ──→ (1) Option
OptionItem (1) ──→ (1) MenuItem (the item being offered as an option)
Recipe (1) ──→ (Many) RecipeRevision
RecipeRevision (1) ──→ (Many) RecipeItem
RecipeItem (1) ──→ (1) StockItem
MenuItem (1) ──→ (Many) MenuItemAvailabilityByDay
MenuItem (1) ──→ (Many) MenuItemTaxRateMap
MenuItem (1) ──→ (Many) MenuItemRoyaltyMap
MenuItem (1) ──→ (Many) MenuItemProductionRoleMap
MenuRevision (1) ──→ (Many) StoreMenuNotificationStatus
Store (1) ──→ (Many) StoreMenuNotificationStatus
Store (1) ──→ (Many) StoreOptionalItemMap
MenuItem (1) ──→ (Many) StoreOptionalItemMap
Key Features¶
- Hierarchical Organization: Brand → Category → MenuItem
- Recipe Management: Separate recipes from menu items (one recipe can be used by multiple items)
- Menu Versioning: Different menu revisions for different stores/profiles
- Store-Specific Control: Each store can have different menu items available
- Variants (Required Choices): Menu items can have required variations (size, crust type, spice level) with price adjustments
- Options (Optional Add-ons): Menu items can have optional add-ons/modifiers (toppings, sides) with additional pricing
- Inventory Integration: Recipes link to stock items for ingredient tracking
- Pricing Flexibility: Base price + variant price adjustments + option prices
- Day-Based Availability: Control when items are available (specific days/times)
- Tax & Royalty Management: Link items to tax rates and royalty configurations
- Kitchen Role Assignment: Assign which kitchen stations can prepare items
- Visibility Control: Hide items on transactions/invoices if needed
- Ordering: Control display order of categories and items
Complete Workflow Example¶
- Admin creates Brand: "Pizza Palace"
- Admin creates Stock Items: Ingredients (flour, cheese, chicken, etc.)
- Admin creates Stock Categories: "Dairy", "Meat", "Sauces", etc.
- Admin creates Variants: "Pizza Size", "Crust Type", "Spice Level"
- Admin creates Variant Values: "Small/Medium/Large", "Thin/Thick/Stuffed", "Mild/Medium/Hot"
- Admin creates Options: "Pizza Toppings", "Extra Sides"
- Admin creates Option Items: "Extra Cheese", "Pepperoni", "Garlic Naan", etc. (these are MenuItems)
- Admin creates Categories: "Pizzas", "Indian Curries"
- Admin creates Recipes: "Margherita Recipe", "Butter Chicken Recipe"
- Admin creates Recipe Items: Links ingredients (StockItems) to recipes with quantities
- Admin creates Menu Items: Links items to categories and recipes, sets base prices
- Admin links Variants to Menu Items: Assigns required variants (size, crust) with price adjustments
- Admin links Options to Menu Items: Assigns optional add-ons (toppings, sides)
- Admin sets Store-Specific Availability: Controls which optional items are available at each store
- Admin sets Day-Based Availability: Controls when items are available
- Admin creates Menu Revisions: Different menu versions
- Admin assigns Menu Revisions to Stores: Each store gets appropriate menu
- Store activates Menu Revision: Menu goes live at that store
-
Customers order:
- Select menu item (e.g., "Margherita Pizza")
- MUST choose required variants (Size: Large, Crust: Thick) - price adjusts
- CAN choose optional add-ons (Toppings: Extra Cheese +$1.50, Pepperoni +$2.00)
- Final price = Base + Variant adjustments + Option prices
Complete Customer Order Example¶
Scenario: Customer Orders "Margherita Pizza" with Variants and Options¶
Step 1: Customer Selects Menu Item
- MenuItem: "Margherita Pizza"
- Base Price: $12.99 (for Medium size)
Step 2: Customer MUST Choose Required Variants
-
Variant: "Pizza Size" (REQUIRED - Single Select)
- Customer selects: "Large"
- Price Adjustment: +$3.00
- Running Total: $12.99 + $3.00 = $15.99
-
Variant: "Crust Type" (REQUIRED - Single Select)
- Customer selects: "Stuffed Crust"
- Price Adjustment: +$2.50
- Running Total: $15.99 + $2.50 = $18.49
Step 3: Customer CAN Choose Optional Options
-
Option: "Pizza Toppings" (OPTIONAL - Multi Select)
- Customer selects: "Extra Cheese" (+$1.50)
- Customer selects: "Pepperoni" (+$2.00)
- Running Total: $18.49 + $1.50 + $2.00 = $22.99
Final Order:
- Item: Margherita Pizza
- Size: Large (+$3.00)
- Crust: Stuffed Crust (+$2.50)
- Toppings: Extra Cheese (+$1.50), Pepperoni (+$2.00)
- Total Price: $22.99
Scenario: Customer Orders "Butter Chicken" with Variants and Options¶
Step 1: Customer Selects Menu Item
- MenuItem: "Butter Chicken"
- Base Price: $15.99
Step 2: Customer MUST Choose Required Variant
-
Variant: "Spice Level" (REQUIRED - Single Select)
- Customer selects: "Hot"
- Price Adjustment: $0.00 (no extra charge)
- Running Total: $15.99
Step 3: Customer CAN Choose Optional Options
-
Option: "Extra Sides" (OPTIONAL - Multi Select)
- Customer selects: "Garlic Naan" (+$3.00)
- Customer selects: "Basmati Rice" (+$2.50)
- Running Total: $15.99 + $3.00 + $2.50 = $21.49
Final Order:
- Item: Butter Chicken
- Spice Level: Hot
- Sides: Garlic Naan (+$3.00), Basmati Rice (+$2.50)
- Total Price: $21.49
Benefits¶
- Centralized Management: Manage all menu items at brand level
- Flexibility: Different stores can have different menus
- Consistency: Recipes ensure consistent preparation
- Scalability: Easy to add new items, categories, or stores
- Control: Fine-grained control over what's available where
- Variants System: Required choices (size, type) with price adjustments
- Options System: Optional add-ons (toppings, sides) with flexible pricing
- Inventory Integration: Track ingredients through recipes and stock items
- Pricing Flexibility: Base price + variant adjustments + option prices
- Time-Based Control: Day and time-based availability
Updated by Redmine Admin about 12 hours ago
- Tracker changed from Task to Feature
- Description updated (diff)