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:
@@ -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<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;
|
||||
|
||||
for (int i = 0; i < productBlocks.Count; i++)
|
||||
|
||||
Reference in New Issue
Block a user