Domain (foodmarket.Domain.Catalog): - Global references: Country (ISO-2), Currency (ISO-3 + symbol + minor unit) - Tenant references: VatRate (Percent + IncludedInPrice + IsDefault), UnitOfMeasure (ОКЕИ code + DecimalPlaces) - Counterparty: kind (Supplier/Customer/Both), type (Legal/Individual), BIN/IIN/TaxNumber, bank details - Store + RetailPoint with fiscal placeholders - ProductGroup: hierarchy via ParentId + denormalized Path - PriceType (Розничная/Оптовая), Product (article, VAT, group, supplier, flags IsService/IsWeighed/IsAlcohol/IsMarked, min/max stock) - ProductPrice (composite unique product+priceType), ProductBarcode (EAN13/EAN8/CODE128/UPC), ProductImage Infrastructure: - CatalogConfigurations with fluent API (indexes, precision 18/4 for money, FK with Restrict) - 13 new DbSets on AppDbContext + builder.ConfigureCatalog() - Migration Phase1Catalog — adds countries, currencies, vat_rates, units_of_measure, counterparties, stores, retail_points, product_groups, price_types, products, product_prices, product_barcodes, product_images Seeders: - SystemReferenceSeeder (always): 12 countries (KZ, RU, CN, TR, …), 5 currencies (KZT primary, RUB, USD, EUR, CNY) - DevDataSeeder extended: for Demo Market seeds VAT (0%, 12% default+included), units (шт/кг/л/м/уп), price types (Розничная default, Оптовая), main store, POS-1 Total DB schema: 26 tables. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
79 lines
3.1 KiB
C#
79 lines
3.1 KiB
C#
using foodmarket.Domain.Catalog;
|
|
using foodmarket.Infrastructure.Persistence;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace foodmarket.Api.Seed;
|
|
|
|
// Seeds global reference data (countries, currencies). Runs in all environments.
|
|
public class SystemReferenceSeeder : IHostedService
|
|
{
|
|
private readonly IServiceProvider _services;
|
|
|
|
public SystemReferenceSeeder(IServiceProvider services)
|
|
{
|
|
_services = services;
|
|
}
|
|
|
|
public async Task StartAsync(CancellationToken ct)
|
|
{
|
|
using var scope = _services.CreateScope();
|
|
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
|
|
await SeedCountriesAsync(db, ct);
|
|
await SeedCurrenciesAsync(db, ct);
|
|
await db.SaveChangesAsync(ct);
|
|
}
|
|
|
|
public Task StopAsync(CancellationToken ct) => Task.CompletedTask;
|
|
|
|
private static async Task SeedCountriesAsync(AppDbContext db, CancellationToken ct)
|
|
{
|
|
// Kazakhstan first, then common trade partners.
|
|
var wanted = new[]
|
|
{
|
|
new Country { Code = "KZ", Name = "Казахстан", SortOrder = 1 },
|
|
new Country { Code = "RU", Name = "Россия", SortOrder = 2 },
|
|
new Country { Code = "CN", Name = "Китай", SortOrder = 3 },
|
|
new Country { Code = "TR", Name = "Турция", SortOrder = 4 },
|
|
new Country { Code = "BY", Name = "Беларусь", SortOrder = 5 },
|
|
new Country { Code = "UZ", Name = "Узбекистан", SortOrder = 6 },
|
|
new Country { Code = "KG", Name = "Кыргызстан", SortOrder = 7 },
|
|
new Country { Code = "DE", Name = "Германия", SortOrder = 10 },
|
|
new Country { Code = "US", Name = "США", SortOrder = 11 },
|
|
new Country { Code = "KR", Name = "Южная Корея", SortOrder = 12 },
|
|
new Country { Code = "IT", Name = "Италия", SortOrder = 13 },
|
|
new Country { Code = "PL", Name = "Польша", SortOrder = 14 },
|
|
};
|
|
|
|
var existingCodes = await db.Countries.Select(c => c.Code).ToListAsync(ct);
|
|
foreach (var c in wanted)
|
|
{
|
|
if (!existingCodes.Contains(c.Code))
|
|
{
|
|
db.Countries.Add(c);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static async Task SeedCurrenciesAsync(AppDbContext db, CancellationToken ct)
|
|
{
|
|
var wanted = new[]
|
|
{
|
|
new Currency { Code = "KZT", Name = "Тенге", Symbol = "₸", MinorUnit = 2 },
|
|
new Currency { Code = "RUB", Name = "Российский рубль", Symbol = "₽", MinorUnit = 2 },
|
|
new Currency { Code = "USD", Name = "Доллар США", Symbol = "$", MinorUnit = 2 },
|
|
new Currency { Code = "EUR", Name = "Евро", Symbol = "€", MinorUnit = 2 },
|
|
new Currency { Code = "CNY", Name = "Китайский юань", Symbol = "¥", MinorUnit = 2 },
|
|
};
|
|
|
|
var existingCodes = await db.Currencies.Select(c => c.Code).ToListAsync(ct);
|
|
foreach (var c in wanted)
|
|
{
|
|
if (!existingCodes.Contains(c.Code))
|
|
{
|
|
db.Currencies.Add(c);
|
|
}
|
|
}
|
|
}
|
|
}
|