Add variant collections system and enhance ProductVariant with weight/stock tracking
This commit introduces a comprehensive variant management system and enhances the existing ProductVariant model with per-variant weight overrides and stock tracking, integrated across Admin Panel and TeleBot. Features Added: - Variant Collections: Reusable variant templates (e.g., "Standard Sizes") - Admin UI for managing variant collections (CRUD operations) - Dynamic variant editor with JavaScript-based UI - Per-variant weight and weight unit overrides - Per-variant stock level tracking - SalesLedger model for financial tracking ProductVariant Enhancements: - Added Weight (decimal, nullable) field for variant-specific weights - Added WeightUnit (enum, nullable) field for variant-specific units - Maintains backward compatibility with product-level weights TeleBot Integration: - Enhanced variant selection UI to display stock levels - Shows weight information with proper unit conversion (µg, g, oz, lb, ml, L) - Compact button format: "Medium (15 in stock, 350g)" - Real-time stock availability display Database Migrations: - 20250928014850_AddVariantCollectionsAndSalesLedger - 20250928155814_AddWeightToProductVariants Technical Changes: - Updated Product model to support VariantCollectionId and VariantsJson - Extended ProductService with variant collection operations - Enhanced OrderService to handle variant-specific pricing and weights - Updated LittleShop.Client DTOs to match server models - Added JavaScript dynamic variant form builder Files Modified: 15 Files Added: 17 Lines Changed: ~2000 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -376,11 +376,44 @@ namespace TeleBot.UI
|
||||
var variantButtons = new List<InlineKeyboardButton>();
|
||||
foreach (var variant in group.OrderBy(v => v.SortOrder))
|
||||
{
|
||||
string variantInfo = "";
|
||||
|
||||
if (variant.StockLevel > 0)
|
||||
{
|
||||
variantInfo = $" ({variant.StockLevel} in stock";
|
||||
}
|
||||
else if (variant.StockLevel == 0)
|
||||
{
|
||||
variantInfo = " (Out of stock";
|
||||
}
|
||||
|
||||
if (variant.Weight.HasValue)
|
||||
{
|
||||
var unitName = variant.WeightUnit switch
|
||||
{
|
||||
1 => "µg",
|
||||
2 => "g",
|
||||
3 => "oz",
|
||||
4 => "lb",
|
||||
5 => "ml",
|
||||
6 => "L",
|
||||
_ => "unit"
|
||||
};
|
||||
variantInfo += variantInfo == "" ? $" ({variant.Weight}{unitName}" : $", {variant.Weight}{unitName}";
|
||||
}
|
||||
|
||||
if (variantInfo != "")
|
||||
{
|
||||
variantInfo += ")";
|
||||
}
|
||||
|
||||
// For multi-buy, allow multiple selections
|
||||
if (quantity > 1)
|
||||
{
|
||||
var count = selectedVariants.Count(v => v == variant.Name);
|
||||
var buttonText = count > 0 ? $"{variant.Name} ({count})" : variant.Name;
|
||||
var buttonText = count > 0
|
||||
? $"{variant.Name} ({count}){variantInfo}"
|
||||
: $"{variant.Name}{variantInfo}";
|
||||
|
||||
variantButtons.Add(InlineKeyboardButton.WithCallbackData(
|
||||
buttonText,
|
||||
@@ -391,7 +424,9 @@ namespace TeleBot.UI
|
||||
{
|
||||
// Single item, select one variant
|
||||
var isSelected = selectedVariants.Contains(variant.Name);
|
||||
var buttonText = isSelected ? $"✅ {variant.Name}" : variant.Name;
|
||||
var buttonText = isSelected
|
||||
? $"✅ {variant.Name}{variantInfo}"
|
||||
: $"{variant.Name}{variantInfo}";
|
||||
|
||||
variantButtons.Add(InlineKeyboardButton.WithCallbackData(
|
||||
buttonText,
|
||||
|
||||
Reference in New Issue
Block a user