# 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 ```csv Name,Description,Price,Weight,WeightUnit,StockQuantity,CategoryName,IsActive,Variations,PhotoUrls ``` ### Product Base Price and Stock - Set `Price` to **0** if using variants (variant prices override base price) - Set `StockQuantity` to **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:** ```csv "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:** ```csv "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:** ```csv "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 1. **Semicolon Detection**: If the Variations column contains semicolons (`;`), it's treated as ProductVariant format 2. **Colon-Only Format**: If only colons (`:`) are present, it's treated as legacy ProductMultiBuy format 3. **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: 1. Delete existing products with incorrect MultiBuy data 2. Re-import using the corrected pipe-delimited format shown above 3. Ensure product base `Price` is set to 0 when using variants ## Order Creation When customers order products with variants: - **TeleBot** automatically passes the `ProductVariantId` to the order API - **OrderService** uses the variant's `Price` property to calculate the order total - If variant `Price` is 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 format - `ImportProductMultiBuysAsync()`: Handles legacy colon-delimited multi-buy format - Detection logic at line ~239