From daa59e32716f8b67dce6cb0e1733630ae63089d7 Mon Sep 17 00:00:00 2001 From: SysAdmin Date: Wed, 8 Oct 2025 16:01:21 +0100 Subject: [PATCH] Enhance: Replace All now clears orders + Auto-creates categories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace All option now deletes ALL sales data (orders, payments, customers, messages) - Auto-create missing categories in text import (same as CSV import) - Deletes in proper order: sales data → products → categories - Ensures clean slate for complete catalog replacement - Add formatted product import file with variant collections Changes: - ImportFromTextAsync: Delete sales + products when replaceAll=true - ImportFromHumanTextAsync: Auto-create categories + delete sales data - Regex parsing to extract category names before import - Enhanced logging for deletion operations --- LittleShop/Services/ProductImportService.cs | 57 ++++++- products_import_ready.txt | 168 ++++++++++++++++++++ 2 files changed, 218 insertions(+), 7 deletions(-) create mode 100644 products_import_ready.txt diff --git a/LittleShop/Services/ProductImportService.cs b/LittleShop/Services/ProductImportService.cs index acb35d7..ed8994c 100644 --- a/LittleShop/Services/ProductImportService.cs +++ b/LittleShop/Services/ProductImportService.cs @@ -53,9 +53,15 @@ public class ProductImportService : IProductImportService // Replace all existing data if requested if (replaceAll) { - _logger.LogWarning("REPLACE ALL: Deleting all existing products, variants, and categories"); - var deletedCount = await DeleteAllProductsAndCategoriesAsync(); - _logger.LogInformation("Deleted {Count} existing records", deletedCount); + _logger.LogWarning("REPLACE ALL: Deleting all existing orders, sales data, products, and categories"); + + // Delete orders and sales data first + var salesDeleted = await DeleteAllOrdersAndSalesDataAsync(); + _logger.LogInformation("Deleted {Count} sales records", salesDeleted); + + // Then delete products and categories + var productDeleted = await DeleteAllProductsAndCategoriesAsync(); + _logger.LogInformation("Deleted {Count} product records", productDeleted); } var lines = csvText.Split('\n', StringSplitOptions.RemoveEmptyEntries); @@ -381,9 +387,15 @@ public class ProductImportService : IProductImportService // Replace all existing data if requested if (replaceAll) { - _logger.LogWarning("REPLACE ALL: Deleting all existing products, variants, and categories"); - var deletedCount = await DeleteAllProductsAndCategoriesAsync(); - _logger.LogInformation("Deleted {Count} existing records", deletedCount); + _logger.LogWarning("REPLACE ALL: Deleting all existing orders, sales data, products, and categories"); + + // Delete orders and sales data first + var salesDeleted = await DeleteAllOrdersAndSalesDataAsync(); + _logger.LogInformation("Deleted {Count} sales records", salesDeleted); + + // Then delete products and categories + var productDeleted = await DeleteAllProductsAndCategoriesAsync(); + _logger.LogInformation("Deleted {Count} product records", productDeleted); } if (string.IsNullOrWhiteSpace(textContent)) @@ -406,8 +418,39 @@ public class ProductImportService : IProductImportService .ToListAsync(); var variantCollections = variantCollectionsList.ToDictionary(vc => vc.Name, vc => vc.Id, StringComparer.OrdinalIgnoreCase); - // Split into product blocks (each starting with #) + // Auto-create categories from text blocks if they don't exist var productBlocks = SplitIntoProductBlocks(textContent); + var uniqueCategoryNames = new HashSet(StringComparer.OrdinalIgnoreCase); + foreach (var block in productBlocks) + { + var categoryMatch = System.Text.RegularExpressions.Regex.Match(block, @"category:\s*(.+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase); + if (categoryMatch.Success) + { + var categoryName = categoryMatch.Groups[1].Value.Trim(); + if (!string.IsNullOrEmpty(categoryName)) + { + uniqueCategoryNames.Add(categoryName); + } + } + } + + // Create missing categories + foreach (var categoryName in uniqueCategoryNames) + { + if (!categoryLookup.ContainsKey(categoryName)) + { + var createCategoryDto = new CreateCategoryDto + { + Name = categoryName, + Description = $"Auto-created category for {categoryName} products" + }; + var newCategory = await _categoryService.CreateCategoryAsync(createCategoryDto); + categoryLookup[categoryName] = newCategory.Id; + _logger.LogInformation("Auto-created category: {CategoryName}", categoryName); + } + } + + // Split into product blocks (each starting with #) result.TotalRows = productBlocks.Count; for (int i = 0; i < productBlocks.Count; i++) diff --git a/products_import_ready.txt b/products_import_ready.txt new file mode 100644 index 0000000..9f0862e --- /dev/null +++ b/products_import_ready.txt @@ -0,0 +1,168 @@ +# Four whittteee; Weights - Standard +category: Flour +price: 100.00 +weight: 3.5 +unit: Grams +stock: 100 + +- 3.5g; 100.00; 100 +- 7g; 190.00; 100 +- 14g; 360.00; 100 + +# double washed Flour; Weights - Standard + +Will come as a organic + +category: Flour +price: 50.00 +weight: 1 +unit: Grams +stock: 100 + +- 1g; 50.00; 100 +- 3.5g; 130.00; 100 +- 7g; 240.00; 100 +- 14g; 460.00; 100 +- 28g; 900.00; 100 + +# Chocolate infused double washed Flour; Weights - Standard +category: Flour +price: 140.00 +weight: 3.5 +unit: Grams +stock: 100 + +- 3.5g; 140.00; 100 +- 7g; 250.00; 100 +- 14g; 470.00; 100 +- 28g; 920.00; 100 + +# Cereal; Weights - Standard +category: Cereal +price: 30.00 +weight: 7 +unit: Grams +stock: 100 + +- 7g; 30.00; 100 +- 14g; 50.00; 100 +- 28g; 80.00; 100 +- 100g; 200.00; 100 + +# Himalayan Cereal Blush; Weights - Standard +category: Cereal +price: 40.00 +weight: 3.5 +unit: Grams +stock: 100 + +- 3.5g; 40.00; 100 +- 7g; 60.00; 100 +- 14g; 100.00; 100 +- 28g; 180.00; 100 + +# Cereal; Weights - Standard +category: Cereal +price: 50.00 +weight: 7 +unit: Grams +stock: 100 + +- 7g; 50.00; 100 +- 14g; 90.00; 100 +- 28g; 160.00; 100 + +# tablets - Vitamin-C; Single Units + +Dutch import + +category: Vitamins +price: 30.00 +weight: 10 +unit: Single +stock: 100 + +- 10; 30.00; 100 +- 25; 50.00; 100 +- 50; 80.00; 100 +- 100; 150.00; 100 + +# tablets Vitamin-B; Single Units + +25mg RAW organic capsules 🔥VEGAN🔥 + +category: Vitamins +price: 40.00 +weight: 10 +unit: Single +stock: 100 + +- 10; 40.00; 100 +- 25; 80.00; 100 +- 50; 150.00; 100 + +# Vitamin-B tablets; Single Units +category: Vitamins +price: 30.00 +weight: 10 +unit: Single +stock: 100 + +- 10; 30.00; 100 +- 25; 50.00; 100 +- 50; 90.00; 100 +- 100; 160.00; 100 + +# Vitamin-B raw organic; Weights - Standard + +(Very very VEGAN 0.025g max per hit, take orally) + +category: Vitamins +price: 60.00 +weight: 0.5 +unit: Grams +stock: 100 + +- 0.5; 60.00; 100 +- 1; 100.00; 100 +- 1.75; 140.00; 100 +- 3.5; 250.00; 100 +- 7; 450.00; 100 +- 14; 860.00; 100 +- 28; 1600.00; 100 + +# N N Guarana; Weights - Standard +category: Herbal +price: 150.00 +weight: 3.5 +unit: Grams +stock: 100 + +- 3.5g; 150.00; 100 +- 7g; 290.00; 100 +- 14g; 550.00; 100 +- 28g; 1000.00; 100 + +# Vitamin-B pyramid gel tabs; Single Units +category: Vitamins +price: 50.00 +weight: 10 +unit: Single +stock: 100 + +- 10; 50.00; 100 +- 25; 80.00; 100 +- 50; 130.00; 100 +- 100; 250.00; 100 + +# aco Guarana tablets 18mg (VEGAN); Weights - Standard +category: Herbal +price: 60.00 +weight: 10 +unit: Single +stock: 100 + +- 10; 60.00; 100 +- 25; 90.00; 100 +- 50; 160.00; 100 +- 100; 300.00; 100 \ No newline at end of file