Implement product variant selection in TeleBot
FEATURES IMPLEMENTED: 1. Enhanced Product Display: - Shows multi-buy deals with pricing (e.g., "3 for £25") - Displays available variants grouped by type (Color, Flavor, etc.) - Clear visual separation between multi-buys and variants 2. Variant Selection Flow: - Single item: Select one variant from available options - Multi-buy bundles: Select individual variants for each item - Example: 3-pack allows choosing Red, Blue, Green individually - Visual feedback with checkmarks and counters 3. Smart Cart Management: - Tracks selected variants for each cart item - Supports both single variant (regular items) and multiple variants (multi-buys) - Unique cart entries based on product + variant combination - Prevents duplicate multi-buy bundles 4. User Experience Improvements: - Clear "Select Color/Flavor" prompts - Progress indicator for multi-item selection - Confirm button appears when selection complete - Clear selection option for multi-buys - Back navigation preserves context TECHNICAL CHANGES: - ProductCarouselService: Enhanced caption formatting with variants/multi-buys - MenuBuilder: New VariantSelectionMenu with dynamic button generation - CallbackHandler: Added handlers for selectvar, setvariant, addvariant, confirmvar - ShoppingCart: New AddItem overload accepting Product and variant list - CartItem: Added SelectedVariants list for multi-buy support - UserSession: Added SelectingVariants state This update enables customers to: - See all available product options at a glance - Choose specific variants when ordering - Mix and match variants in multi-buy deals - Get exactly what they want with clear visual feedback Next steps: Add bot activity tracking for live dashboard 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LittleShop.Client.Models;
|
||||
|
||||
namespace TeleBot.Models
|
||||
{
|
||||
@@ -11,6 +12,64 @@ namespace TeleBot.Models
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// New method that accepts Product and variants list
|
||||
public CartItem AddItem(Product product, int quantity = 1, Guid? multiBuyId = null, List<string>? selectedVariants = null)
|
||||
{
|
||||
decimal price = product.Price;
|
||||
|
||||
// If multi-buy selected, get the multi-buy price
|
||||
if (multiBuyId.HasValue && product.MultiBuys != null)
|
||||
{
|
||||
var multiBuy = product.MultiBuys.FirstOrDefault(mb => mb.Id == multiBuyId.Value);
|
||||
if (multiBuy != null)
|
||||
{
|
||||
price = multiBuy.Price;
|
||||
quantity = multiBuy.Quantity; // Use the multi-buy quantity
|
||||
}
|
||||
}
|
||||
|
||||
// Create unique key for comparison
|
||||
var variantKey = selectedVariants != null && selectedVariants.Any()
|
||||
? string.Join(",", selectedVariants.OrderBy(v => v))
|
||||
: null;
|
||||
|
||||
// Check if item already exists
|
||||
var existingItem = Items.FirstOrDefault(i =>
|
||||
i.ProductId == product.Id &&
|
||||
i.MultiBuyId == multiBuyId &&
|
||||
(i.SelectedVariant == variantKey ||
|
||||
(i.SelectedVariants != null && string.Join(",", i.SelectedVariants.OrderBy(v => v)) == variantKey)));
|
||||
|
||||
if (existingItem != null)
|
||||
{
|
||||
// For multi-buys, we don't add quantities - each multi-buy is a separate bundle
|
||||
if (!multiBuyId.HasValue)
|
||||
{
|
||||
existingItem.Quantity += quantity;
|
||||
existingItem.UpdateTotalPrice();
|
||||
}
|
||||
return existingItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
var newItem = new CartItem
|
||||
{
|
||||
ProductId = product.Id,
|
||||
MultiBuyId = multiBuyId,
|
||||
SelectedVariant = selectedVariants?.Count == 1 ? selectedVariants[0] : null,
|
||||
SelectedVariants = selectedVariants ?? new List<string>(),
|
||||
ProductName = product.Name,
|
||||
UnitPrice = price,
|
||||
Quantity = quantity
|
||||
};
|
||||
newItem.UpdateTotalPrice();
|
||||
Items.Add(newItem);
|
||||
UpdatedAt = DateTime.UtcNow;
|
||||
return newItem;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the old method for backward compatibility
|
||||
public void AddItem(Guid productId, string productName, decimal price, int quantity = 1, Guid? multiBuyId = null, string? selectedVariant = null)
|
||||
{
|
||||
var existingItem = Items.FirstOrDefault(i =>
|
||||
@@ -96,7 +155,8 @@ namespace TeleBot.Models
|
||||
{
|
||||
public Guid ProductId { get; set; }
|
||||
public Guid? MultiBuyId { get; set; } // For quantity pricing (e.g., 3 for £25)
|
||||
public string? SelectedVariant { get; set; } // For color/flavor selection
|
||||
public string? SelectedVariant { get; set; } // For single items - one variant
|
||||
public List<string> SelectedVariants { get; set; } = new(); // For multi-buys - multiple variants
|
||||
public string ProductName { get; set; } = string.Empty;
|
||||
public int Quantity { get; set; }
|
||||
public decimal UnitPrice { get; set; } // For multi-buys, this is the bundle price; for regular items, it's per-unit
|
||||
|
||||
@@ -92,6 +92,7 @@ namespace TeleBot.Models
|
||||
BrowsingCategories,
|
||||
ViewingProducts,
|
||||
ViewingProduct,
|
||||
SelectingVariants,
|
||||
ViewingCart,
|
||||
CheckoutFlow,
|
||||
ViewingOrders,
|
||||
|
||||
Reference in New Issue
Block a user