phase1a: catalog domain (countries, currencies, vat, units, counterparties, stores, retail points, products)
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>
This commit is contained in:
parent
047cf841f2
commit
cb66684134
|
|
@ -95,6 +95,7 @@
|
|||
builder.Services.AddSwaggerGen();
|
||||
|
||||
builder.Services.AddHostedService<OpenIddictClientSeeder>();
|
||||
builder.Services.AddHostedService<SystemReferenceSeeder>();
|
||||
builder.Services.AddHostedService<DevDataSeeder>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using foodmarket.Infrastructure.Identity;
|
||||
using foodmarket.Domain.Catalog;
|
||||
using foodmarket.Domain.Organizations;
|
||||
using foodmarket.Infrastructure.Identity;
|
||||
using foodmarket.Infrastructure.Persistence;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
|
@ -29,7 +30,7 @@ public async Task StartAsync(CancellationToken ct)
|
|||
var userMgr = scope.ServiceProvider.GetRequiredService<UserManager<User>>();
|
||||
var roleMgr = scope.ServiceProvider.GetRequiredService<RoleManager<Role>>();
|
||||
|
||||
foreach (var role in new[] { SystemRoles.Admin, SystemRoles.Manager, SystemRoles.Cashier, SystemRoles.Storekeeper })
|
||||
foreach (var role in new[] { SystemRoles.SuperAdmin, SystemRoles.Admin, SystemRoles.Manager, SystemRoles.Cashier, SystemRoles.Storekeeper })
|
||||
{
|
||||
if (!await roleMgr.RoleExistsAsync(role))
|
||||
{
|
||||
|
|
@ -53,6 +54,8 @@ public async Task StartAsync(CancellationToken ct)
|
|||
await db.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
await SeedTenantReferencesAsync(db, demoOrg.Id, ct);
|
||||
|
||||
const string adminEmail = "admin@food-market.local";
|
||||
var admin = await userMgr.FindByEmailAsync(adminEmail);
|
||||
if (admin is null)
|
||||
|
|
@ -73,5 +76,68 @@ public async Task StartAsync(CancellationToken ct)
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task SeedTenantReferencesAsync(AppDbContext db, Guid orgId, CancellationToken ct)
|
||||
{
|
||||
var anyVat = await db.VatRates.IgnoreQueryFilters().AnyAsync(v => v.OrganizationId == orgId, ct);
|
||||
if (!anyVat)
|
||||
{
|
||||
db.VatRates.AddRange(
|
||||
new VatRate { OrganizationId = orgId, Name = "Без НДС", Percent = 0m, IsDefault = false },
|
||||
new VatRate { OrganizationId = orgId, Name = "НДС 12%", Percent = 12m, IsIncludedInPrice = true, IsDefault = true }
|
||||
);
|
||||
}
|
||||
|
||||
var anyUnit = await db.UnitsOfMeasure.IgnoreQueryFilters().AnyAsync(u => u.OrganizationId == orgId, ct);
|
||||
if (!anyUnit)
|
||||
{
|
||||
db.UnitsOfMeasure.AddRange(
|
||||
new UnitOfMeasure { OrganizationId = orgId, Code = "796", Symbol = "шт", Name = "штука", DecimalPlaces = 0, IsBase = true },
|
||||
new UnitOfMeasure { OrganizationId = orgId, Code = "166", Symbol = "кг", Name = "килограмм", DecimalPlaces = 3 },
|
||||
new UnitOfMeasure { OrganizationId = orgId, Code = "112", Symbol = "л", Name = "литр", DecimalPlaces = 3 },
|
||||
new UnitOfMeasure { OrganizationId = orgId, Code = "006", Symbol = "м", Name = "метр", DecimalPlaces = 3 },
|
||||
new UnitOfMeasure { OrganizationId = orgId, Code = "625", Symbol = "уп", Name = "упаковка", DecimalPlaces = 0 }
|
||||
);
|
||||
}
|
||||
|
||||
var anyPriceType = await db.PriceTypes.IgnoreQueryFilters().AnyAsync(p => p.OrganizationId == orgId, ct);
|
||||
if (!anyPriceType)
|
||||
{
|
||||
db.PriceTypes.AddRange(
|
||||
new PriceType { OrganizationId = orgId, Name = "Розничная", IsDefault = true, IsRetail = true, SortOrder = 1 },
|
||||
new PriceType { OrganizationId = orgId, Name = "Оптовая", SortOrder = 2 }
|
||||
);
|
||||
}
|
||||
|
||||
var mainStore = await db.Stores.IgnoreQueryFilters().FirstOrDefaultAsync(s => s.OrganizationId == orgId && s.IsMain, ct);
|
||||
if (mainStore is null)
|
||||
{
|
||||
mainStore = new Store
|
||||
{
|
||||
OrganizationId = orgId,
|
||||
Name = "Основной склад",
|
||||
Code = "MAIN",
|
||||
Kind = StoreKind.Warehouse,
|
||||
IsMain = true,
|
||||
Address = "Алматы, ул. Пример 1",
|
||||
};
|
||||
db.Stores.Add(mainStore);
|
||||
await db.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
var anyRetail = await db.RetailPoints.IgnoreQueryFilters().AnyAsync(r => r.OrganizationId == orgId, ct);
|
||||
if (!anyRetail)
|
||||
{
|
||||
db.RetailPoints.Add(new RetailPoint
|
||||
{
|
||||
OrganizationId = orgId,
|
||||
Name = "Касса 1",
|
||||
Code = "POS-1",
|
||||
StoreId = mainStore.Id,
|
||||
});
|
||||
}
|
||||
|
||||
await db.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken ct) => Task.CompletedTask;
|
||||
}
|
||||
|
|
|
|||
78
src/food-market.api/Seed/SystemReferenceSeeder.cs
Normal file
78
src/food-market.api/Seed/SystemReferenceSeeder.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/food-market.domain/Catalog/Counterparty.cs
Normal file
25
src/food-market.domain/Catalog/Counterparty.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
public class Counterparty : TenantEntity
|
||||
{
|
||||
public string Name { get; set; } = null!; // отображаемое имя
|
||||
public string? LegalName { get; set; } // полное юридическое имя
|
||||
public CounterpartyKind Kind { get; set; } // Supplier / Customer / Both
|
||||
public CounterpartyType Type { get; set; } // Юрлицо / Физлицо
|
||||
public string? Bin { get; set; } // БИН (для юрлиц РК)
|
||||
public string? Iin { get; set; } // ИИН (для физлиц РК)
|
||||
public string? TaxNumber { get; set; } // ИНН (для РФ) или другой идентификатор
|
||||
public Guid? CountryId { get; set; }
|
||||
public Country? Country { get; set; }
|
||||
public string? Address { get; set; }
|
||||
public string? Phone { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? BankName { get; set; }
|
||||
public string? BankAccount { get; set; }
|
||||
public string? Bik { get; set; }
|
||||
public string? ContactPerson { get; set; }
|
||||
public string? Notes { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
11
src/food-market.domain/Catalog/Country.cs
Normal file
11
src/food-market.domain/Catalog/Country.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
// Global reference (not tenant-scoped). Shared across organizations.
|
||||
public class Country : Entity
|
||||
{
|
||||
public string Code { get; set; } = null!; // ISO 3166-1 alpha-2, e.g. "KZ"
|
||||
public string Name { get; set; } = null!;
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
13
src/food-market.domain/Catalog/Currency.cs
Normal file
13
src/food-market.domain/Catalog/Currency.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
// Global reference (not tenant-scoped).
|
||||
public class Currency : Entity
|
||||
{
|
||||
public string Code { get; set; } = null!; // ISO 4217, e.g. "KZT"
|
||||
public string Name { get; set; } = null!;
|
||||
public string Symbol { get; set; } = null!; // "₸"
|
||||
public int MinorUnit { get; set; } = 2; // 2 = two decimal places
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
31
src/food-market.domain/Catalog/Enums.cs
Normal file
31
src/food-market.domain/Catalog/Enums.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
public enum CounterpartyKind
|
||||
{
|
||||
Supplier = 1,
|
||||
Customer = 2,
|
||||
Both = 3,
|
||||
}
|
||||
|
||||
public enum CounterpartyType
|
||||
{
|
||||
LegalEntity = 1,
|
||||
Individual = 2,
|
||||
}
|
||||
|
||||
public enum StoreKind
|
||||
{
|
||||
Warehouse = 1,
|
||||
RetailFloor = 2,
|
||||
}
|
||||
|
||||
public enum BarcodeType
|
||||
{
|
||||
Ean13 = 1,
|
||||
Ean8 = 2,
|
||||
Code128 = 3,
|
||||
Code39 = 4,
|
||||
Upca = 5,
|
||||
Upce = 6,
|
||||
Other = 99,
|
||||
}
|
||||
13
src/food-market.domain/Catalog/PriceType.cs
Normal file
13
src/food-market.domain/Catalog/PriceType.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
// Тип цены: Розничная, Оптовая, Минимальная и т.д. По одной организации может быть несколько.
|
||||
public class PriceType : TenantEntity
|
||||
{
|
||||
public string Name { get; set; } = null!;
|
||||
public bool IsDefault { get; set; } // цена по умолчанию для новых товаров
|
||||
public bool IsRetail { get; set; } // используется на кассе
|
||||
public int SortOrder { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
44
src/food-market.domain/Catalog/Product.cs
Normal file
44
src/food-market.domain/Catalog/Product.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
public class Product : TenantEntity
|
||||
{
|
||||
public string Name { get; set; } = null!;
|
||||
public string? Article { get; set; } // артикул
|
||||
public string? Description { get; set; }
|
||||
|
||||
public Guid UnitOfMeasureId { get; set; }
|
||||
public UnitOfMeasure? UnitOfMeasure { get; set; }
|
||||
|
||||
public Guid VatRateId { get; set; }
|
||||
public VatRate? VatRate { get; set; }
|
||||
|
||||
public Guid? ProductGroupId { get; set; }
|
||||
public ProductGroup? ProductGroup { get; set; }
|
||||
|
||||
public Guid? DefaultSupplierId { get; set; } // основной поставщик
|
||||
public Counterparty? DefaultSupplier { get; set; }
|
||||
|
||||
public Guid? CountryOfOriginId { get; set; } // страна происхождения
|
||||
public Country? CountryOfOrigin { get; set; }
|
||||
|
||||
public bool IsService { get; set; } // услуга, а не физический товар
|
||||
public bool IsWeighed { get; set; } // весовой (продаётся с весов)
|
||||
public bool IsAlcohol { get; set; } // алкоголь (подакцизный)
|
||||
public bool IsMarked { get; set; } // маркируемый (Datamatrix)
|
||||
|
||||
public decimal? MinStock { get; set; } // минимальный остаток (для уведомлений)
|
||||
public decimal? MaxStock { get; set; } // максимальный остаток (для автозаказа)
|
||||
|
||||
public decimal? PurchasePrice { get; set; } // закупочная цена по умолчанию
|
||||
public Guid? PurchaseCurrencyId { get; set; }
|
||||
public Currency? PurchaseCurrency { get; set; }
|
||||
|
||||
public string? ImageUrl { get; set; } // основное изображение (остальные в ProductImage)
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
public ICollection<ProductPrice> Prices { get; set; } = [];
|
||||
public ICollection<ProductBarcode> Barcodes { get; set; } = [];
|
||||
public ICollection<ProductImage> Images { get; set; } = [];
|
||||
}
|
||||
12
src/food-market.domain/Catalog/ProductBarcode.cs
Normal file
12
src/food-market.domain/Catalog/ProductBarcode.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
public class ProductBarcode : TenantEntity
|
||||
{
|
||||
public Guid ProductId { get; set; }
|
||||
public Product? Product { get; set; }
|
||||
public string Code { get; set; } = null!;
|
||||
public BarcodeType Type { get; set; } = BarcodeType.Ean13;
|
||||
public bool IsPrimary { get; set; }
|
||||
}
|
||||
15
src/food-market.domain/Catalog/ProductGroup.cs
Normal file
15
src/food-market.domain/Catalog/ProductGroup.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
// Иерархическая группа товаров (категория). Произвольная вложенность через ParentId.
|
||||
public class ProductGroup : TenantEntity
|
||||
{
|
||||
public string Name { get; set; } = null!;
|
||||
public Guid? ParentId { get; set; }
|
||||
public ProductGroup? Parent { get; set; }
|
||||
public ICollection<ProductGroup> Children { get; set; } = [];
|
||||
public string Path { get; set; } = ""; // денормализованный путь "Электроника/Телефоны/Смартфоны" для фильтрации
|
||||
public int SortOrder { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
12
src/food-market.domain/Catalog/ProductImage.cs
Normal file
12
src/food-market.domain/Catalog/ProductImage.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
public class ProductImage : TenantEntity
|
||||
{
|
||||
public Guid ProductId { get; set; }
|
||||
public Product? Product { get; set; }
|
||||
public string Url { get; set; } = null!;
|
||||
public bool IsMain { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
17
src/food-market.domain/Catalog/ProductPrice.cs
Normal file
17
src/food-market.domain/Catalog/ProductPrice.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
public class ProductPrice : TenantEntity
|
||||
{
|
||||
public Guid ProductId { get; set; }
|
||||
public Product? Product { get; set; }
|
||||
|
||||
public Guid PriceTypeId { get; set; }
|
||||
public PriceType? PriceType { get; set; }
|
||||
|
||||
public decimal Amount { get; set; }
|
||||
|
||||
public Guid CurrencyId { get; set; }
|
||||
public Currency? Currency { get; set; }
|
||||
}
|
||||
17
src/food-market.domain/Catalog/RetailPoint.cs
Normal file
17
src/food-market.domain/Catalog/RetailPoint.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
// Точка продаж (магазин/отдел). Привязана к складу, с которого продаёт.
|
||||
public class RetailPoint : TenantEntity
|
||||
{
|
||||
public string Name { get; set; } = null!;
|
||||
public string? Code { get; set; }
|
||||
public Guid StoreId { get; set; } // склад, с которого идут продажи
|
||||
public Store? Store { get; set; }
|
||||
public string? Address { get; set; }
|
||||
public string? Phone { get; set; }
|
||||
public string? FiscalSerial { get; set; } // серийный номер ККМ (заполнится когда подключим фискализацию)
|
||||
public string? FiscalRegNumber { get; set; } // регистрационный номер в ОФД
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
16
src/food-market.domain/Catalog/Store.cs
Normal file
16
src/food-market.domain/Catalog/Store.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
// Склад: физическое место хранения товаров. Может быть чисто склад или торговый зал.
|
||||
public class Store : TenantEntity
|
||||
{
|
||||
public string Name { get; set; } = null!;
|
||||
public string? Code { get; set; } // внутренний код склада
|
||||
public StoreKind Kind { get; set; } = StoreKind.Warehouse;
|
||||
public string? Address { get; set; }
|
||||
public string? Phone { get; set; }
|
||||
public string? ManagerName { get; set; }
|
||||
public bool IsMain { get; set; } // основной склад организации
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
14
src/food-market.domain/Catalog/UnitOfMeasure.cs
Normal file
14
src/food-market.domain/Catalog/UnitOfMeasure.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
// Tenant-scoped справочник единиц измерения.
|
||||
public class UnitOfMeasure : TenantEntity
|
||||
{
|
||||
public string Code { get; set; } = null!; // ОКЕИ код: "796" (шт), "166" (кг), "112" (л)
|
||||
public string Symbol { get; set; } = null!; // "шт", "кг", "л", "м"
|
||||
public string Name { get; set; } = null!; // "штука", "килограмм", "литр"
|
||||
public int DecimalPlaces { get; set; } // 0 для шт, 3 для кг/л
|
||||
public bool IsBase { get; set; } // базовая единица этой организации
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
13
src/food-market.domain/Catalog/VatRate.cs
Normal file
13
src/food-market.domain/Catalog/VatRate.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using foodmarket.Domain.Common;
|
||||
|
||||
namespace foodmarket.Domain.Catalog;
|
||||
|
||||
// Tenant-scoped: разные организации могут работать в разных режимах (с НДС / упрощёнка).
|
||||
public class VatRate : TenantEntity
|
||||
{
|
||||
public string Name { get; set; } = null!; // "НДС 12%", "Без НДС"
|
||||
public decimal Percent { get; set; } // 12.00, 0.00
|
||||
public bool IsIncludedInPrice { get; set; } // входит ли в цену или начисляется сверху
|
||||
public bool IsDefault { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
using foodmarket.Application.Common.Tenancy;
|
||||
using foodmarket.Domain.Catalog;
|
||||
using foodmarket.Domain.Common;
|
||||
using foodmarket.Infrastructure.Identity;
|
||||
using foodmarket.Domain.Organizations;
|
||||
using foodmarket.Infrastructure.Persistence.Configurations;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
|
||||
namespace foodmarket.Infrastructure.Persistence;
|
||||
|
||||
|
|
@ -20,6 +21,20 @@ public AppDbContext(DbContextOptions<AppDbContext> options, ITenantContext tenan
|
|||
|
||||
public DbSet<Organization> Organizations => Set<Organization>();
|
||||
|
||||
public DbSet<Country> Countries => Set<Country>();
|
||||
public DbSet<Currency> Currencies => Set<Currency>();
|
||||
public DbSet<VatRate> VatRates => Set<VatRate>();
|
||||
public DbSet<UnitOfMeasure> UnitsOfMeasure => Set<UnitOfMeasure>();
|
||||
public DbSet<Counterparty> Counterparties => Set<Counterparty>();
|
||||
public DbSet<Store> Stores => Set<Store>();
|
||||
public DbSet<RetailPoint> RetailPoints => Set<RetailPoint>();
|
||||
public DbSet<ProductGroup> ProductGroups => Set<ProductGroup>();
|
||||
public DbSet<PriceType> PriceTypes => Set<PriceType>();
|
||||
public DbSet<Product> Products => Set<Product>();
|
||||
public DbSet<ProductPrice> ProductPrices => Set<ProductPrice>();
|
||||
public DbSet<ProductBarcode> ProductBarcodes => Set<ProductBarcode>();
|
||||
public DbSet<ProductImage> ProductImages => Set<ProductImage>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
|
|
@ -46,6 +61,8 @@ protected override void OnModelCreating(ModelBuilder builder)
|
|||
b.HasIndex(o => o.Name);
|
||||
});
|
||||
|
||||
builder.ConfigureCatalog();
|
||||
|
||||
// Apply multi-tenant query filter to every entity that implements ITenantEntity
|
||||
foreach (var entityType in builder.Model.GetEntityTypes())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,170 @@
|
|||
using foodmarket.Domain.Catalog;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace foodmarket.Infrastructure.Persistence.Configurations;
|
||||
|
||||
internal static class CatalogConfigurations
|
||||
{
|
||||
public static void ConfigureCatalog(this ModelBuilder b)
|
||||
{
|
||||
b.Entity<Country>(ConfigureCountry);
|
||||
b.Entity<Currency>(ConfigureCurrency);
|
||||
b.Entity<VatRate>(ConfigureVatRate);
|
||||
b.Entity<UnitOfMeasure>(ConfigureUnit);
|
||||
b.Entity<Counterparty>(ConfigureCounterparty);
|
||||
b.Entity<Store>(ConfigureStore);
|
||||
b.Entity<RetailPoint>(ConfigureRetailPoint);
|
||||
b.Entity<ProductGroup>(ConfigureProductGroup);
|
||||
b.Entity<PriceType>(ConfigurePriceType);
|
||||
b.Entity<Product>(ConfigureProduct);
|
||||
b.Entity<ProductPrice>(ConfigureProductPrice);
|
||||
b.Entity<ProductBarcode>(ConfigureBarcode);
|
||||
b.Entity<ProductImage>(ConfigureImage);
|
||||
}
|
||||
|
||||
private static void ConfigureCountry(EntityTypeBuilder<Country> b)
|
||||
{
|
||||
b.ToTable("countries");
|
||||
b.Property(x => x.Code).HasMaxLength(2).IsRequired();
|
||||
b.Property(x => x.Name).HasMaxLength(100).IsRequired();
|
||||
b.HasIndex(x => x.Code).IsUnique();
|
||||
}
|
||||
|
||||
private static void ConfigureCurrency(EntityTypeBuilder<Currency> b)
|
||||
{
|
||||
b.ToTable("currencies");
|
||||
b.Property(x => x.Code).HasMaxLength(3).IsRequired();
|
||||
b.Property(x => x.Name).HasMaxLength(100).IsRequired();
|
||||
b.Property(x => x.Symbol).HasMaxLength(5).IsRequired();
|
||||
b.HasIndex(x => x.Code).IsUnique();
|
||||
}
|
||||
|
||||
private static void ConfigureVatRate(EntityTypeBuilder<VatRate> b)
|
||||
{
|
||||
b.ToTable("vat_rates");
|
||||
b.Property(x => x.Name).HasMaxLength(100).IsRequired();
|
||||
b.Property(x => x.Percent).HasPrecision(5, 2);
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Name }).IsUnique();
|
||||
}
|
||||
|
||||
private static void ConfigureUnit(EntityTypeBuilder<UnitOfMeasure> b)
|
||||
{
|
||||
b.ToTable("units_of_measure");
|
||||
b.Property(x => x.Code).HasMaxLength(10).IsRequired();
|
||||
b.Property(x => x.Symbol).HasMaxLength(20).IsRequired();
|
||||
b.Property(x => x.Name).HasMaxLength(100).IsRequired();
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Code }).IsUnique();
|
||||
}
|
||||
|
||||
private static void ConfigureCounterparty(EntityTypeBuilder<Counterparty> b)
|
||||
{
|
||||
b.ToTable("counterparties");
|
||||
b.Property(x => x.Name).HasMaxLength(255).IsRequired();
|
||||
b.Property(x => x.LegalName).HasMaxLength(500);
|
||||
b.Property(x => x.Bin).HasMaxLength(20);
|
||||
b.Property(x => x.Iin).HasMaxLength(20);
|
||||
b.Property(x => x.TaxNumber).HasMaxLength(20);
|
||||
b.Property(x => x.Phone).HasMaxLength(50);
|
||||
b.Property(x => x.Email).HasMaxLength(255);
|
||||
b.Property(x => x.BankName).HasMaxLength(255);
|
||||
b.Property(x => x.BankAccount).HasMaxLength(50);
|
||||
b.Property(x => x.Bik).HasMaxLength(20);
|
||||
b.Property(x => x.ContactPerson).HasMaxLength(255);
|
||||
b.HasOne(x => x.Country).WithMany().HasForeignKey(x => x.CountryId).OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Name });
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Bin });
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Kind });
|
||||
}
|
||||
|
||||
private static void ConfigureStore(EntityTypeBuilder<Store> b)
|
||||
{
|
||||
b.ToTable("stores");
|
||||
b.Property(x => x.Name).HasMaxLength(200).IsRequired();
|
||||
b.Property(x => x.Code).HasMaxLength(50);
|
||||
b.Property(x => x.Phone).HasMaxLength(50);
|
||||
b.Property(x => x.ManagerName).HasMaxLength(200);
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Name });
|
||||
}
|
||||
|
||||
private static void ConfigureRetailPoint(EntityTypeBuilder<RetailPoint> b)
|
||||
{
|
||||
b.ToTable("retail_points");
|
||||
b.Property(x => x.Name).HasMaxLength(200).IsRequired();
|
||||
b.Property(x => x.Code).HasMaxLength(50);
|
||||
b.Property(x => x.Phone).HasMaxLength(50);
|
||||
b.Property(x => x.FiscalSerial).HasMaxLength(50);
|
||||
b.Property(x => x.FiscalRegNumber).HasMaxLength(50);
|
||||
b.HasOne(x => x.Store).WithMany().HasForeignKey(x => x.StoreId).OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Name });
|
||||
}
|
||||
|
||||
private static void ConfigureProductGroup(EntityTypeBuilder<ProductGroup> b)
|
||||
{
|
||||
b.ToTable("product_groups");
|
||||
b.Property(x => x.Name).HasMaxLength(200).IsRequired();
|
||||
b.Property(x => x.Path).HasMaxLength(1000);
|
||||
b.HasOne(x => x.Parent)
|
||||
.WithMany(x => x.Children)
|
||||
.HasForeignKey(x => x.ParentId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasIndex(x => new { x.OrganizationId, x.ParentId });
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Path });
|
||||
}
|
||||
|
||||
private static void ConfigurePriceType(EntityTypeBuilder<PriceType> b)
|
||||
{
|
||||
b.ToTable("price_types");
|
||||
b.Property(x => x.Name).HasMaxLength(100).IsRequired();
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Name }).IsUnique();
|
||||
}
|
||||
|
||||
private static void ConfigureProduct(EntityTypeBuilder<Product> b)
|
||||
{
|
||||
b.ToTable("products");
|
||||
b.Property(x => x.Name).HasMaxLength(500).IsRequired();
|
||||
b.Property(x => x.Article).HasMaxLength(100);
|
||||
b.Property(x => x.MinStock).HasPrecision(18, 4);
|
||||
b.Property(x => x.MaxStock).HasPrecision(18, 4);
|
||||
b.Property(x => x.PurchasePrice).HasPrecision(18, 4);
|
||||
b.Property(x => x.ImageUrl).HasMaxLength(1000);
|
||||
|
||||
b.HasOne(x => x.UnitOfMeasure).WithMany().HasForeignKey(x => x.UnitOfMeasureId).OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasOne(x => x.VatRate).WithMany().HasForeignKey(x => x.VatRateId).OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasOne(x => x.ProductGroup).WithMany().HasForeignKey(x => x.ProductGroupId).OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasOne(x => x.DefaultSupplier).WithMany().HasForeignKey(x => x.DefaultSupplierId).OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasOne(x => x.CountryOfOrigin).WithMany().HasForeignKey(x => x.CountryOfOriginId).OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasOne(x => x.PurchaseCurrency).WithMany().HasForeignKey(x => x.PurchaseCurrencyId).OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Name });
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Article });
|
||||
b.HasIndex(x => new { x.OrganizationId, x.ProductGroupId });
|
||||
b.HasIndex(x => new { x.OrganizationId, x.IsActive });
|
||||
}
|
||||
|
||||
private static void ConfigureProductPrice(EntityTypeBuilder<ProductPrice> b)
|
||||
{
|
||||
b.ToTable("product_prices");
|
||||
b.Property(x => x.Amount).HasPrecision(18, 4);
|
||||
b.HasOne(x => x.Product).WithMany(p => p.Prices).HasForeignKey(x => x.ProductId).OnDelete(DeleteBehavior.Cascade);
|
||||
b.HasOne(x => x.PriceType).WithMany().HasForeignKey(x => x.PriceTypeId).OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasOne(x => x.Currency).WithMany().HasForeignKey(x => x.CurrencyId).OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasIndex(x => new { x.ProductId, x.PriceTypeId }).IsUnique();
|
||||
}
|
||||
|
||||
private static void ConfigureBarcode(EntityTypeBuilder<ProductBarcode> b)
|
||||
{
|
||||
b.ToTable("product_barcodes");
|
||||
b.Property(x => x.Code).HasMaxLength(100).IsRequired();
|
||||
b.HasOne(x => x.Product).WithMany(p => p.Barcodes).HasForeignKey(x => x.ProductId).OnDelete(DeleteBehavior.Cascade);
|
||||
b.HasIndex(x => new { x.OrganizationId, x.Code }).IsUnique();
|
||||
}
|
||||
|
||||
private static void ConfigureImage(EntityTypeBuilder<ProductImage> b)
|
||||
{
|
||||
b.ToTable("product_images");
|
||||
b.Property(x => x.Url).HasMaxLength(1000).IsRequired();
|
||||
b.HasOne(x => x.Product).WithMany(p => p.Images).HasForeignKey(x => x.ProductId).OnDelete(DeleteBehavior.Cascade);
|
||||
b.HasIndex(x => x.ProductId);
|
||||
}
|
||||
}
|
||||
1389
src/food-market.infrastructure/Persistence/Migrations/20260421141151_Phase1Catalog.Designer.cs
generated
Normal file
1389
src/food-market.infrastructure/Persistence/Migrations/20260421141151_Phase1Catalog.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,647 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace foodmarket.Infrastructure.Persistence.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Phase1Catalog : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "countries",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Code = table.Column<string>(type: "character varying(2)", maxLength: 2, nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||
SortOrder = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_countries", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "currencies",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Code = table.Column<string>(type: "character varying(3)", maxLength: 3, nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||
Symbol = table.Column<string>(type: "character varying(5)", maxLength: 5, nullable: false),
|
||||
MinorUnit = table.Column<int>(type: "integer", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_currencies", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "price_types",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||
IsDefault = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsRetail = table.Column<bool>(type: "boolean", nullable: false),
|
||||
SortOrder = table.Column<int>(type: "integer", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_price_types", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "product_groups",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||
ParentId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
Path = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: false),
|
||||
SortOrder = table.Column<int>(type: "integer", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_product_groups", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_product_groups_product_groups_ParentId",
|
||||
column: x => x.ParentId,
|
||||
principalSchema: "public",
|
||||
principalTable: "product_groups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "stores",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||
Code = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
Address = table.Column<string>(type: "text", nullable: true),
|
||||
Phone = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
||||
ManagerName = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
||||
IsMain = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_stores", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "units_of_measure",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Code = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: false),
|
||||
Symbol = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||
DecimalPlaces = table.Column<int>(type: "integer", nullable: false),
|
||||
IsBase = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_units_of_measure", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "vat_rates",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||
Percent = table.Column<decimal>(type: "numeric(5,2)", precision: 5, scale: 2, nullable: false),
|
||||
IsIncludedInPrice = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsDefault = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_vat_rates", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "counterparties",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false),
|
||||
LegalName = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
||||
Kind = table.Column<int>(type: "integer", nullable: false),
|
||||
Type = table.Column<int>(type: "integer", nullable: false),
|
||||
Bin = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
|
||||
Iin = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
|
||||
TaxNumber = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
|
||||
CountryId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
Address = table.Column<string>(type: "text", nullable: true),
|
||||
Phone = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
||||
Email = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
|
||||
BankName = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
|
||||
BankAccount = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
||||
Bik = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
|
||||
ContactPerson = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
|
||||
Notes = table.Column<string>(type: "text", nullable: true),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_counterparties", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_counterparties_countries_CountryId",
|
||||
column: x => x.CountryId,
|
||||
principalSchema: "public",
|
||||
principalTable: "countries",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "retail_points",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||
Code = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
||||
StoreId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Address = table.Column<string>(type: "text", nullable: true),
|
||||
Phone = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
||||
FiscalSerial = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
||||
FiscalRegNumber = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_retail_points", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_retail_points_stores_StoreId",
|
||||
column: x => x.StoreId,
|
||||
principalSchema: "public",
|
||||
principalTable: "stores",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "products",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
||||
Article = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
||||
Description = table.Column<string>(type: "text", nullable: true),
|
||||
UnitOfMeasureId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
VatRateId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ProductGroupId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
DefaultSupplierId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
CountryOfOriginId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
IsService = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsWeighed = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsAlcohol = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsMarked = table.Column<bool>(type: "boolean", nullable: false),
|
||||
MinStock = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true),
|
||||
MaxStock = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true),
|
||||
PurchasePrice = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true),
|
||||
PurchaseCurrencyId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
ImageUrl = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_products", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_products_counterparties_DefaultSupplierId",
|
||||
column: x => x.DefaultSupplierId,
|
||||
principalSchema: "public",
|
||||
principalTable: "counterparties",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_products_countries_CountryOfOriginId",
|
||||
column: x => x.CountryOfOriginId,
|
||||
principalSchema: "public",
|
||||
principalTable: "countries",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_products_currencies_PurchaseCurrencyId",
|
||||
column: x => x.PurchaseCurrencyId,
|
||||
principalSchema: "public",
|
||||
principalTable: "currencies",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_products_product_groups_ProductGroupId",
|
||||
column: x => x.ProductGroupId,
|
||||
principalSchema: "public",
|
||||
principalTable: "product_groups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_products_units_of_measure_UnitOfMeasureId",
|
||||
column: x => x.UnitOfMeasureId,
|
||||
principalSchema: "public",
|
||||
principalTable: "units_of_measure",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_products_vat_rates_VatRateId",
|
||||
column: x => x.VatRateId,
|
||||
principalSchema: "public",
|
||||
principalTable: "vat_rates",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "product_barcodes",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ProductId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||
Type = table.Column<int>(type: "integer", nullable: false),
|
||||
IsPrimary = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_product_barcodes", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_product_barcodes_products_ProductId",
|
||||
column: x => x.ProductId,
|
||||
principalSchema: "public",
|
||||
principalTable: "products",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "product_images",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ProductId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Url = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: false),
|
||||
IsMain = table.Column<bool>(type: "boolean", nullable: false),
|
||||
SortOrder = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_product_images", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_product_images_products_ProductId",
|
||||
column: x => x.ProductId,
|
||||
principalSchema: "public",
|
||||
principalTable: "products",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "product_prices",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ProductId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
PriceTypeId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Amount = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
|
||||
CurrencyId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
OrganizationId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_product_prices", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_product_prices_currencies_CurrencyId",
|
||||
column: x => x.CurrencyId,
|
||||
principalSchema: "public",
|
||||
principalTable: "currencies",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_product_prices_price_types_PriceTypeId",
|
||||
column: x => x.PriceTypeId,
|
||||
principalSchema: "public",
|
||||
principalTable: "price_types",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_product_prices_products_ProductId",
|
||||
column: x => x.ProductId,
|
||||
principalSchema: "public",
|
||||
principalTable: "products",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_counterparties_CountryId",
|
||||
schema: "public",
|
||||
table: "counterparties",
|
||||
column: "CountryId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_counterparties_OrganizationId_Bin",
|
||||
schema: "public",
|
||||
table: "counterparties",
|
||||
columns: new[] { "OrganizationId", "Bin" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_counterparties_OrganizationId_Kind",
|
||||
schema: "public",
|
||||
table: "counterparties",
|
||||
columns: new[] { "OrganizationId", "Kind" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_counterparties_OrganizationId_Name",
|
||||
schema: "public",
|
||||
table: "counterparties",
|
||||
columns: new[] { "OrganizationId", "Name" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_countries_Code",
|
||||
schema: "public",
|
||||
table: "countries",
|
||||
column: "Code",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_currencies_Code",
|
||||
schema: "public",
|
||||
table: "currencies",
|
||||
column: "Code",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_price_types_OrganizationId_Name",
|
||||
schema: "public",
|
||||
table: "price_types",
|
||||
columns: new[] { "OrganizationId", "Name" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_product_barcodes_OrganizationId_Code",
|
||||
schema: "public",
|
||||
table: "product_barcodes",
|
||||
columns: new[] { "OrganizationId", "Code" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_product_barcodes_ProductId",
|
||||
schema: "public",
|
||||
table: "product_barcodes",
|
||||
column: "ProductId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_product_groups_OrganizationId_ParentId",
|
||||
schema: "public",
|
||||
table: "product_groups",
|
||||
columns: new[] { "OrganizationId", "ParentId" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_product_groups_OrganizationId_Path",
|
||||
schema: "public",
|
||||
table: "product_groups",
|
||||
columns: new[] { "OrganizationId", "Path" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_product_groups_ParentId",
|
||||
schema: "public",
|
||||
table: "product_groups",
|
||||
column: "ParentId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_product_images_ProductId",
|
||||
schema: "public",
|
||||
table: "product_images",
|
||||
column: "ProductId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_product_prices_CurrencyId",
|
||||
schema: "public",
|
||||
table: "product_prices",
|
||||
column: "CurrencyId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_product_prices_PriceTypeId",
|
||||
schema: "public",
|
||||
table: "product_prices",
|
||||
column: "PriceTypeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_product_prices_ProductId_PriceTypeId",
|
||||
schema: "public",
|
||||
table: "product_prices",
|
||||
columns: new[] { "ProductId", "PriceTypeId" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_CountryOfOriginId",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
column: "CountryOfOriginId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_DefaultSupplierId",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
column: "DefaultSupplierId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_OrganizationId_Article",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
columns: new[] { "OrganizationId", "Article" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_OrganizationId_IsActive",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
columns: new[] { "OrganizationId", "IsActive" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_OrganizationId_Name",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
columns: new[] { "OrganizationId", "Name" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_OrganizationId_ProductGroupId",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
columns: new[] { "OrganizationId", "ProductGroupId" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_ProductGroupId",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
column: "ProductGroupId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_PurchaseCurrencyId",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
column: "PurchaseCurrencyId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_UnitOfMeasureId",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
column: "UnitOfMeasureId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_products_VatRateId",
|
||||
schema: "public",
|
||||
table: "products",
|
||||
column: "VatRateId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_retail_points_OrganizationId_Name",
|
||||
schema: "public",
|
||||
table: "retail_points",
|
||||
columns: new[] { "OrganizationId", "Name" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_retail_points_StoreId",
|
||||
schema: "public",
|
||||
table: "retail_points",
|
||||
column: "StoreId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_stores_OrganizationId_Name",
|
||||
schema: "public",
|
||||
table: "stores",
|
||||
columns: new[] { "OrganizationId", "Name" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_units_of_measure_OrganizationId_Code",
|
||||
schema: "public",
|
||||
table: "units_of_measure",
|
||||
columns: new[] { "OrganizationId", "Code" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_vat_rates_OrganizationId_Name",
|
||||
schema: "public",
|
||||
table: "vat_rates",
|
||||
columns: new[] { "OrganizationId", "Name" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "product_barcodes",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "product_images",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "product_prices",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "retail_points",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "price_types",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "products",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "stores",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "counterparties",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "currencies",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "product_groups",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "units_of_measure",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "vat_rates",
|
||||
schema: "public");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "countries",
|
||||
schema: "public");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -334,6 +334,665 @@ protected override void BuildModel(ModelBuilder modelBuilder)
|
|||
b.ToTable("OpenIddictTokens", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.Counterparty", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("BankAccount")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("BankName")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("Bik")
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("Bin")
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("ContactPerson")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<Guid?>("CountryId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("Iin")
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("Kind")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("LegalName")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("TaxNumber")
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CountryId");
|
||||
|
||||
b.HasIndex("OrganizationId", "Bin");
|
||||
|
||||
b.HasIndex("OrganizationId", "Kind");
|
||||
|
||||
b.HasIndex("OrganizationId", "Name");
|
||||
|
||||
b.ToTable("counterparties", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.Country", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasMaxLength(2)
|
||||
.HasColumnType("character varying(2)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<int>("SortOrder")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Code")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("countries", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.Currency", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasMaxLength(3)
|
||||
.HasColumnType("character varying(3)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("MinorUnit")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.IsRequired()
|
||||
.HasMaxLength(5)
|
||||
.HasColumnType("character varying(5)");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Code")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("currencies", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.PriceType", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsDefault")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsRetail")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("SortOrder")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OrganizationId", "Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("price_types", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.Product", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Article")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<Guid?>("CountryOfOriginId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid?>("DefaultSupplierId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ImageUrl")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAlcohol")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsMarked")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsService")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsWeighed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal?>("MaxStock")
|
||||
.HasPrecision(18, 4)
|
||||
.HasColumnType("numeric(18,4)");
|
||||
|
||||
b.Property<decimal?>("MinStock")
|
||||
.HasPrecision(18, 4)
|
||||
.HasColumnType("numeric(18,4)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("ProductGroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("PurchaseCurrencyId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<decimal?>("PurchasePrice")
|
||||
.HasPrecision(18, 4)
|
||||
.HasColumnType("numeric(18,4)");
|
||||
|
||||
b.Property<Guid>("UnitOfMeasureId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("VatRateId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CountryOfOriginId");
|
||||
|
||||
b.HasIndex("DefaultSupplierId");
|
||||
|
||||
b.HasIndex("ProductGroupId");
|
||||
|
||||
b.HasIndex("PurchaseCurrencyId");
|
||||
|
||||
b.HasIndex("UnitOfMeasureId");
|
||||
|
||||
b.HasIndex("VatRateId");
|
||||
|
||||
b.HasIndex("OrganizationId", "Article");
|
||||
|
||||
b.HasIndex("OrganizationId", "IsActive");
|
||||
|
||||
b.HasIndex("OrganizationId", "Name");
|
||||
|
||||
b.HasIndex("OrganizationId", "ProductGroupId");
|
||||
|
||||
b.ToTable("products", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.ProductBarcode", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsPrimary")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("ProductId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ProductId");
|
||||
|
||||
b.HasIndex("OrganizationId", "Code")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("product_barcodes", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.ProductGroup", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("ParentId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<int>("SortOrder")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ParentId");
|
||||
|
||||
b.HasIndex("OrganizationId", "ParentId");
|
||||
|
||||
b.HasIndex("OrganizationId", "Path");
|
||||
|
||||
b.ToTable("product_groups", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.ProductImage", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsMain")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("ProductId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("SortOrder")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ProductId");
|
||||
|
||||
b.ToTable("product_images", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.ProductPrice", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasPrecision(18, 4)
|
||||
.HasColumnType("numeric(18,4)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("CurrencyId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("PriceTypeId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("ProductId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.HasIndex("PriceTypeId");
|
||||
|
||||
b.HasIndex("ProductId", "PriceTypeId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("product_prices", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.RetailPoint", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("FiscalRegNumber")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("FiscalSerial")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<Guid>("StoreId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("StoreId");
|
||||
|
||||
b.HasIndex("OrganizationId", "Name");
|
||||
|
||||
b.ToTable("retail_points", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.Store", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsMain")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("Kind")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ManagerName")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OrganizationId", "Name");
|
||||
|
||||
b.ToTable("stores", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.UnitOfMeasure", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("character varying(10)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("DecimalPlaces")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsBase")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.IsRequired()
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OrganizationId", "Code")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("units_of_measure", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.VatRate", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsDefault")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsIncludedInPrice")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<decimal>("Percent")
|
||||
.HasPrecision(5, 2)
|
||||
.HasColumnType("numeric(5,2)");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OrganizationId", "Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("vat_rates", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Organizations.Organization", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
|
|
@ -569,6 +1228,133 @@ protected override void BuildModel(ModelBuilder modelBuilder)
|
|||
b.Navigation("Authorization");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.Counterparty", b =>
|
||||
{
|
||||
b.HasOne("foodmarket.Domain.Catalog.Country", "Country")
|
||||
.WithMany()
|
||||
.HasForeignKey("CountryId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.Navigation("Country");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.Product", b =>
|
||||
{
|
||||
b.HasOne("foodmarket.Domain.Catalog.Country", "CountryOfOrigin")
|
||||
.WithMany()
|
||||
.HasForeignKey("CountryOfOriginId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasOne("foodmarket.Domain.Catalog.Counterparty", "DefaultSupplier")
|
||||
.WithMany()
|
||||
.HasForeignKey("DefaultSupplierId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasOne("foodmarket.Domain.Catalog.ProductGroup", "ProductGroup")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProductGroupId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasOne("foodmarket.Domain.Catalog.Currency", "PurchaseCurrency")
|
||||
.WithMany()
|
||||
.HasForeignKey("PurchaseCurrencyId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasOne("foodmarket.Domain.Catalog.UnitOfMeasure", "UnitOfMeasure")
|
||||
.WithMany()
|
||||
.HasForeignKey("UnitOfMeasureId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("foodmarket.Domain.Catalog.VatRate", "VatRate")
|
||||
.WithMany()
|
||||
.HasForeignKey("VatRateId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CountryOfOrigin");
|
||||
|
||||
b.Navigation("DefaultSupplier");
|
||||
|
||||
b.Navigation("ProductGroup");
|
||||
|
||||
b.Navigation("PurchaseCurrency");
|
||||
|
||||
b.Navigation("UnitOfMeasure");
|
||||
|
||||
b.Navigation("VatRate");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.ProductBarcode", b =>
|
||||
{
|
||||
b.HasOne("foodmarket.Domain.Catalog.Product", "Product")
|
||||
.WithMany("Barcodes")
|
||||
.HasForeignKey("ProductId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Product");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.ProductGroup", b =>
|
||||
{
|
||||
b.HasOne("foodmarket.Domain.Catalog.ProductGroup", "Parent")
|
||||
.WithMany("Children")
|
||||
.HasForeignKey("ParentId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.ProductImage", b =>
|
||||
{
|
||||
b.HasOne("foodmarket.Domain.Catalog.Product", "Product")
|
||||
.WithMany("Images")
|
||||
.HasForeignKey("ProductId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Product");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.ProductPrice", b =>
|
||||
{
|
||||
b.HasOne("foodmarket.Domain.Catalog.Currency", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("foodmarket.Domain.Catalog.PriceType", "PriceType")
|
||||
.WithMany()
|
||||
.HasForeignKey("PriceTypeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("foodmarket.Domain.Catalog.Product", "Product")
|
||||
.WithMany("Prices")
|
||||
.HasForeignKey("ProductId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
|
||||
b.Navigation("PriceType");
|
||||
|
||||
b.Navigation("Product");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.RetailPoint", b =>
|
||||
{
|
||||
b.HasOne("foodmarket.Domain.Catalog.Store", "Store")
|
||||
.WithMany()
|
||||
.HasForeignKey("StoreId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Store");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OpenIddict.EntityFrameworkCore.Models.OpenIddictEntityFrameworkCoreApplication", b =>
|
||||
{
|
||||
b.Navigation("Authorizations");
|
||||
|
|
@ -580,6 +1366,20 @@ protected override void BuildModel(ModelBuilder modelBuilder)
|
|||
{
|
||||
b.Navigation("Tokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.Product", b =>
|
||||
{
|
||||
b.Navigation("Barcodes");
|
||||
|
||||
b.Navigation("Images");
|
||||
|
||||
b.Navigation("Prices");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("foodmarket.Domain.Catalog.ProductGroup", b =>
|
||||
{
|
||||
b.Navigation("Children");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue