CRITICAL BUG FIX: Orders were totaling £0 because imported products had: - Base price set to £0 - Variants stored as ProductMultiBuys (not ProductVariants) - Order creation couldn't find variant prices → used base price of £0 Changes: - CSV import now detects format: semicolons (;) = variants, colons (:) = multi-buys - Added ImportProductVariantsAsync() to handle pipe-delimited variant format - Format: "value; price; stock|value; price; stock" (e.g., "10; 30.00; 100|25; 70.00; 50") - Updated CSV export to prioritize ProductVariants over MultiBuys - Updated CSV template with correct variant format examples - Added comprehensive documentation in VARIANT_CSV_FORMAT.md Migration Required: - Existing products with incorrect MultiBuy data need re-import - Convert format from "name:qty:price;name:qty:price" to "value; price; stock|value; price; stock" - Ensure base price is 0 for variant-based products 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
3.6 KiB
Product Variant CSV Import Format
Overview
As of the latest update, the CSV import system now correctly creates ProductVariant records instead of ProductMultiBuy records when using semicolon-delimited variations.
CSV Column Format
Name,Description,Price,Weight,WeightUnit,StockQuantity,CategoryName,IsActive,Variations,PhotoUrls
Product Base Price and Stock
- Set
Priceto 0 if using variants (variant prices override base price) - Set
StockQuantityto 0 if using variants (variant stock is tracked separately)
Variations Column Format
ProductVariant Format (Recommended)
Use pipe | to separate multiple variants, semicolons ; to separate the three required parts:
"value; price; stock|value; price; stock|value; price; stock"
Format Components:
value: Variant name/value (e.g., "10", "25", "3.5g", "7g")price: Price for this variant as decimal (e.g., 30.00)stock: Stock level for this variant as integer (e.g., 100)
Example - Quantity-based variants:
"Buprenorphine 2mg",0,150,Grams,0,Pharmaceuticals,true,"10; 30.00; 100|25; 70.00; 50|50; 130.00; 25",""
This creates:
- Variant "10" at £30.00 with 100 in stock
- Variant "25" at £70.00 with 50 in stock
- Variant "50" at £130.00 with 25 in stock
Example - Weight-based variants:
"Cannabis Flower",0,200,Grams,0,Botanicals,true,"3.5g; 35.00; 10|7g; 65.00; 8|14g; 120.00; 5",""
This creates:
- Variant "3.5g" at £35.00 with 10 in stock
- Variant "7g" at £65.00 with 8 in stock
- Variant "14g" at £120.00 with 5 in stock
Legacy ProductMultiBuy Format (Still Supported)
Old multi-buy format using colons : (no semicolons):
"Name:Quantity:Price;Name:Quantity:Price"
Example:
"Example Product",29.99,150,Grams,50,Electronics,true,"Single:1:29.99;Twin Pack:2:55.00",""
Variant Type Detection
The system automatically determines variant type based on the value:
- Contains "g" (grams): Weight variant type
- Otherwise: Quantity variant type
CSV Import Behavior
- Semicolon Detection: If the Variations column contains semicolons (
;), it's treated as ProductVariant format - Colon-Only Format: If only colons (
:) are present, it's treated as legacy ProductMultiBuy format - Empty Variations: Product uses base Price and StockQuantity
Exporting Products
When exporting products to CSV:
- Products with ProductVariants export in the pipe-delimited format:
"value; price; stock|value; price; stock" - Products with ProductMultiBuys export in the legacy colon format:
"name:qty:price;name:qty:price"
Template Download
Download the CSV template from Admin Panel → Products → Import CSV → Download Template to see the correct format with examples.
Migration from Old Format
If you previously imported products using the old format (semicolons but creating MultiBuys), you'll need to:
- Delete existing products with incorrect MultiBuy data
- Re-import using the corrected pipe-delimited format shown above
- Ensure product base
Priceis set to 0 when using variants
Order Creation
When customers order products with variants:
- TeleBot automatically passes the
ProductVariantIdto the order API - OrderService uses the variant's
Priceproperty to calculate the order total - If variant
Priceis null, it falls back to product base price (which should be 0 for variant-based products)
Technical Implementation
See ProductImportService.cs:
ImportProductVariantsAsync(): Handles pipe-delimited variant formatImportProductMultiBuysAsync(): Handles legacy colon-delimited multi-buy format- Detection logic at line ~239