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:
parent
4f591418df
commit
daa59e3271
@ -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
168
products_import_ready.txt
Normal 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
|
||||||
Loading…
Reference in New Issue
Block a user