Enhance: Replace All now clears orders + Auto-creates categories

- 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
This commit is contained in:
SysAdmin 2025-10-08 16:01:21 +01:00
parent 4f591418df
commit daa59e3271
2 changed files with 218 additions and 7 deletions

View File

@ -53,9 +53,15 @@ public class ProductImportService : IProductImportService
// Replace all existing data if requested // Replace all existing data if requested
if (replaceAll) if (replaceAll)
{ {
_logger.LogWarning("REPLACE ALL: Deleting all existing products, variants, and categories"); _logger.LogWarning("REPLACE ALL: Deleting all existing orders, sales data, products, and categories");
var deletedCount = await DeleteAllProductsAndCategoriesAsync();
_logger.LogInformation("Deleted {Count} existing records", deletedCount); // 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); var lines = csvText.Split('\n', StringSplitOptions.RemoveEmptyEntries);
@ -381,9 +387,15 @@ public class ProductImportService : IProductImportService
// Replace all existing data if requested // Replace all existing data if requested
if (replaceAll) if (replaceAll)
{ {
_logger.LogWarning("REPLACE ALL: Deleting all existing products, variants, and categories"); _logger.LogWarning("REPLACE ALL: Deleting all existing orders, sales data, products, and categories");
var deletedCount = await DeleteAllProductsAndCategoriesAsync();
_logger.LogInformation("Deleted {Count} existing records", deletedCount); // 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)) if (string.IsNullOrWhiteSpace(textContent))
@ -406,8 +418,39 @@ public class ProductImportService : IProductImportService
.ToListAsync(); .ToListAsync();
var variantCollections = variantCollectionsList.ToDictionary(vc => vc.Name, vc => vc.Id, StringComparer.OrdinalIgnoreCase); 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 productBlocks = SplitIntoProductBlocks(textContent);
var uniqueCategoryNames = new HashSet<string>(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; result.TotalRows = productBlocks.Count;
for (int i = 0; i < productBlocks.Count; i++) for (int i = 0; i < productBlocks.Count; i++)

168
products_import_ready.txt Normal file
View File

@ -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
<text>
Will come as a organic
</text>
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
<text>
Dutch import
</text>
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
<text>
25mg RAW organic capsules 🔥VEGAN🔥
</text>
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
<text>
(Very very VEGAN 0.025g max per hit, take orally)
</text>
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