From 63bc6e9cd88956970e9c26fe1c9189666688b5ba Mon Sep 17 00:00:00 2001 From: DeepnaPooja Date: Thu, 20 Aug 2026 17:28:55 +0530 Subject: [PATCH 1/2] Add pricing and supplier master data --- Distribution/Data/AppDBContext.cs | 7 + Distribution/Features/Item/IItemRepository.cs | 1 + Distribution/Features/Item/ItemRepository.cs | 3 + Distribution/Features/Order/OrderDTOs.cs | 4 +- Distribution/Features/Order/OrderService.cs | 49 +- .../PriceList/IPriceListRepository.cs | 27 + .../Features/PriceList/PriceListController.cs | 70 + .../Features/PriceList/PriceListDTOs.cs | 25 + .../Features/PriceList/PriceListRepository.cs | 76 + .../Features/PriceList/PriceListService.cs | 171 ++ .../Features/Store/IStoreRepository.cs | 1 + .../Features/Store/StoreRepository.cs | 5 + .../Features/Supplier/ISupplierRepository.cs | 10 + .../Features/Supplier/SupplierController.cs | 42 + .../Features/Supplier/SupplierDTOs.cs | 13 + .../Features/Supplier/SupplierRepository.cs | 25 + .../Features/Supplier/SupplierService.cs | 61 + ...0101525_AddPricingAndSuppliers.Designer.cs | 2613 ++++++++++++++++ .../20260820101525_AddPricingAndSuppliers.cs | 116 + ...05946_AddPriceListItemMinPrice.Designer.cs | 2616 +++++++++++++++++ ...20260820105946_AddPriceListItemMinPrice.cs | 28 + .../Migrations/AppDBContextModelSnapshot.cs | 126 + Distribution/Models/PriceList.cs | 18 + Distribution/Models/PriceListItem.cs | 23 + Distribution/Models/Supplier.cs | 11 + Distribution/Program.cs | 6 + 26 files changed, 6138 insertions(+), 9 deletions(-) create mode 100644 Distribution/Features/PriceList/IPriceListRepository.cs create mode 100644 Distribution/Features/PriceList/PriceListController.cs create mode 100644 Distribution/Features/PriceList/PriceListDTOs.cs create mode 100644 Distribution/Features/PriceList/PriceListRepository.cs create mode 100644 Distribution/Features/PriceList/PriceListService.cs create mode 100644 Distribution/Features/Supplier/ISupplierRepository.cs create mode 100644 Distribution/Features/Supplier/SupplierController.cs create mode 100644 Distribution/Features/Supplier/SupplierDTOs.cs create mode 100644 Distribution/Features/Supplier/SupplierRepository.cs create mode 100644 Distribution/Features/Supplier/SupplierService.cs create mode 100644 Distribution/Migrations/20260820101525_AddPricingAndSuppliers.Designer.cs create mode 100644 Distribution/Migrations/20260820101525_AddPricingAndSuppliers.cs create mode 100644 Distribution/Migrations/20260820105946_AddPriceListItemMinPrice.Designer.cs create mode 100644 Distribution/Migrations/20260820105946_AddPriceListItemMinPrice.cs create mode 100644 Distribution/Models/PriceList.cs create mode 100644 Distribution/Models/PriceListItem.cs create mode 100644 Distribution/Models/Supplier.cs diff --git a/Distribution/Data/AppDBContext.cs b/Distribution/Data/AppDBContext.cs index 2e43ac4..9355ba6 100644 --- a/Distribution/Data/AppDBContext.cs +++ b/Distribution/Data/AppDBContext.cs @@ -30,6 +30,9 @@ public class AppDBContext(DbContextOptions options) : DbContext(op public DbSet StockBalances { get; set; } public DbSet StockMovements { get; set; } public DbSet StoreKycDocuments { get; set; } + public DbSet PriceLists { get; set; } + public DbSet PriceListItems { get; set; } + public DbSet Suppliers { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -58,6 +61,10 @@ public class AppDBContext(DbContextOptions options) : DbContext(op .HasIndex(sb => new { sb.FK_ItemId, sb.LocationId }) .IsUnique(); + modelBuilder.Entity() + .HasIndex(pli => new { pli.FK_PriceListId, pli.FK_ItemId }) + .IsUnique(); + Seed.RoleAndPermissionSeed.Apply(modelBuilder); } } diff --git a/Distribution/Features/Item/IItemRepository.cs b/Distribution/Features/Item/IItemRepository.cs index ec9bfc2..edc96e2 100644 --- a/Distribution/Features/Item/IItemRepository.cs +++ b/Distribution/Features/Item/IItemRepository.cs @@ -3,6 +3,7 @@ namespace Distribution.Features.Item; public interface IItemRepository { Task GetByIdAsync(Guid id); + Task GetBySkuAsync(string sku); Task> GetAllAsync(Guid? categoryId = null, Guid? subCategoryId = null, Guid? brandId = null); Task SkuExistsAsync(string sku, Guid? excludeId = null); Task GetByExternalErpItemIdAsync(int erpId); diff --git a/Distribution/Features/Item/ItemRepository.cs b/Distribution/Features/Item/ItemRepository.cs index b60cd2c..7069e94 100644 --- a/Distribution/Features/Item/ItemRepository.cs +++ b/Distribution/Features/Item/ItemRepository.cs @@ -15,6 +15,9 @@ public class ItemRepository(AppDBContext context) : IItemRepository .Include(i => i.Conversions).ThenInclude(c => c.ToUom) .FirstOrDefaultAsync(i => i.Id == id); + public async Task GetBySkuAsync(string sku) => + await context.Items.FirstOrDefaultAsync(i => i.Sku == sku && i.IsActive); + public async Task> GetAllAsync(Guid? categoryId = null, Guid? subCategoryId = null, Guid? brandId = null) { var query = context.Items diff --git a/Distribution/Features/Order/OrderDTOs.cs b/Distribution/Features/Order/OrderDTOs.cs index dfb7b9a..4f22a00 100644 --- a/Distribution/Features/Order/OrderDTOs.cs +++ b/Distribution/Features/Order/OrderDTOs.cs @@ -1,12 +1,12 @@ namespace Distribution.Features.Order; -public record OrderItemRequest(Guid ItemId, int Quantity); +public record OrderItemRequest(Guid ItemId, int Quantity, decimal? UnitPrice = null); public record CreateOrderRequest(Guid StoreId, DateTime OrderDate, decimal TotalAmount, List Items); public record UpdateOrderRequest(DateTime OrderDate, decimal TotalAmount); -public record OrderItemResponse(Guid ItemId, int Quantity); +public record OrderItemResponse(Guid ItemId, int Quantity, decimal UnitPrice); public record OrderResponse( Guid Id, diff --git a/Distribution/Features/Order/OrderService.cs b/Distribution/Features/Order/OrderService.cs index d7d6fb4..21e1527 100644 --- a/Distribution/Features/Order/OrderService.cs +++ b/Distribution/Features/Order/OrderService.cs @@ -1,3 +1,5 @@ +using Distribution.Features.Item; +using Distribution.Features.PriceList; using Distribution.Features.Store; using Distribution.Infra.Authorization; using Distribution.Infra.UoW; @@ -9,6 +11,8 @@ namespace Distribution.Features.Order; public class OrderService( IOrderRepository repo, IStoreRepository storeRepo, + IItemRepository itemRepo, + PriceListService priceListService, IUnitOfWork uow, ICurrentUserService currentUser, IScopeAccessService scopeAccess, @@ -18,7 +22,7 @@ public class OrderService( private static OrderResponse ToResponse(Models.Order o, List items) => new(o.Id, o.OrderDate, o.FK_StoreId, o.TotalAmount, - items.Select(i => new OrderItemResponse(i.FK_ItemId, i.Quantity)).ToList(), + items.Select(i => new OrderItemResponse(i.FK_ItemId, i.Quantity, i.UnitPrice)).ToList(), o.IsActive, o.CreatedAt); private bool HasGlobalScope => currentUser.RoleLevel >= GlobalScopeRoleLevel; @@ -29,6 +33,29 @@ public class OrderService( return await scopeAccess.HasStoreScopeAsync(currentUser.UserId.Value, storeId); } + /// + /// applyPricingAndDiscounts (price-list half, 14_pricing_and_suppliers.md): resolves the + /// region-scoped active price list, then global, then Item.SalePrice, and validates any + /// caller-supplied override falls within [MinPrice ?? Price, Price]. Returns null if no price + /// can be resolved, or if the requested price is outside the allowed band. + /// + private async Task ResolveUnitPriceAsync(Guid itemId, decimal? requestedUnitPrice, Models.Store store, DateTime orderDate) + { + var item = await itemRepo.GetByIdAsync(itemId); + if (item is null) return null; + var regionId = store.Route?.FK_RegionId; + var resolution = await priceListService.ResolvePriceAsync(itemId, regionId, item.SalePrice, orderDate); + if (resolution is null) return null; + + if (!requestedUnitPrice.HasValue) return resolution.Price; + + var min = resolution.MinPrice ?? resolution.Price; + var max = resolution.Price; + if (requestedUnitPrice.Value < min || requestedUnitPrice.Value > max) return null; + + return requestedUnitPrice.Value; + } + public async Task> GetAllAsync() { var orders = (await repo.GetAllAsync()).Where(o => o.IsActive).ToList(); @@ -72,7 +99,7 @@ public class OrderService( { if (!await HasStoreScopeAsync(request.StoreId)) return null; - var store = await storeRepo.GetByIdAsync(request.StoreId); + var store = await storeRepo.GetByIdWithRegionAsync(request.StoreId); if (store is null || !store.IsActive) return null; if (store.KycStatus != KycStatus.Verified) { @@ -86,12 +113,20 @@ public class OrderService( OrderDate = request.OrderDate, TotalAmount = request.TotalAmount }; - var orderItems = request.Items.Select(i => new Models.OrderItem + var orderItems = new List(); + foreach (var i in request.Items) { - FK_OrderId = order.Id, - FK_ItemId = i.ItemId, - Quantity = i.Quantity - }).ToList(); + var unitPrice = await ResolveUnitPriceAsync(i.ItemId, i.UnitPrice, store, request.OrderDate); + if (unitPrice is null) return null; + + orderItems.Add(new Models.OrderItem + { + FK_OrderId = order.Id, + FK_ItemId = i.ItemId, + Quantity = i.Quantity, + UnitPrice = unitPrice.Value + }); + } await uow.BeginAsync(ct); try diff --git a/Distribution/Features/PriceList/IPriceListRepository.cs b/Distribution/Features/PriceList/IPriceListRepository.cs new file mode 100644 index 0000000..d5a9658 --- /dev/null +++ b/Distribution/Features/PriceList/IPriceListRepository.cs @@ -0,0 +1,27 @@ +namespace Distribution.Features.PriceList; + +public interface IPriceListRepository +{ + Task GetByIdAsync(Guid id); + Task> GetAllAsync(Guid? regionId = null); + Task AddAsync(Models.PriceList entity); + void Update(Models.PriceList entity); + void Remove(Models.PriceList entity); + + Task GetItemAsync(Guid priceListId, Guid itemId); + Task AddItemAsync(Models.PriceListItem entity); + void UpdateItem(Models.PriceListItem entity); + void RemoveItem(Models.PriceListItem entity); + + /// + /// Active PriceListItem rows for the given item and region (region null = global lists only), + /// whose parent PriceList is active and effective on orderDate. Most recently created first. + /// + Task> GetActiveItemsAsync(Guid itemId, Guid? regionId, DateTime orderDate); + + /// + /// Active PriceListItem rows for itemId under any PriceList with the given RegionId (null = global), + /// whose date range overlaps [effectiveFrom, effectiveTo], excluding a given PriceList. + /// + Task HasOverlapAsync(Guid itemId, Guid? regionId, DateTime effectiveFrom, DateTime effectiveTo, Guid? excludePriceListId); +} diff --git a/Distribution/Features/PriceList/PriceListController.cs b/Distribution/Features/PriceList/PriceListController.cs new file mode 100644 index 0000000..d5d4eca --- /dev/null +++ b/Distribution/Features/PriceList/PriceListController.cs @@ -0,0 +1,70 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Distribution.Features.PriceList; + +[ApiController] +[Route("api/price-lists")] +[Authorize] +public class PriceListController(PriceListService service) : ControllerBase +{ + [HttpGet] + public async Task GetAll([FromQuery] Guid? regionId) => + Ok(await service.GetAllAsync(regionId)); + + [HttpGet("{id:guid}")] + public async Task GetById(Guid id) + { + var result = await service.GetByIdAsync(id); + return result is null ? NotFound() : Ok(result); + } + + [HttpPost] + public async Task Create(CreatePriceListRequest request, CancellationToken ct) + { + var result = await service.CreateAsync(request, ct); + return CreatedAtAction(nameof(GetById), new { id = result.Id }, result); + } + + [HttpPut("{id:guid}")] + public async Task Update(Guid id, UpdatePriceListRequest request, CancellationToken ct) + { + try + { + var result = await service.UpdateAsync(id, request, ct); + return result is null ? NotFound() : Ok(result); + } + catch (InvalidOperationException ex) + { + return Conflict(new { error = ex.Message }); + } + } + + [HttpDelete("{id:guid}")] + public async Task Delete(Guid id, CancellationToken ct) + { + var deleted = await service.DeleteAsync(id, ct); + return deleted ? NoContent() : NotFound(); + } + + [HttpPut("{id:guid}/items/{sku}")] + public async Task UpsertItem(Guid id, string sku, UpsertPriceListItemRequest request, CancellationToken ct) + { + try + { + var result = await service.UpsertItemAsync(id, sku, request, ct); + return result is null ? NotFound() : Ok(result); + } + catch (InvalidOperationException ex) + { + return Conflict(new { error = ex.Message }); + } + } + + [HttpDelete("{id:guid}/items/{sku}")] + public async Task RemoveItem(Guid id, string sku, CancellationToken ct) + { + var result = await service.RemoveItemAsync(id, sku, ct); + return result is null ? NotFound() : Ok(result); + } +} diff --git a/Distribution/Features/PriceList/PriceListDTOs.cs b/Distribution/Features/PriceList/PriceListDTOs.cs new file mode 100644 index 0000000..2e24595 --- /dev/null +++ b/Distribution/Features/PriceList/PriceListDTOs.cs @@ -0,0 +1,25 @@ +namespace Distribution.Features.PriceList; + +public record CreatePriceListRequest(string Name, Guid? RegionId, DateTime EffectiveFrom, DateTime EffectiveTo); + +public record UpdatePriceListRequest(string Name, Guid? RegionId, DateTime EffectiveFrom, DateTime EffectiveTo); + +public record UpsertPriceListItemRequest(decimal Price, decimal? MinPrice = null); + +public record PriceListItemResponse(Guid Id, Guid ItemId, string Sku, string ItemName, decimal Price, decimal? MinPrice); + +/// +/// A resolved price with its negotiable floor. MinPrice null = no negotiation, Price is fixed. +/// +public record PriceResolution(decimal Price, decimal? MinPrice); + +public record PriceListResponse( + Guid Id, + string Name, + Guid? RegionId, + string? RegionName, + DateTime EffectiveFrom, + DateTime EffectiveTo, + bool IsActive, + DateTime CreatedAt, + List Items); diff --git a/Distribution/Features/PriceList/PriceListRepository.cs b/Distribution/Features/PriceList/PriceListRepository.cs new file mode 100644 index 0000000..d02e5b2 --- /dev/null +++ b/Distribution/Features/PriceList/PriceListRepository.cs @@ -0,0 +1,76 @@ +using Distribution.Data; +using Microsoft.EntityFrameworkCore; + +namespace Distribution.Features.PriceList; + +public class PriceListRepository(AppDBContext context) : IPriceListRepository +{ + public async Task GetByIdAsync(Guid id) => + await context.PriceLists + .Include(pl => pl.Region) + .Include(pl => pl.Items.Where(i => i.IsActive)).ThenInclude(i => i.Item) + .FirstOrDefaultAsync(pl => pl.Id == id); + + public async Task> GetAllAsync(Guid? regionId = null) + { + var query = context.PriceLists + .Include(pl => pl.Region) + .Where(pl => pl.IsActive); + + if (regionId.HasValue) query = query.Where(pl => pl.FK_RegionId == regionId); + + return await query.ToListAsync(); + } + + public async Task AddAsync(Models.PriceList entity) => + await context.PriceLists.AddAsync(entity); + + public void Update(Models.PriceList entity) => + context.PriceLists.Update(entity); + + public void Remove(Models.PriceList entity) + { + entity.IsActive = false; + context.PriceLists.Update(entity); + } + + public async Task GetItemAsync(Guid priceListId, Guid itemId) => + await context.PriceListItems + .FirstOrDefaultAsync(i => i.FK_PriceListId == priceListId && i.FK_ItemId == itemId && i.IsActive); + + public async Task AddItemAsync(Models.PriceListItem entity) => + await context.PriceListItems.AddAsync(entity); + + public void UpdateItem(Models.PriceListItem entity) => + context.PriceListItems.Update(entity); + + public void RemoveItem(Models.PriceListItem entity) + { + entity.IsActive = false; + context.PriceListItems.Update(entity); + } + + public async Task> GetActiveItemsAsync(Guid itemId, Guid? regionId, DateTime orderDate) => + await context.PriceListItems + .Include(i => i.PriceList) + .Where(i => i.IsActive + && i.FK_ItemId == itemId + && i.PriceList.IsActive + && i.PriceList.FK_RegionId == regionId + && i.PriceList.EffectiveFrom <= orderDate + && i.PriceList.EffectiveTo >= orderDate) + .OrderByDescending(i => i.PriceList.CreatedAt) + .ToListAsync(); + + public async Task HasOverlapAsync(Guid itemId, Guid? regionId, DateTime effectiveFrom, DateTime effectiveTo, Guid? excludePriceListId) => + await context.PriceListItems + .Include(i => i.PriceList) + .Where(i => i.IsActive + && i.FK_ItemId == itemId + && i.PriceList.IsActive + && i.PriceList.FK_RegionId == regionId + && (excludePriceListId == null || i.FK_PriceListId != excludePriceListId) + && i.PriceList.EffectiveFrom <= effectiveTo + && i.PriceList.EffectiveTo >= effectiveFrom) + .AnyAsync(); +} diff --git a/Distribution/Features/PriceList/PriceListService.cs b/Distribution/Features/PriceList/PriceListService.cs new file mode 100644 index 0000000..01c7f4b --- /dev/null +++ b/Distribution/Features/PriceList/PriceListService.cs @@ -0,0 +1,171 @@ +using Distribution.Features.Item; +using Distribution.Infra.UoW; + +namespace Distribution.Features.PriceList; + +public class PriceListService(IPriceListRepository repo, IItemRepository itemRepo, IUnitOfWork uow) +{ + private static PriceListItemResponse MapItem(Models.PriceListItem i) => + new(i.Id, i.FK_ItemId, i.Item.Sku, i.Item.Name, i.Price, i.MinPrice); + + private static PriceListResponse MapDetail(Models.PriceList pl) => + new(pl.Id, pl.Name, pl.FK_RegionId, pl.Region?.Name, + pl.EffectiveFrom, pl.EffectiveTo, pl.IsActive, pl.CreatedAt, + pl.Items.Where(i => i.IsActive).Select(MapItem).ToList()); + + public async Task> GetAllAsync(Guid? regionId = null) + { + var lists = await repo.GetAllAsync(regionId); + return lists.Select(pl => new PriceListResponse( + pl.Id, pl.Name, pl.FK_RegionId, pl.Region?.Name, + pl.EffectiveFrom, pl.EffectiveTo, pl.IsActive, pl.CreatedAt, [])).ToList(); + } + + public async Task GetByIdAsync(Guid id) + { + var pl = await repo.GetByIdAsync(id); + if (pl is null || !pl.IsActive) return null; + return MapDetail(pl); + } + + public async Task CreateAsync(CreatePriceListRequest request, CancellationToken ct = default) + { + var priceList = new Models.PriceList + { + Name = request.Name, + FK_RegionId = request.RegionId, + EffectiveFrom = request.EffectiveFrom, + EffectiveTo = request.EffectiveTo + }; + + await uow.BeginAsync(ct); + try { await repo.AddAsync(priceList); await uow.CommitAsync(ct); } + catch { await uow.RollbackAsync(ct); throw; } + + return (await GetByIdAsync(priceList.Id))!; + } + + public async Task UpdateAsync(Guid id, UpdatePriceListRequest request, CancellationToken ct = default) + { + var priceList = await repo.GetByIdAsync(id); + if (priceList is null || !priceList.IsActive) return null; + + foreach (var item in priceList.Items.Where(i => i.IsActive)) + { + if (await repo.HasOverlapAsync(item.FK_ItemId, request.RegionId, request.EffectiveFrom, request.EffectiveTo, id)) + throw new InvalidOperationException( + $"Overlapping price list already exists for item '{item.Item.Sku}' in the same region for the requested date range."); + } + + priceList.Name = request.Name; + priceList.FK_RegionId = request.RegionId; + priceList.EffectiveFrom = request.EffectiveFrom; + priceList.EffectiveTo = request.EffectiveTo; + + await uow.BeginAsync(ct); + try { repo.Update(priceList); await uow.CommitAsync(ct); } + catch { await uow.RollbackAsync(ct); throw; } + + return (await GetByIdAsync(id))!; + } + + public async Task DeleteAsync(Guid id, CancellationToken ct = default) + { + var priceList = await repo.GetByIdAsync(id); + if (priceList is null || !priceList.IsActive) return false; + + await uow.BeginAsync(ct); + try + { + foreach (var item in priceList.Items.Where(i => i.IsActive)) + repo.RemoveItem(item); + repo.Remove(priceList); + await uow.CommitAsync(ct); + } + catch { await uow.RollbackAsync(ct); throw; } + + return true; + } + + public async Task UpsertItemAsync(Guid priceListId, string sku, UpsertPriceListItemRequest request, CancellationToken ct = default) + { + var priceList = await repo.GetByIdAsync(priceListId); + if (priceList is null || !priceList.IsActive) return null; + + var item = await itemRepo.GetBySkuAsync(sku); + if (item is null) return null; + + if (request.MinPrice.HasValue && request.MinPrice.Value > request.Price) + throw new InvalidOperationException( + $"MinPrice ({request.MinPrice}) cannot exceed Price ({request.Price}) for item '{sku}'."); + + if (await repo.HasOverlapAsync(item.Id, priceList.FK_RegionId, priceList.EffectiveFrom, priceList.EffectiveTo, priceListId)) + throw new InvalidOperationException( + $"Overlapping price list already exists for item '{sku}' in the same region for this date range."); + + var existing = await repo.GetItemAsync(priceListId, item.Id); + + await uow.BeginAsync(ct); + try + { + if (existing is null) + { + await repo.AddItemAsync(new Models.PriceListItem + { + FK_PriceListId = priceListId, + FK_ItemId = item.Id, + Price = request.Price, + MinPrice = request.MinPrice + }); + } + else + { + existing.Price = request.Price; + existing.MinPrice = request.MinPrice; + repo.UpdateItem(existing); + } + await uow.CommitAsync(ct); + } + catch { await uow.RollbackAsync(ct); throw; } + + return (await GetByIdAsync(priceListId))!; + } + + public async Task RemoveItemAsync(Guid priceListId, string sku, CancellationToken ct = default) + { + var priceList = await repo.GetByIdAsync(priceListId); + if (priceList is null || !priceList.IsActive) return null; + + var item = await itemRepo.GetBySkuAsync(sku); + if (item is null) return null; + + var existing = await repo.GetItemAsync(priceListId, item.Id); + if (existing is null) return null; + + await uow.BeginAsync(ct); + try { repo.RemoveItem(existing); await uow.CommitAsync(ct); } + catch { await uow.RollbackAsync(ct); throw; } + + return (await GetByIdAsync(priceListId))!; + } + + /// + /// applyPricingAndDiscounts (price-list half): region-scoped active price list -> global + /// active price list -> Item.SalePrice -> null if none apply. The returned PriceResolution + /// carries MinPrice so the caller can validate a negotiated UnitPrice against the band; + /// the Item.SalePrice fallback has no MinPrice (fixed, non-negotiable). + /// + public async Task ResolvePriceAsync(Guid itemId, Guid? regionId, decimal? itemSalePrice, DateTime orderDate) + { + if (regionId.HasValue) + { + var regionMatches = await repo.GetActiveItemsAsync(itemId, regionId, orderDate); + if (regionMatches.Count > 0) return new PriceResolution(regionMatches[0].Price, regionMatches[0].MinPrice); + } + + var globalMatches = await repo.GetActiveItemsAsync(itemId, null, orderDate); + if (globalMatches.Count > 0) return new PriceResolution(globalMatches[0].Price, globalMatches[0].MinPrice); + + return itemSalePrice.HasValue ? new PriceResolution(itemSalePrice.Value, null) : null; + } +} diff --git a/Distribution/Features/Store/IStoreRepository.cs b/Distribution/Features/Store/IStoreRepository.cs index 45416a8..e8d178d 100644 --- a/Distribution/Features/Store/IStoreRepository.cs +++ b/Distribution/Features/Store/IStoreRepository.cs @@ -3,6 +3,7 @@ namespace Distribution.Features.Store; public interface IStoreRepository { Task GetByIdAsync(Guid id); + Task GetByIdWithRegionAsync(Guid id); Task> GetAllAsync(); Task AddAsync(Models.Store entity); void Update(Models.Store entity); diff --git a/Distribution/Features/Store/StoreRepository.cs b/Distribution/Features/Store/StoreRepository.cs index 30ff1aa..9c44537 100644 --- a/Distribution/Features/Store/StoreRepository.cs +++ b/Distribution/Features/Store/StoreRepository.cs @@ -8,6 +8,11 @@ public class StoreRepository(AppDBContext context) : IStoreRepository public async Task GetByIdAsync(Guid id) => await context.Stores.FindAsync(id); + public async Task GetByIdWithRegionAsync(Guid id) => + await context.Stores + .Include(s => s.Route).ThenInclude(r => r.Region) + .FirstOrDefaultAsync(s => s.Id == id); + public async Task> GetAllAsync() => await context.Stores.ToListAsync(); diff --git a/Distribution/Features/Supplier/ISupplierRepository.cs b/Distribution/Features/Supplier/ISupplierRepository.cs new file mode 100644 index 0000000..4481613 --- /dev/null +++ b/Distribution/Features/Supplier/ISupplierRepository.cs @@ -0,0 +1,10 @@ +namespace Distribution.Features.Supplier; + +public interface ISupplierRepository +{ + Task GetByIdAsync(Guid id); + Task> GetAllAsync(); + Task AddAsync(Models.Supplier entity); + void Update(Models.Supplier entity); + void Remove(Models.Supplier entity); +} diff --git a/Distribution/Features/Supplier/SupplierController.cs b/Distribution/Features/Supplier/SupplierController.cs new file mode 100644 index 0000000..f1c83f9 --- /dev/null +++ b/Distribution/Features/Supplier/SupplierController.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Distribution.Features.Supplier; + +[ApiController] +[Route("api/suppliers")] +[Authorize] +public class SupplierController(SupplierService service) : ControllerBase +{ + [HttpGet] + public async Task GetAll() => + Ok(await service.GetAllAsync()); + + [HttpGet("{id:guid}")] + public async Task GetById(Guid id) + { + var result = await service.GetByIdAsync(id); + return result is null ? NotFound() : Ok(result); + } + + [HttpPost] + public async Task Create(CreateSupplierRequest request, CancellationToken ct) + { + var result = await service.CreateAsync(request, ct); + return CreatedAtAction(nameof(GetById), new { id = result.Id }, result); + } + + [HttpPut("{id:guid}")] + public async Task Update(Guid id, UpdateSupplierRequest request, CancellationToken ct) + { + var result = await service.UpdateAsync(id, request, ct); + return result is null ? NotFound() : Ok(result); + } + + [HttpDelete("{id:guid}")] + public async Task Delete(Guid id, CancellationToken ct) + { + var deleted = await service.DeleteAsync(id, ct); + return deleted ? NoContent() : NotFound(); + } +} diff --git a/Distribution/Features/Supplier/SupplierDTOs.cs b/Distribution/Features/Supplier/SupplierDTOs.cs new file mode 100644 index 0000000..2976050 --- /dev/null +++ b/Distribution/Features/Supplier/SupplierDTOs.cs @@ -0,0 +1,13 @@ +namespace Distribution.Features.Supplier; + +public record CreateSupplierRequest(string Name, string? ContactInfo); + +public record UpdateSupplierRequest(string Name, string? ContactInfo); + +public record SupplierResponse( + Guid Id, + string Name, + string? ContactInfo, + decimal? PerformanceScore, + bool IsActive, + DateTime CreatedAt); diff --git a/Distribution/Features/Supplier/SupplierRepository.cs b/Distribution/Features/Supplier/SupplierRepository.cs new file mode 100644 index 0000000..32bae61 --- /dev/null +++ b/Distribution/Features/Supplier/SupplierRepository.cs @@ -0,0 +1,25 @@ +using Distribution.Data; +using Microsoft.EntityFrameworkCore; + +namespace Distribution.Features.Supplier; + +public class SupplierRepository(AppDBContext context) : ISupplierRepository +{ + public async Task GetByIdAsync(Guid id) => + await context.Suppliers.FindAsync(id); + + public async Task> GetAllAsync() => + await context.Suppliers.Where(s => s.IsActive).ToListAsync(); + + public async Task AddAsync(Models.Supplier entity) => + await context.Suppliers.AddAsync(entity); + + public void Update(Models.Supplier entity) => + context.Suppliers.Update(entity); + + public void Remove(Models.Supplier entity) + { + entity.IsActive = false; + context.Suppliers.Update(entity); + } +} diff --git a/Distribution/Features/Supplier/SupplierService.cs b/Distribution/Features/Supplier/SupplierService.cs new file mode 100644 index 0000000..27013ec --- /dev/null +++ b/Distribution/Features/Supplier/SupplierService.cs @@ -0,0 +1,61 @@ +using Distribution.Infra.UoW; + +namespace Distribution.Features.Supplier; + +public class SupplierService(ISupplierRepository repo, IUnitOfWork uow) +{ + private static SupplierResponse Map(Models.Supplier s) => + new(s.Id, s.Name, s.ContactInfo, s.PerformanceScore, s.IsActive, s.CreatedAt); + + public async Task> GetAllAsync() => + (await repo.GetAllAsync()).Select(Map).ToList(); + + public async Task GetByIdAsync(Guid id) + { + var supplier = await repo.GetByIdAsync(id); + if (supplier is null || !supplier.IsActive) return null; + return Map(supplier); + } + + public async Task CreateAsync(CreateSupplierRequest request, CancellationToken ct = default) + { + var supplier = new Models.Supplier + { + Name = request.Name, + ContactInfo = request.ContactInfo + }; + + await uow.BeginAsync(ct); + try { await repo.AddAsync(supplier); await uow.CommitAsync(ct); } + catch { await uow.RollbackAsync(ct); throw; } + + return Map(supplier); + } + + public async Task UpdateAsync(Guid id, UpdateSupplierRequest request, CancellationToken ct = default) + { + var supplier = await repo.GetByIdAsync(id); + if (supplier is null || !supplier.IsActive) return null; + + supplier.Name = request.Name; + supplier.ContactInfo = request.ContactInfo; + + await uow.BeginAsync(ct); + try { repo.Update(supplier); await uow.CommitAsync(ct); } + catch { await uow.RollbackAsync(ct); throw; } + + return Map(supplier); + } + + public async Task DeleteAsync(Guid id, CancellationToken ct = default) + { + var supplier = await repo.GetByIdAsync(id); + if (supplier is null || !supplier.IsActive) return false; + + await uow.BeginAsync(ct); + try { repo.Remove(supplier); await uow.CommitAsync(ct); } + catch { await uow.RollbackAsync(ct); throw; } + + return true; + } +} diff --git a/Distribution/Migrations/20260820101525_AddPricingAndSuppliers.Designer.cs b/Distribution/Migrations/20260820101525_AddPricingAndSuppliers.Designer.cs new file mode 100644 index 0000000..9f349fa --- /dev/null +++ b/Distribution/Migrations/20260820101525_AddPricingAndSuppliers.Designer.cs @@ -0,0 +1,2613 @@ +// +using System; +using Distribution.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Distribution.Migrations +{ + [DbContext(typeof(AppDBContext))] + [Migration("20260820101525_AddPricingAndSuppliers")] + partial class AddPricingAndSuppliers + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("Distribution.Models.Brand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExternalErpId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Brands"); + }); + + modelBuilder.Entity("Distribution.Models.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowCustomerReturn") + .HasColumnType("tinyint(1)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExternalErpId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Distribution.Models.DeliveryRun", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FK_RouteId") + .HasColumnType("char(36)"); + + b.Property("FK_VehicleId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Meterend") + .HasColumnType("int"); + + b.Property("Meterstart") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FK_RouteId"); + + b.HasIndex("FK_VehicleId"); + + b.ToTable("DeliveryRuns"); + }); + + modelBuilder.Entity("Distribution.Models.Item", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("ExternalErpItemId") + .HasColumnType("int"); + + b.Property("FK_BaseUomId") + .HasColumnType("char(36)"); + + b.Property("FK_BrandId") + .HasColumnType("char(36)"); + + b.Property("FK_CategoryId") + .HasColumnType("char(36)"); + + b.Property("FK_SubCategoryId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("LastSyncedAt") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SalePrice") + .HasColumnType("decimal(65,30)"); + + b.Property("Sku") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SyncSource") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FK_BaseUomId"); + + b.HasIndex("FK_BrandId"); + + b.HasIndex("FK_CategoryId"); + + b.HasIndex("FK_SubCategoryId"); + + b.ToTable("Items"); + }); + + modelBuilder.Entity("Distribution.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FK_StoreId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("TotalAmount") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.HasIndex("FK_StoreId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Distribution.Models.OrderItem", b => + { + b.Property("FK_OrderId") + .HasColumnType("char(36)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(65,30)"); + + b.HasKey("FK_OrderId", "FK_ItemId"); + + b.HasIndex("FK_ItemId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Distribution.Models.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Code") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Permissions"); + + b.HasData( + new + { + Id = new Guid("20000000-0000-0000-0000-000000000001"), + Code = "regions.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View regions", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000002"), + Code = "regions.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create regions", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000003"), + Code = "regions.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update regions", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000004"), + Code = "regions.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete regions", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000005"), + Code = "routes.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View routes", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000006"), + Code = "routes.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create routes", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000007"), + Code = "routes.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update routes", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000008"), + Code = "routes.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete routes", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000009"), + Code = "vehicles.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View vehicles", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000010"), + Code = "vehicles.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create vehicles", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000011"), + Code = "vehicles.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update vehicles", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000012"), + Code = "vehicles.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete vehicles", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000013"), + Code = "stores.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View stores", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000014"), + Code = "stores.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create stores", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000015"), + Code = "stores.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update stores", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000016"), + Code = "stores.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete stores", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000017"), + Code = "stores.kyc.verify", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Verify or reject store KYC documents", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000018"), + Code = "stores.credit.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update store credit limit and outstanding balance", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000019"), + Code = "warehouses.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View warehouses", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000020"), + Code = "warehouses.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create warehouses", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000021"), + Code = "warehouses.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update warehouses", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000022"), + Code = "warehouses.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete warehouses", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000023"), + Code = "orders.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View orders", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000024"), + Code = "orders.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create orders", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000025"), + Code = "orders.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update orders", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000026"), + Code = "orders.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete orders", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000027"), + Code = "users.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View users", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000028"), + Code = "users.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create users", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000029"), + Code = "users.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update users", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000030"), + Code = "users.deactivate", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Deactivate users", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000031"), + Code = "users.assign_role", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Assign a role to a user", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000032"), + Code = "users.assign_scope", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Assign region/route/store scope to a user", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000033"), + Code = "items.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View items, brands and UOMs", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000034"), + Code = "items.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create items, brands and UOMs", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000035"), + Code = "items.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update items, brands and UOMs", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000036"), + Code = "items.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete items, brands and UOMs", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000037"), + Code = "categories.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View categories", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000038"), + Code = "categories.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create categories and subcategories", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000039"), + Code = "categories.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update categories and subcategories", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000040"), + Code = "categories.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete categories and subcategories", + IsActive = true + }); + }); + + modelBuilder.Entity("Distribution.Models.PriceList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("EffectiveFrom") + .HasColumnType("datetime(6)"); + + b.Property("EffectiveTo") + .HasColumnType("datetime(6)"); + + b.Property("FK_RegionId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_RegionId"); + + b.ToTable("PriceLists"); + }); + + modelBuilder.Entity("Distribution.Models.PriceListItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("FK_PriceListId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Price") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.HasIndex("FK_ItemId"); + + b.HasIndex("FK_PriceListId", "FK_ItemId") + .IsUnique(); + + b.ToTable("PriceListItems"); + }); + + modelBuilder.Entity("Distribution.Models.Region", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Regions"); + }); + + modelBuilder.Entity("Distribution.Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + + b.HasData( + new + { + Id = new Guid("10000000-0000-0000-0000-000000000001"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 10, + Name = "SalesRep" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000002"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 20, + Name = "Supervisor" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000003"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 30, + Name = "AreaManager" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000004"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 40, + Name = "AreaSupervisor" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 50, + Name = "RegionalManager" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000006"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 60, + Name = "RegionalAgency" + }); + }); + + modelBuilder.Entity("Distribution.Models.RolePermission", b => + { + b.Property("FK_RoleId") + .HasColumnType("char(36)"); + + b.Property("FK_PermissionId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("FK_RoleId", "FK_PermissionId"); + + b.HasIndex("FK_PermissionId"); + + b.ToTable("RolePermissions"); + + b.HasData( + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("dfe4bb14-1047-219c-cabe-a2b49b105d86"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c0739b84-50a2-0971-429b-02bab8354c51"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c268a531-44eb-0f29-82ba-18394ac2dcb5"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("0e0613fd-d62c-1e87-a5b6-8bd2c3697c2a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("75737fa8-fed0-d97a-8c24-5716758a7222"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("ddb2d04d-19b0-20b1-2639-b157d12a9eec"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("320ba3fb-666c-ce57-3e61-95c9824c4048"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e1f39dc4-6c33-45f4-8c23-3ad8ae5784a8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("357c36de-9b6c-1c9a-4926-c18a9bccf0ca"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1b126bb0-e582-3e84-4728-a7ab5628fe7b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("eb4ffa50-b09a-f0a5-1994-3fc2ae3a35d0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7ee233b9-3758-e005-7bb2-5ad1edf36e21"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("0f291826-e169-c06a-0735-bd06cbb2062d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("10dd0249-ce04-c5d9-8f94-ccb348c1d979"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f50b201c-6c8d-0df8-85ad-08cb137bc213"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5adb4d1a-eba8-16cb-8603-c3443d4ee8c8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("23105bb1-ef1f-6e19-1a48-d62ccaec1db4"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f2c14d55-d557-5cd2-a70a-4a6f58933436"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5cee999e-1b77-cb87-5148-6a793af7c44e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("73e00ce7-c124-4677-4369-1eb9876852c0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("929950da-d51b-ad5d-c4e5-55175908fb43"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("680b582c-dbc9-cfde-f54b-58c3ad5a57b6"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e9c8355a-26a9-4107-504e-d61722f9e7cd"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d49f086e-30f0-6ce8-ae96-4395d5e04472"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("a41f94ba-c24d-93dc-9f25-c462df19785a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("a9a49749-f99d-3166-5d92-b7e380fcabb2"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("0b7d47cf-efd9-9589-682b-78df22062e5a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4aaa0f3d-4360-5f11-41c1-5257662428af"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d92d572f-f1bf-9e7d-1d4d-7c7b0d575c8e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7fef12f3-6875-14bb-9554-0c9d82f02a37"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f367f6f6-3d26-7a6c-888b-da1a240b59af"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("38ea5531-a29d-a6bb-eebe-a18f3afe066d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b17df3df-022c-c903-6ce0-e6423e648dc8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1e7fe1b6-5150-4b99-38ed-088d9495cfd8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("db15215a-0a16-ef1f-5c82-6bb902a2b319"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7b4f3482-b8bd-d348-e4c1-ae6dc93a3771"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("04ece77e-b36f-8ed0-4ef9-2f6962b6f9c6"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("76f58da8-09f6-c4e2-01bd-ddd94809c1f5"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c6d74049-3f46-88af-1067-c9ae133132f7"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7c392a13-1a57-0d85-dffa-2fb9e892abe9"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d1dcef02-d4c3-caba-372f-dab82011e9c1"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("bf2a2f96-04ed-905d-5a8a-9047d814aa3e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c99adad6-94e8-0d5b-3d35-086f393207fb"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b22d4f78-7a21-da50-5351-553bdf06c9c2"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5e10d61c-2d7a-3388-722f-45232d2cfb71"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("dafe8f7e-e527-5863-5cde-92599c4ba9eb"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d8257363-d838-fe7e-57a5-51b626dbfc83"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3cb22998-b618-c13f-48cd-9e7416f324fc"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("97708eed-6ce4-7710-abde-01d00c0c879b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9afe507e-191e-bdee-0c5a-cfbcbf1efb3e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000006"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("29d71000-6715-de8a-a3af-814938d50dfb"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000007"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f58f4242-af91-0b8d-5be5-4b07b4367e8c"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000016"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e0b27435-f505-43f5-7ed9-4711f2248495"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000036"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9c278616-4289-96fb-944d-b8f1495ccb00"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000038"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9cc36229-dfba-49b9-1d6e-8929546e894d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000039"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("a66f3854-5a8f-95c2-cb1c-b2b2e67ee226"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000040"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("14bcecd1-b1a2-6da3-155a-233611484467"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4d682c93-d6df-4214-436d-85f76a3ade93"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4b2c3b3b-c27d-410c-c1fc-7e43e280242f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1d227ae7-0eb9-c742-41df-3472718cb077"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4d287b19-ba40-7d4d-3d39-291be64197f8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("fcc6af61-cc43-066c-5634-2ddc24a8460d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("2f994b6b-b055-28c2-2fb1-99a0076a0e3f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("55e84a29-428d-bf95-d589-793ecd8bac6e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000016"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("43ec940a-44d2-9c47-a37d-049f2cfb2615"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("ee175c87-23bd-5529-ed18-6ce46985c6ed"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("2ae2eba4-4427-ab1e-cf03-e59a3925ef89"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d95e7d5a-b12c-12b8-fee9-39576c905fed"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000006"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d97abb20-e53d-c970-d337-3764584874fa"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000007"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("a63446ad-14a9-6239-8791-0a1f86813903"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000008"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7f9502a2-feb4-f0ef-cb71-a62d00570fd0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d1f4316a-72a0-66af-2a8a-1fdbdb4f8c3a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000010"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("30e94e9b-c70c-2df3-0813-e99ce4511838"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000011"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("94f2f2ec-94b7-b768-76a4-9ee4256d95c1"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000012"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7201efa2-f829-8035-6607-174214f8fdba"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c88131d2-51b2-2bac-ad15-c7c130eb26f8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000020"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3a2ccc28-7416-388d-17f2-424d0520049f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("08de9913-8cfc-4ab4-2cb9-2bc9217fbb6e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f3c8f315-3b2f-f923-e3cd-f3e575010138"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000001"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3e3e6f06-72c8-42fa-f7e6-8feeaca36d60"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000027"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("43a4c7b4-a50f-aa37-b147-a30636d9d65f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("0efa7259-aadb-0019-4be5-38d3f8f4cd54"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9e60e7d7-8bd6-c1c7-4bf1-4de2c9dcb91c"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5df82318-bc01-1947-09ef-60508e02b257"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000036"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("34f478f4-6c96-4b31-b68a-28c7942c0789"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("69598e0e-b7ad-477b-c587-7abf6189162d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000038"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b36fb2d4-43df-44f8-ff51-de6d88644c94"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000039"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("aeb29e0e-e819-1446-6cc6-1fb64b5ecc6b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000040"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e18a6eca-1009-bcc6-35e9-ead943c1649f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000001"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f64e20e2-f9ca-7ea5-42f4-c1256b0c0798"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000002"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7b6765bc-1510-cfc6-55ae-ac689caf0dcc"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000003"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d9e06d2d-82d6-84e8-e9ba-5406e9b4122d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000004"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b53e01bb-4e54-3270-87b1-0d54f947e09b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("111b7d3c-3640-66e6-0757-b9fb67572943"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000006"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7ee06ff0-8557-b5bd-02dc-c4ff99e76348"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000007"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d20bcba0-a5af-de47-919d-a8645a828d27"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000008"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b3ef35de-afc2-d80a-115f-77ba954f9586"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d1b7e0a2-149f-b56b-8c63-bb8d10bfcc1e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000010"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("51e06fd0-cd20-ceeb-04cc-7dc79388c4a1"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000011"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("25639115-7083-1324-c3bd-3ad90fcfa1a0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000012"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("51011cb7-5753-14ad-280c-86a6bd33124f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("51ce3fad-cdbc-cfad-6cf0-52b47ec3f200"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4a080973-c23f-3d1b-9883-6b7e06025a77"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3f78910a-76ee-f34b-52d3-af79d7f3b724"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000016"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("812cbb8d-e268-aad3-373e-42b8720f0f45"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("046cd13e-77f1-78c7-fa52-d49ea7fb9855"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("96f24adf-386d-14d0-46fe-a22ceff2f79b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9b5f23fb-2396-3f43-1d3e-97551eb4248d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000020"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("30397d69-3b96-56e7-0ca1-1e612dfb64f1"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("91260fa1-3754-ad7e-10d8-2a8fd9b208ff"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("8b993e65-b066-198a-385d-602660ed85ac"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("248d6092-c2e5-5f8f-5ef0-cd60dc94cbc8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5f6e3c68-27d2-e00f-d5c9-4ce9e2b9587f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("96a4ac9e-cfea-6391-8020-75b2980bf2a3"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("6eb59953-807d-aa61-29e3-1699c0aebda9"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000027"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1095440c-ce52-235b-b95f-6b28c5d1b3a8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000028"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3a56ab5c-f0c5-a37b-0795-de061597628f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000029"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("104ebcfb-ca82-3f95-d75e-35a943618176"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000030"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("ace990cf-6654-5e68-3dc8-1e62347e0946"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000031"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("bd209f90-6671-8ea0-eb20-aa151faec6a0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000032"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4cc32686-8391-0214-5747-db14f53c5b6f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("26c6d86a-835d-6f0d-3730-66a46ea26b11"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e8039d9c-a286-fb74-5abb-b5c6c67f243a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d9e038cb-bcff-cce1-5d34-b4e63a9ce694"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000036"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("343e71f0-da6b-2489-5571-f8d7c6378ee7"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("ac894328-a935-8e6e-8427-6c0f36ac75da"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000038"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1d6273d4-db6a-d70e-4b5f-98cb634d668a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000039"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3f32cdac-6925-23f2-064e-8226d781d4a3"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000040"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("dc3dd9ff-b123-a8d4-dcea-b4f5f8ff171e"), + IsActive = true + }); + }); + + modelBuilder.Entity("Distribution.Models.Route", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("EndPoint") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FK_RegionId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Length") + .HasColumnType("decimal(65,30)"); + + b.Property("RouteName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StartPoint") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_RegionId"); + + b.ToTable("Routes"); + }); + + modelBuilder.Entity("Distribution.Models.SaleRoute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("SaleRoutes"); + }); + + modelBuilder.Entity("Distribution.Models.StockBalance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("LocationId") + .HasColumnType("char(36)"); + + b.Property("LocationType") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("decimal(65,30)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("FK_ItemId", "LocationId") + .IsUnique(); + + b.ToTable("StockBalances"); + }); + + modelBuilder.Entity("Distribution.Models.StockMovement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedBy") + .HasColumnType("char(36)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("FromLocationId") + .HasColumnType("char(36)"); + + b.Property("FromLocationType") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("decimal(65,30)"); + + b.Property("ReasonCode") + .HasColumnType("longtext"); + + b.Property("ReferenceId") + .HasColumnType("char(36)"); + + b.Property("ToLocationId") + .HasColumnType("char(36)"); + + b.Property("ToLocationType") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FK_ItemId"); + + b.ToTable("StockMovements"); + }); + + modelBuilder.Entity("Distribution.Models.Store", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreditAmount") + .HasColumnType("decimal(65,30)"); + + b.Property("CreditLimit") + .HasColumnType("decimal(65,30)"); + + b.Property("FK_RouteId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("KycStatus") + .HasColumnType("int"); + + b.Property("Latitude") + .HasColumnType("decimal(65,30)"); + + b.Property("Longitude") + .HasColumnType("decimal(65,30)"); + + b.Property("OneTimeAmount") + .HasColumnType("decimal(65,30)"); + + b.Property("OutstandingBalance") + .HasColumnType("decimal(65,30)"); + + b.Property("OwnerName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Segment") + .HasColumnType("longtext"); + + b.Property("StoreAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StoreName") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_RouteId"); + + b.ToTable("Stores"); + }); + + modelBuilder.Entity("Distribution.Models.StoreKycDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("DocumentType") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FK_StoreId") + .HasColumnType("char(36)"); + + b.Property("FileReference") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("UploadedAt") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("FK_StoreId"); + + b.ToTable("StoreKycDocuments"); + }); + + modelBuilder.Entity("Distribution.Models.SubCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExternalErpId") + .HasColumnType("int"); + + b.Property("FK_CategoryId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_CategoryId"); + + b.ToTable("SubCategories"); + }); + + modelBuilder.Entity("Distribution.Models.Supplier", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContactInfo") + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PerformanceScore") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.ToTable("Suppliers"); + }); + + modelBuilder.Entity("Distribution.Models.Uom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExternalErpId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Uoms"); + }); + + modelBuilder.Entity("Distribution.Models.UomConversion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("FK_FromUomId") + .HasColumnType("char(36)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("FK_ToUomId") + .HasColumnType("char(36)"); + + b.Property("Factor") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.HasIndex("FK_FromUomId"); + + b.HasIndex("FK_ItemId"); + + b.HasIndex("FK_ToUomId"); + + b.ToTable("UomConversions"); + }); + + modelBuilder.Entity("Distribution.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FK_ReportsToUserId") + .HasColumnType("char(36)"); + + b.Property("FK_RoleId") + .HasColumnType("char(36)"); + + b.Property("FullName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_ReportsToUserId"); + + b.HasIndex("FK_RoleId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Distribution.Models.UserRegionScope", b => + { + b.Property("FK_UserId") + .HasColumnType("char(36)"); + + b.Property("FK_RegionId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("FK_UserId", "FK_RegionId"); + + b.HasIndex("FK_RegionId"); + + b.ToTable("UserRegionScopes"); + }); + + modelBuilder.Entity("Distribution.Models.UserRouteScope", b => + { + b.Property("FK_UserId") + .HasColumnType("char(36)"); + + b.Property("FK_RouteId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("FK_UserId", "FK_RouteId"); + + b.HasIndex("FK_RouteId"); + + b.ToTable("UserRouteScopes"); + }); + + modelBuilder.Entity("Distribution.Models.UserStoreScope", b => + { + b.Property("FK_UserId") + .HasColumnType("char(36)"); + + b.Property("FK_StoreId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("FK_UserId", "FK_StoreId"); + + b.HasIndex("FK_StoreId"); + + b.ToTable("UserStoreScopes"); + }); + + modelBuilder.Entity("Distribution.Models.Vehicle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("NumberPlate") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RegNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Vehicles"); + }); + + modelBuilder.Entity("Distribution.Models.Warehouse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Location") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("VehicleId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("VehicleId"); + + b.ToTable("Warehouses"); + }); + + modelBuilder.Entity("Distribution.Models.DeliveryRun", b => + { + b.HasOne("Distribution.Models.Route", "Route") + .WithMany() + .HasForeignKey("FK_RouteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Vehicle", "Vehicle") + .WithMany() + .HasForeignKey("FK_VehicleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Route"); + + b.Navigation("Vehicle"); + }); + + modelBuilder.Entity("Distribution.Models.Item", b => + { + b.HasOne("Distribution.Models.Uom", "BaseUom") + .WithMany() + .HasForeignKey("FK_BaseUomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Brand", "Brand") + .WithMany() + .HasForeignKey("FK_BrandId"); + + b.HasOne("Distribution.Models.Category", "Category") + .WithMany() + .HasForeignKey("FK_CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.SubCategory", "SubCategory") + .WithMany() + .HasForeignKey("FK_SubCategoryId"); + + b.Navigation("BaseUom"); + + b.Navigation("Brand"); + + b.Navigation("Category"); + + b.Navigation("SubCategory"); + }); + + modelBuilder.Entity("Distribution.Models.Order", b => + { + b.HasOne("Distribution.Models.Store", "Store") + .WithMany() + .HasForeignKey("FK_StoreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Store"); + }); + + modelBuilder.Entity("Distribution.Models.OrderItem", b => + { + b.HasOne("Distribution.Models.Item", "Item") + .WithMany() + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Order", "Order") + .WithMany() + .HasForeignKey("FK_OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("Distribution.Models.PriceList", b => + { + b.HasOne("Distribution.Models.Region", "Region") + .WithMany() + .HasForeignKey("FK_RegionId"); + + b.Navigation("Region"); + }); + + modelBuilder.Entity("Distribution.Models.PriceListItem", b => + { + b.HasOne("Distribution.Models.Item", "Item") + .WithMany() + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.PriceList", "PriceList") + .WithMany("Items") + .HasForeignKey("FK_PriceListId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + + b.Navigation("PriceList"); + }); + + modelBuilder.Entity("Distribution.Models.RolePermission", b => + { + b.HasOne("Distribution.Models.Permission", "Permission") + .WithMany() + .HasForeignKey("FK_PermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Role", "Role") + .WithMany() + .HasForeignKey("FK_RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Distribution.Models.Route", b => + { + b.HasOne("Distribution.Models.Region", "Region") + .WithMany() + .HasForeignKey("FK_RegionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Region"); + }); + + modelBuilder.Entity("Distribution.Models.StockBalance", b => + { + b.HasOne("Distribution.Models.Item", "Item") + .WithMany() + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + }); + + modelBuilder.Entity("Distribution.Models.StockMovement", b => + { + b.HasOne("Distribution.Models.Item", "Item") + .WithMany() + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + }); + + modelBuilder.Entity("Distribution.Models.Store", b => + { + b.HasOne("Distribution.Models.Route", "Route") + .WithMany() + .HasForeignKey("FK_RouteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Route"); + }); + + modelBuilder.Entity("Distribution.Models.StoreKycDocument", b => + { + b.HasOne("Distribution.Models.Store", "Store") + .WithMany() + .HasForeignKey("FK_StoreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Store"); + }); + + modelBuilder.Entity("Distribution.Models.SubCategory", b => + { + b.HasOne("Distribution.Models.Category", "Category") + .WithMany() + .HasForeignKey("FK_CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); + + modelBuilder.Entity("Distribution.Models.UomConversion", b => + { + b.HasOne("Distribution.Models.Uom", "FromUom") + .WithMany() + .HasForeignKey("FK_FromUomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Item", "Item") + .WithMany("Conversions") + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Uom", "ToUom") + .WithMany() + .HasForeignKey("FK_ToUomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("FromUom"); + + b.Navigation("Item"); + + b.Navigation("ToUom"); + }); + + modelBuilder.Entity("Distribution.Models.User", b => + { + b.HasOne("Distribution.Models.User", "ReportsTo") + .WithMany() + .HasForeignKey("FK_ReportsToUserId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("Distribution.Models.Role", "Role") + .WithMany() + .HasForeignKey("FK_RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReportsTo"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Distribution.Models.UserRegionScope", b => + { + b.HasOne("Distribution.Models.Region", "Region") + .WithMany() + .HasForeignKey("FK_RegionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.User", "User") + .WithMany() + .HasForeignKey("FK_UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Region"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Distribution.Models.UserRouteScope", b => + { + b.HasOne("Distribution.Models.Route", "Route") + .WithMany() + .HasForeignKey("FK_RouteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.User", "User") + .WithMany() + .HasForeignKey("FK_UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Route"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Distribution.Models.UserStoreScope", b => + { + b.HasOne("Distribution.Models.Store", "Store") + .WithMany() + .HasForeignKey("FK_StoreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.User", "User") + .WithMany() + .HasForeignKey("FK_UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Store"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Distribution.Models.Warehouse", b => + { + b.HasOne("Distribution.Models.Vehicle", "Vehicle") + .WithMany() + .HasForeignKey("VehicleId"); + + b.Navigation("Vehicle"); + }); + + modelBuilder.Entity("Distribution.Models.Item", b => + { + b.Navigation("Conversions"); + }); + + modelBuilder.Entity("Distribution.Models.PriceList", b => + { + b.Navigation("Items"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Distribution/Migrations/20260820101525_AddPricingAndSuppliers.cs b/Distribution/Migrations/20260820101525_AddPricingAndSuppliers.cs new file mode 100644 index 0000000..39e411f --- /dev/null +++ b/Distribution/Migrations/20260820101525_AddPricingAndSuppliers.cs @@ -0,0 +1,116 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Distribution.Migrations +{ + /// + public partial class AddPricingAndSuppliers : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "PriceLists", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Name = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + FK_RegionId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + EffectiveFrom = table.Column(type: "datetime(6)", nullable: false), + EffectiveTo = table.Column(type: "datetime(6)", nullable: false), + CreatedAt = table.Column(type: "datetime(6)", nullable: false), + IsActive = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PriceLists", x => x.Id); + table.ForeignKey( + name: "FK_PriceLists_Regions_FK_RegionId", + column: x => x.FK_RegionId, + principalTable: "Regions", + principalColumn: "Id"); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Suppliers", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Name = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ContactInfo = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + PerformanceScore = table.Column(type: "decimal(65,30)", nullable: true), + CreatedAt = table.Column(type: "datetime(6)", nullable: false), + IsActive = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Suppliers", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "PriceListItems", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + FK_PriceListId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + FK_ItemId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Price = table.Column(type: "decimal(65,30)", nullable: false), + CreatedAt = table.Column(type: "datetime(6)", nullable: false), + IsActive = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PriceListItems", x => x.Id); + table.ForeignKey( + name: "FK_PriceListItems_Items_FK_ItemId", + column: x => x.FK_ItemId, + principalTable: "Items", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PriceListItems_PriceLists_FK_PriceListId", + column: x => x.FK_PriceListId, + principalTable: "PriceLists", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_PriceListItems_FK_ItemId", + table: "PriceListItems", + column: "FK_ItemId"); + + migrationBuilder.CreateIndex( + name: "IX_PriceListItems_FK_PriceListId_FK_ItemId", + table: "PriceListItems", + columns: new[] { "FK_PriceListId", "FK_ItemId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_PriceLists_FK_RegionId", + table: "PriceLists", + column: "FK_RegionId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "PriceListItems"); + + migrationBuilder.DropTable( + name: "Suppliers"); + + migrationBuilder.DropTable( + name: "PriceLists"); + } + } +} diff --git a/Distribution/Migrations/20260820105946_AddPriceListItemMinPrice.Designer.cs b/Distribution/Migrations/20260820105946_AddPriceListItemMinPrice.Designer.cs new file mode 100644 index 0000000..e07e4b3 --- /dev/null +++ b/Distribution/Migrations/20260820105946_AddPriceListItemMinPrice.Designer.cs @@ -0,0 +1,2616 @@ +// +using System; +using Distribution.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Distribution.Migrations +{ + [DbContext(typeof(AppDBContext))] + [Migration("20260820105946_AddPriceListItemMinPrice")] + partial class AddPriceListItemMinPrice + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("Distribution.Models.Brand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExternalErpId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Brands"); + }); + + modelBuilder.Entity("Distribution.Models.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowCustomerReturn") + .HasColumnType("tinyint(1)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExternalErpId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Distribution.Models.DeliveryRun", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FK_RouteId") + .HasColumnType("char(36)"); + + b.Property("FK_VehicleId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Meterend") + .HasColumnType("int"); + + b.Property("Meterstart") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FK_RouteId"); + + b.HasIndex("FK_VehicleId"); + + b.ToTable("DeliveryRuns"); + }); + + modelBuilder.Entity("Distribution.Models.Item", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("ExternalErpItemId") + .HasColumnType("int"); + + b.Property("FK_BaseUomId") + .HasColumnType("char(36)"); + + b.Property("FK_BrandId") + .HasColumnType("char(36)"); + + b.Property("FK_CategoryId") + .HasColumnType("char(36)"); + + b.Property("FK_SubCategoryId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("LastSyncedAt") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SalePrice") + .HasColumnType("decimal(65,30)"); + + b.Property("Sku") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SyncSource") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FK_BaseUomId"); + + b.HasIndex("FK_BrandId"); + + b.HasIndex("FK_CategoryId"); + + b.HasIndex("FK_SubCategoryId"); + + b.ToTable("Items"); + }); + + modelBuilder.Entity("Distribution.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FK_StoreId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("TotalAmount") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.HasIndex("FK_StoreId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Distribution.Models.OrderItem", b => + { + b.Property("FK_OrderId") + .HasColumnType("char(36)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(65,30)"); + + b.HasKey("FK_OrderId", "FK_ItemId"); + + b.HasIndex("FK_ItemId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Distribution.Models.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Code") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Permissions"); + + b.HasData( + new + { + Id = new Guid("20000000-0000-0000-0000-000000000001"), + Code = "regions.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View regions", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000002"), + Code = "regions.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create regions", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000003"), + Code = "regions.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update regions", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000004"), + Code = "regions.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete regions", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000005"), + Code = "routes.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View routes", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000006"), + Code = "routes.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create routes", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000007"), + Code = "routes.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update routes", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000008"), + Code = "routes.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete routes", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000009"), + Code = "vehicles.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View vehicles", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000010"), + Code = "vehicles.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create vehicles", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000011"), + Code = "vehicles.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update vehicles", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000012"), + Code = "vehicles.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete vehicles", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000013"), + Code = "stores.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View stores", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000014"), + Code = "stores.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create stores", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000015"), + Code = "stores.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update stores", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000016"), + Code = "stores.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete stores", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000017"), + Code = "stores.kyc.verify", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Verify or reject store KYC documents", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000018"), + Code = "stores.credit.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update store credit limit and outstanding balance", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000019"), + Code = "warehouses.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View warehouses", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000020"), + Code = "warehouses.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create warehouses", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000021"), + Code = "warehouses.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update warehouses", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000022"), + Code = "warehouses.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete warehouses", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000023"), + Code = "orders.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View orders", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000024"), + Code = "orders.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create orders", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000025"), + Code = "orders.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update orders", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000026"), + Code = "orders.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete orders", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000027"), + Code = "users.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View users", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000028"), + Code = "users.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create users", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000029"), + Code = "users.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update users", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000030"), + Code = "users.deactivate", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Deactivate users", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000031"), + Code = "users.assign_role", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Assign a role to a user", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000032"), + Code = "users.assign_scope", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Assign region/route/store scope to a user", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000033"), + Code = "items.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View items, brands and UOMs", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000034"), + Code = "items.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create items, brands and UOMs", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000035"), + Code = "items.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update items, brands and UOMs", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000036"), + Code = "items.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete items, brands and UOMs", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000037"), + Code = "categories.view", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "View categories", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000038"), + Code = "categories.create", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Create categories and subcategories", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000039"), + Code = "categories.update", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Update categories and subcategories", + IsActive = true + }, + new + { + Id = new Guid("20000000-0000-0000-0000-000000000040"), + Code = "categories.delete", + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Description = "Delete categories and subcategories", + IsActive = true + }); + }); + + modelBuilder.Entity("Distribution.Models.PriceList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("EffectiveFrom") + .HasColumnType("datetime(6)"); + + b.Property("EffectiveTo") + .HasColumnType("datetime(6)"); + + b.Property("FK_RegionId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_RegionId"); + + b.ToTable("PriceLists"); + }); + + modelBuilder.Entity("Distribution.Models.PriceListItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("FK_PriceListId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("MinPrice") + .HasColumnType("decimal(65,30)"); + + b.Property("Price") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.HasIndex("FK_ItemId"); + + b.HasIndex("FK_PriceListId", "FK_ItemId") + .IsUnique(); + + b.ToTable("PriceListItems"); + }); + + modelBuilder.Entity("Distribution.Models.Region", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Regions"); + }); + + modelBuilder.Entity("Distribution.Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + + b.HasData( + new + { + Id = new Guid("10000000-0000-0000-0000-000000000001"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 10, + Name = "SalesRep" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000002"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 20, + Name = "Supervisor" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000003"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 30, + Name = "AreaManager" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000004"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 40, + Name = "AreaSupervisor" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 50, + Name = "RegionalManager" + }, + new + { + Id = new Guid("10000000-0000-0000-0000-000000000006"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + IsActive = true, + Level = 60, + Name = "RegionalAgency" + }); + }); + + modelBuilder.Entity("Distribution.Models.RolePermission", b => + { + b.Property("FK_RoleId") + .HasColumnType("char(36)"); + + b.Property("FK_PermissionId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("FK_RoleId", "FK_PermissionId"); + + b.HasIndex("FK_PermissionId"); + + b.ToTable("RolePermissions"); + + b.HasData( + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("dfe4bb14-1047-219c-cabe-a2b49b105d86"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c0739b84-50a2-0971-429b-02bab8354c51"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c268a531-44eb-0f29-82ba-18394ac2dcb5"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("0e0613fd-d62c-1e87-a5b6-8bd2c3697c2a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("75737fa8-fed0-d97a-8c24-5716758a7222"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("ddb2d04d-19b0-20b1-2639-b157d12a9eec"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("320ba3fb-666c-ce57-3e61-95c9824c4048"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e1f39dc4-6c33-45f4-8c23-3ad8ae5784a8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("357c36de-9b6c-1c9a-4926-c18a9bccf0ca"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1b126bb0-e582-3e84-4728-a7ab5628fe7b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("eb4ffa50-b09a-f0a5-1994-3fc2ae3a35d0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7ee233b9-3758-e005-7bb2-5ad1edf36e21"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("0f291826-e169-c06a-0735-bd06cbb2062d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("10dd0249-ce04-c5d9-8f94-ccb348c1d979"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f50b201c-6c8d-0df8-85ad-08cb137bc213"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5adb4d1a-eba8-16cb-8603-c3443d4ee8c8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("23105bb1-ef1f-6e19-1a48-d62ccaec1db4"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f2c14d55-d557-5cd2-a70a-4a6f58933436"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5cee999e-1b77-cb87-5148-6a793af7c44e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("73e00ce7-c124-4677-4369-1eb9876852c0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("929950da-d51b-ad5d-c4e5-55175908fb43"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("680b582c-dbc9-cfde-f54b-58c3ad5a57b6"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e9c8355a-26a9-4107-504e-d61722f9e7cd"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d49f086e-30f0-6ce8-ae96-4395d5e04472"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("a41f94ba-c24d-93dc-9f25-c462df19785a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("a9a49749-f99d-3166-5d92-b7e380fcabb2"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("0b7d47cf-efd9-9589-682b-78df22062e5a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4aaa0f3d-4360-5f11-41c1-5257662428af"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d92d572f-f1bf-9e7d-1d4d-7c7b0d575c8e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7fef12f3-6875-14bb-9554-0c9d82f02a37"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f367f6f6-3d26-7a6c-888b-da1a240b59af"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("38ea5531-a29d-a6bb-eebe-a18f3afe066d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b17df3df-022c-c903-6ce0-e6423e648dc8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1e7fe1b6-5150-4b99-38ed-088d9495cfd8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("db15215a-0a16-ef1f-5c82-6bb902a2b319"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7b4f3482-b8bd-d348-e4c1-ae6dc93a3771"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("04ece77e-b36f-8ed0-4ef9-2f6962b6f9c6"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("76f58da8-09f6-c4e2-01bd-ddd94809c1f5"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c6d74049-3f46-88af-1067-c9ae133132f7"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7c392a13-1a57-0d85-dffa-2fb9e892abe9"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d1dcef02-d4c3-caba-372f-dab82011e9c1"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("bf2a2f96-04ed-905d-5a8a-9047d814aa3e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c99adad6-94e8-0d5b-3d35-086f393207fb"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b22d4f78-7a21-da50-5351-553bdf06c9c2"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5e10d61c-2d7a-3388-722f-45232d2cfb71"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("dafe8f7e-e527-5863-5cde-92599c4ba9eb"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d8257363-d838-fe7e-57a5-51b626dbfc83"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3cb22998-b618-c13f-48cd-9e7416f324fc"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("97708eed-6ce4-7710-abde-01d00c0c879b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9afe507e-191e-bdee-0c5a-cfbcbf1efb3e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000006"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("29d71000-6715-de8a-a3af-814938d50dfb"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000007"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f58f4242-af91-0b8d-5be5-4b07b4367e8c"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000016"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e0b27435-f505-43f5-7ed9-4711f2248495"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000036"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9c278616-4289-96fb-944d-b8f1495ccb00"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000038"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9cc36229-dfba-49b9-1d6e-8929546e894d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000039"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("a66f3854-5a8f-95c2-cb1c-b2b2e67ee226"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000040"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("14bcecd1-b1a2-6da3-155a-233611484467"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4d682c93-d6df-4214-436d-85f76a3ade93"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4b2c3b3b-c27d-410c-c1fc-7e43e280242f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1d227ae7-0eb9-c742-41df-3472718cb077"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4d287b19-ba40-7d4d-3d39-291be64197f8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("fcc6af61-cc43-066c-5634-2ddc24a8460d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("2f994b6b-b055-28c2-2fb1-99a0076a0e3f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("55e84a29-428d-bf95-d589-793ecd8bac6e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000016"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("43ec940a-44d2-9c47-a37d-049f2cfb2615"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("ee175c87-23bd-5529-ed18-6ce46985c6ed"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("2ae2eba4-4427-ab1e-cf03-e59a3925ef89"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d95e7d5a-b12c-12b8-fee9-39576c905fed"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000006"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d97abb20-e53d-c970-d337-3764584874fa"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000007"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("a63446ad-14a9-6239-8791-0a1f86813903"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000008"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7f9502a2-feb4-f0ef-cb71-a62d00570fd0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d1f4316a-72a0-66af-2a8a-1fdbdb4f8c3a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000010"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("30e94e9b-c70c-2df3-0813-e99ce4511838"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000011"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("94f2f2ec-94b7-b768-76a4-9ee4256d95c1"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000012"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7201efa2-f829-8035-6607-174214f8fdba"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("c88131d2-51b2-2bac-ad15-c7c130eb26f8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000020"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3a2ccc28-7416-388d-17f2-424d0520049f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("08de9913-8cfc-4ab4-2cb9-2bc9217fbb6e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f3c8f315-3b2f-f923-e3cd-f3e575010138"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000001"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3e3e6f06-72c8-42fa-f7e6-8feeaca36d60"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000027"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("43a4c7b4-a50f-aa37-b147-a30636d9d65f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("0efa7259-aadb-0019-4be5-38d3f8f4cd54"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9e60e7d7-8bd6-c1c7-4bf1-4de2c9dcb91c"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5df82318-bc01-1947-09ef-60508e02b257"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000036"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("34f478f4-6c96-4b31-b68a-28c7942c0789"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("69598e0e-b7ad-477b-c587-7abf6189162d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000038"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b36fb2d4-43df-44f8-ff51-de6d88644c94"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000039"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("aeb29e0e-e819-1446-6cc6-1fb64b5ecc6b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000040"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e18a6eca-1009-bcc6-35e9-ead943c1649f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000001"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("f64e20e2-f9ca-7ea5-42f4-c1256b0c0798"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000002"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7b6765bc-1510-cfc6-55ae-ac689caf0dcc"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000003"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d9e06d2d-82d6-84e8-e9ba-5406e9b4122d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000004"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b53e01bb-4e54-3270-87b1-0d54f947e09b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("111b7d3c-3640-66e6-0757-b9fb67572943"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000006"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("7ee06ff0-8557-b5bd-02dc-c4ff99e76348"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000007"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d20bcba0-a5af-de47-919d-a8645a828d27"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000008"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("b3ef35de-afc2-d80a-115f-77ba954f9586"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d1b7e0a2-149f-b56b-8c63-bb8d10bfcc1e"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000010"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("51e06fd0-cd20-ceeb-04cc-7dc79388c4a1"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000011"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("25639115-7083-1324-c3bd-3ad90fcfa1a0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000012"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("51011cb7-5753-14ad-280c-86a6bd33124f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("51ce3fad-cdbc-cfad-6cf0-52b47ec3f200"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000014"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4a080973-c23f-3d1b-9883-6b7e06025a77"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000015"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3f78910a-76ee-f34b-52d3-af79d7f3b724"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000016"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("812cbb8d-e268-aad3-373e-42b8720f0f45"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("046cd13e-77f1-78c7-fa52-d49ea7fb9855"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("96f24adf-386d-14d0-46fe-a22ceff2f79b"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("9b5f23fb-2396-3f43-1d3e-97551eb4248d"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000020"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("30397d69-3b96-56e7-0ca1-1e612dfb64f1"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("91260fa1-3754-ad7e-10d8-2a8fd9b208ff"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("8b993e65-b066-198a-385d-602660ed85ac"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000023"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("248d6092-c2e5-5f8f-5ef0-cd60dc94cbc8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000024"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("5f6e3c68-27d2-e00f-d5c9-4ce9e2b9587f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("96a4ac9e-cfea-6391-8020-75b2980bf2a3"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("6eb59953-807d-aa61-29e3-1699c0aebda9"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000027"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1095440c-ce52-235b-b95f-6b28c5d1b3a8"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000028"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3a56ab5c-f0c5-a37b-0795-de061597628f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000029"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("104ebcfb-ca82-3f95-d75e-35a943618176"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000030"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("ace990cf-6654-5e68-3dc8-1e62347e0946"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000031"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("bd209f90-6671-8ea0-eb20-aa151faec6a0"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000032"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("4cc32686-8391-0214-5747-db14f53c5b6f"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("26c6d86a-835d-6f0d-3730-66a46ea26b11"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("e8039d9c-a286-fb74-5abb-b5c6c67f243a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("d9e038cb-bcff-cce1-5d34-b4e63a9ce694"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000036"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("343e71f0-da6b-2489-5571-f8d7c6378ee7"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("ac894328-a935-8e6e-8427-6c0f36ac75da"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000038"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("1d6273d4-db6a-d70e-4b5f-98cb634d668a"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000039"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("3f32cdac-6925-23f2-064e-8226d781d4a3"), + IsActive = true + }, + new + { + FK_RoleId = new Guid("10000000-0000-0000-0000-000000000006"), + FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000040"), + CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), + Id = new Guid("dc3dd9ff-b123-a8d4-dcea-b4f5f8ff171e"), + IsActive = true + }); + }); + + modelBuilder.Entity("Distribution.Models.Route", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("EndPoint") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FK_RegionId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Length") + .HasColumnType("decimal(65,30)"); + + b.Property("RouteName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StartPoint") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_RegionId"); + + b.ToTable("Routes"); + }); + + modelBuilder.Entity("Distribution.Models.SaleRoute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("SaleRoutes"); + }); + + modelBuilder.Entity("Distribution.Models.StockBalance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("LocationId") + .HasColumnType("char(36)"); + + b.Property("LocationType") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("decimal(65,30)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("FK_ItemId", "LocationId") + .IsUnique(); + + b.ToTable("StockBalances"); + }); + + modelBuilder.Entity("Distribution.Models.StockMovement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedBy") + .HasColumnType("char(36)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("FromLocationId") + .HasColumnType("char(36)"); + + b.Property("FromLocationType") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("decimal(65,30)"); + + b.Property("ReasonCode") + .HasColumnType("longtext"); + + b.Property("ReferenceId") + .HasColumnType("char(36)"); + + b.Property("ToLocationId") + .HasColumnType("char(36)"); + + b.Property("ToLocationType") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FK_ItemId"); + + b.ToTable("StockMovements"); + }); + + modelBuilder.Entity("Distribution.Models.Store", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreditAmount") + .HasColumnType("decimal(65,30)"); + + b.Property("CreditLimit") + .HasColumnType("decimal(65,30)"); + + b.Property("FK_RouteId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("KycStatus") + .HasColumnType("int"); + + b.Property("Latitude") + .HasColumnType("decimal(65,30)"); + + b.Property("Longitude") + .HasColumnType("decimal(65,30)"); + + b.Property("OneTimeAmount") + .HasColumnType("decimal(65,30)"); + + b.Property("OutstandingBalance") + .HasColumnType("decimal(65,30)"); + + b.Property("OwnerName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Segment") + .HasColumnType("longtext"); + + b.Property("StoreAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StoreName") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_RouteId"); + + b.ToTable("Stores"); + }); + + modelBuilder.Entity("Distribution.Models.StoreKycDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("DocumentType") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FK_StoreId") + .HasColumnType("char(36)"); + + b.Property("FileReference") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("UploadedAt") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("FK_StoreId"); + + b.ToTable("StoreKycDocuments"); + }); + + modelBuilder.Entity("Distribution.Models.SubCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExternalErpId") + .HasColumnType("int"); + + b.Property("FK_CategoryId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_CategoryId"); + + b.ToTable("SubCategories"); + }); + + modelBuilder.Entity("Distribution.Models.Supplier", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContactInfo") + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PerformanceScore") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.ToTable("Suppliers"); + }); + + modelBuilder.Entity("Distribution.Models.Uom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExternalErpId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Uoms"); + }); + + modelBuilder.Entity("Distribution.Models.UomConversion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("FK_FromUomId") + .HasColumnType("char(36)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("FK_ToUomId") + .HasColumnType("char(36)"); + + b.Property("Factor") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.HasIndex("FK_FromUomId"); + + b.HasIndex("FK_ItemId"); + + b.HasIndex("FK_ToUomId"); + + b.ToTable("UomConversions"); + }); + + modelBuilder.Entity("Distribution.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FK_ReportsToUserId") + .HasColumnType("char(36)"); + + b.Property("FK_RoleId") + .HasColumnType("char(36)"); + + b.Property("FullName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_ReportsToUserId"); + + b.HasIndex("FK_RoleId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Distribution.Models.UserRegionScope", b => + { + b.Property("FK_UserId") + .HasColumnType("char(36)"); + + b.Property("FK_RegionId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("FK_UserId", "FK_RegionId"); + + b.HasIndex("FK_RegionId"); + + b.ToTable("UserRegionScopes"); + }); + + modelBuilder.Entity("Distribution.Models.UserRouteScope", b => + { + b.Property("FK_UserId") + .HasColumnType("char(36)"); + + b.Property("FK_RouteId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("FK_UserId", "FK_RouteId"); + + b.HasIndex("FK_RouteId"); + + b.ToTable("UserRouteScopes"); + }); + + modelBuilder.Entity("Distribution.Models.UserStoreScope", b => + { + b.Property("FK_UserId") + .HasColumnType("char(36)"); + + b.Property("FK_StoreId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.HasKey("FK_UserId", "FK_StoreId"); + + b.HasIndex("FK_StoreId"); + + b.ToTable("UserStoreScopes"); + }); + + modelBuilder.Entity("Distribution.Models.Vehicle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("NumberPlate") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RegNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Vehicles"); + }); + + modelBuilder.Entity("Distribution.Models.Warehouse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Location") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("VehicleId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("VehicleId"); + + b.ToTable("Warehouses"); + }); + + modelBuilder.Entity("Distribution.Models.DeliveryRun", b => + { + b.HasOne("Distribution.Models.Route", "Route") + .WithMany() + .HasForeignKey("FK_RouteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Vehicle", "Vehicle") + .WithMany() + .HasForeignKey("FK_VehicleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Route"); + + b.Navigation("Vehicle"); + }); + + modelBuilder.Entity("Distribution.Models.Item", b => + { + b.HasOne("Distribution.Models.Uom", "BaseUom") + .WithMany() + .HasForeignKey("FK_BaseUomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Brand", "Brand") + .WithMany() + .HasForeignKey("FK_BrandId"); + + b.HasOne("Distribution.Models.Category", "Category") + .WithMany() + .HasForeignKey("FK_CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.SubCategory", "SubCategory") + .WithMany() + .HasForeignKey("FK_SubCategoryId"); + + b.Navigation("BaseUom"); + + b.Navigation("Brand"); + + b.Navigation("Category"); + + b.Navigation("SubCategory"); + }); + + modelBuilder.Entity("Distribution.Models.Order", b => + { + b.HasOne("Distribution.Models.Store", "Store") + .WithMany() + .HasForeignKey("FK_StoreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Store"); + }); + + modelBuilder.Entity("Distribution.Models.OrderItem", b => + { + b.HasOne("Distribution.Models.Item", "Item") + .WithMany() + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Order", "Order") + .WithMany() + .HasForeignKey("FK_OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("Distribution.Models.PriceList", b => + { + b.HasOne("Distribution.Models.Region", "Region") + .WithMany() + .HasForeignKey("FK_RegionId"); + + b.Navigation("Region"); + }); + + modelBuilder.Entity("Distribution.Models.PriceListItem", b => + { + b.HasOne("Distribution.Models.Item", "Item") + .WithMany() + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.PriceList", "PriceList") + .WithMany("Items") + .HasForeignKey("FK_PriceListId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + + b.Navigation("PriceList"); + }); + + modelBuilder.Entity("Distribution.Models.RolePermission", b => + { + b.HasOne("Distribution.Models.Permission", "Permission") + .WithMany() + .HasForeignKey("FK_PermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Role", "Role") + .WithMany() + .HasForeignKey("FK_RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Distribution.Models.Route", b => + { + b.HasOne("Distribution.Models.Region", "Region") + .WithMany() + .HasForeignKey("FK_RegionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Region"); + }); + + modelBuilder.Entity("Distribution.Models.StockBalance", b => + { + b.HasOne("Distribution.Models.Item", "Item") + .WithMany() + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + }); + + modelBuilder.Entity("Distribution.Models.StockMovement", b => + { + b.HasOne("Distribution.Models.Item", "Item") + .WithMany() + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + }); + + modelBuilder.Entity("Distribution.Models.Store", b => + { + b.HasOne("Distribution.Models.Route", "Route") + .WithMany() + .HasForeignKey("FK_RouteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Route"); + }); + + modelBuilder.Entity("Distribution.Models.StoreKycDocument", b => + { + b.HasOne("Distribution.Models.Store", "Store") + .WithMany() + .HasForeignKey("FK_StoreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Store"); + }); + + modelBuilder.Entity("Distribution.Models.SubCategory", b => + { + b.HasOne("Distribution.Models.Category", "Category") + .WithMany() + .HasForeignKey("FK_CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); + + modelBuilder.Entity("Distribution.Models.UomConversion", b => + { + b.HasOne("Distribution.Models.Uom", "FromUom") + .WithMany() + .HasForeignKey("FK_FromUomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Item", "Item") + .WithMany("Conversions") + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.Uom", "ToUom") + .WithMany() + .HasForeignKey("FK_ToUomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("FromUom"); + + b.Navigation("Item"); + + b.Navigation("ToUom"); + }); + + modelBuilder.Entity("Distribution.Models.User", b => + { + b.HasOne("Distribution.Models.User", "ReportsTo") + .WithMany() + .HasForeignKey("FK_ReportsToUserId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("Distribution.Models.Role", "Role") + .WithMany() + .HasForeignKey("FK_RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReportsTo"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Distribution.Models.UserRegionScope", b => + { + b.HasOne("Distribution.Models.Region", "Region") + .WithMany() + .HasForeignKey("FK_RegionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.User", "User") + .WithMany() + .HasForeignKey("FK_UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Region"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Distribution.Models.UserRouteScope", b => + { + b.HasOne("Distribution.Models.Route", "Route") + .WithMany() + .HasForeignKey("FK_RouteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.User", "User") + .WithMany() + .HasForeignKey("FK_UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Route"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Distribution.Models.UserStoreScope", b => + { + b.HasOne("Distribution.Models.Store", "Store") + .WithMany() + .HasForeignKey("FK_StoreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.User", "User") + .WithMany() + .HasForeignKey("FK_UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Store"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Distribution.Models.Warehouse", b => + { + b.HasOne("Distribution.Models.Vehicle", "Vehicle") + .WithMany() + .HasForeignKey("VehicleId"); + + b.Navigation("Vehicle"); + }); + + modelBuilder.Entity("Distribution.Models.Item", b => + { + b.Navigation("Conversions"); + }); + + modelBuilder.Entity("Distribution.Models.PriceList", b => + { + b.Navigation("Items"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Distribution/Migrations/20260820105946_AddPriceListItemMinPrice.cs b/Distribution/Migrations/20260820105946_AddPriceListItemMinPrice.cs new file mode 100644 index 0000000..1a2d20f --- /dev/null +++ b/Distribution/Migrations/20260820105946_AddPriceListItemMinPrice.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Distribution.Migrations +{ + /// + public partial class AddPriceListItemMinPrice : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "MinPrice", + table: "PriceListItems", + type: "decimal(65,30)", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "MinPrice", + table: "PriceListItems"); + } + } +} diff --git a/Distribution/Migrations/AppDBContextModelSnapshot.cs b/Distribution/Migrations/AppDBContextModelSnapshot.cs index 9799916..1a8ac31 100644 --- a/Distribution/Migrations/AppDBContextModelSnapshot.cs +++ b/Distribution/Migrations/AppDBContextModelSnapshot.cs @@ -571,6 +571,72 @@ namespace Distribution.Migrations }); }); + modelBuilder.Entity("Distribution.Models.PriceList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("EffectiveFrom") + .HasColumnType("datetime(6)"); + + b.Property("EffectiveTo") + .HasColumnType("datetime(6)"); + + b.Property("FK_RegionId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FK_RegionId"); + + b.ToTable("PriceLists"); + }); + + modelBuilder.Entity("Distribution.Models.PriceListItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FK_ItemId") + .HasColumnType("char(36)"); + + b.Property("FK_PriceListId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("MinPrice") + .HasColumnType("decimal(65,30)"); + + b.Property("Price") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.HasIndex("FK_ItemId"); + + b.HasIndex("FK_PriceListId", "FK_ItemId") + .IsUnique(); + + b.ToTable("PriceListItems"); + }); + modelBuilder.Entity("Distribution.Models.Region", b => { b.Property("Id") @@ -1973,6 +2039,33 @@ namespace Distribution.Migrations b.ToTable("SubCategories"); }); + modelBuilder.Entity("Distribution.Models.Supplier", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContactInfo") + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PerformanceScore") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.ToTable("Suppliers"); + }); + modelBuilder.Entity("Distribution.Models.Uom", b => { b.Property("Id") @@ -2281,6 +2374,34 @@ namespace Distribution.Migrations b.Navigation("Order"); }); + modelBuilder.Entity("Distribution.Models.PriceList", b => + { + b.HasOne("Distribution.Models.Region", "Region") + .WithMany() + .HasForeignKey("FK_RegionId"); + + b.Navigation("Region"); + }); + + modelBuilder.Entity("Distribution.Models.PriceListItem", b => + { + b.HasOne("Distribution.Models.Item", "Item") + .WithMany() + .HasForeignKey("FK_ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Distribution.Models.PriceList", "PriceList") + .WithMany("Items") + .HasForeignKey("FK_PriceListId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + + b.Navigation("PriceList"); + }); + modelBuilder.Entity("Distribution.Models.RolePermission", b => { b.HasOne("Distribution.Models.Permission", "Permission") @@ -2481,6 +2602,11 @@ namespace Distribution.Migrations { b.Navigation("Conversions"); }); + + modelBuilder.Entity("Distribution.Models.PriceList", b => + { + b.Navigation("Items"); + }); #pragma warning restore 612, 618 } } diff --git a/Distribution/Models/PriceList.cs b/Distribution/Models/PriceList.cs new file mode 100644 index 0000000..9b86001 --- /dev/null +++ b/Distribution/Models/PriceList.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace Distribution.Models +{ + public class PriceList : Template + { + public string Name { get; set; } + + public Guid? FK_RegionId { get; set; } + [ForeignKey("FK_RegionId")] + public Region? Region { get; set; } + + public DateTime EffectiveFrom { get; set; } + public DateTime EffectiveTo { get; set; } + + public ICollection Items { get; set; } = []; + } +} diff --git a/Distribution/Models/PriceListItem.cs b/Distribution/Models/PriceListItem.cs new file mode 100644 index 0000000..f9b7b24 --- /dev/null +++ b/Distribution/Models/PriceListItem.cs @@ -0,0 +1,23 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace Distribution.Models +{ + public class PriceListItem : Template + { + public Guid FK_PriceListId { get; set; } + [ForeignKey("FK_PriceListId")] + public PriceList PriceList { get; set; } + + public Guid FK_ItemId { get; set; } + [ForeignKey("FK_ItemId")] + public Item Item { get; set; } + + public decimal Price { get; set; } + + /// + /// Floor price for negotiation. Null = no negotiation allowed, Price is fixed. + /// Must be less than or equal to Price when set. + /// + public decimal? MinPrice { get; set; } + } +} diff --git a/Distribution/Models/Supplier.cs b/Distribution/Models/Supplier.cs new file mode 100644 index 0000000..baba4fb --- /dev/null +++ b/Distribution/Models/Supplier.cs @@ -0,0 +1,11 @@ +namespace Distribution.Models +{ + public class Supplier : Template + { + public string Name { get; set; } + public string? ContactInfo { get; set; } + public decimal? PerformanceScore { get; set; } + } +} + + diff --git a/Distribution/Program.cs b/Distribution/Program.cs index 3569321..ff8f51f 100644 --- a/Distribution/Program.cs +++ b/Distribution/Program.cs @@ -5,11 +5,13 @@ using Distribution.Features.Brand; using Distribution.Features.Category; using Distribution.Features.Item; using Distribution.Features.Order; +using Distribution.Features.PriceList; using Distribution.Features.Region; using Distribution.Features.Role; using Distribution.Features.Route; using Distribution.Features.Store; using Distribution.Features.Store.Kyc; +using Distribution.Features.Supplier; using Distribution.Features.Sync; using Distribution.Features.Uom; using Distribution.Features.User; @@ -48,6 +50,8 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -65,6 +69,8 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddHttpContextAccessor(); builder.Services.AddScoped(); -- 2.52.0 From b2681d1236054a960f82fe1b25590529a0ad8204 Mon Sep 17 00:00:00 2001 From: DeepnaPooja Date: Thu, 20 Aug 2026 17:29:11 +0530 Subject: [PATCH 2/2] Update pricing and store implementation plans --- Distribution/docs/14_pricing_and_suppliers.md | 335 ++++++++++++++++-- Distribution/docs/mainPlan.md | 33 +- 2 files changed, 326 insertions(+), 42 deletions(-) diff --git a/Distribution/docs/14_pricing_and_suppliers.md b/Distribution/docs/14_pricing_and_suppliers.md index ea0ca15..4719ee1 100644 --- a/Distribution/docs/14_pricing_and_suppliers.md +++ b/Distribution/docs/14_pricing_and_suppliers.md @@ -1,7 +1,7 @@ # 14 — Pricing & Supplier Master Data -**Status**: Not Started -**Depends On**: 01 — Item Catalog +**Status**: Done — migration applied to the database +**Depends On**: 01 — Item Catalog (Done) --- @@ -15,56 +15,339 @@ records. `createProduct`/`deactivateSku` live in 01; this step is everything els ## Background / Context -`Item.BasePrice` (from [01_item_catalog.md](./01_item_catalog.md)) is a single flat price. There is -no concept of a region- or date-scoped price list, and no `Supplier` entity anywhere in the schema. +`Item.SalePrice` (from [01_item_catalog.md](./01_item_catalog.md)) is a single flat, optional price +— `OrderItem.UnitPrice` is captured from it at order-creation time, or supplied manually if +`SalePrice` is null. There is no concept of a region- or date-scoped price list, and no `Supplier` +entity anywhere in the schema. + +`applyPricingAndDiscounts` ([mainPlan.md §1](./mainPlan.md#1-order-management-lifecycle)) is the +function that resolves the actual price for an order line; this step implements the price-list half +of it (region + date scoping). The discount/scheme half stays out of scope until +[17_promotions_schemes.md](./17_promotions_schemes.md) lands — until then `applyPricingAndDiscounts` +only walks price lists, never scheme discounts. + +Resolved in planning discussion (2026-08-20): price lists are **region-only in v1**, not +segment-scoped. `Store.Segment` ([12_store_management.md](./12_store_management.md)) is not +consulted by pricing. Segment-based pricing can be added as a later step without breaking this +model, since it would only add an optional new scoping column. + +### Negotiable price range (Min/Max) + +An item's price within a price list can float in a band instead of being fixed: the same actor who +creates the price list (`pricing.create`/`pricing.update`, AreaManager and above) sets both a +**ceiling** (`Price` — the list/default price) and an optional **floor** (`MinPrice`) below which no +order for that item may be priced. The sales rep/driver placing the order can then supply any +`UnitPrice` within `[MinPrice, Price]` on `OrderItemRequest` instead of always taking the resolved +default — the same negotiation-boundary pattern already used for discount limits in +[08_sales_agent_controls.md](./08_sales_agent_controls.md). + +- `PriceListItem.MinPrice (decimal?)` — `null` = no negotiation, the item is fixed at `Price`. +- `PUT /api/price-lists/{id}/items/{sku}` accepts `{ "price": ..., "minPrice": ... }`; rejected with + 409 if `MinPrice > Price`. +- `OrderService.CreateAsync` validates any caller-supplied `OrderItemRequest.UnitPrice` against + `[MinPrice ?? Price, Price]` for that item's resolved price (region-scoped list → global list; + the `Item.SalePrice` fallback has no `MinPrice` and is always fixed). The order is rejected + (400, via a null resolution) if the requested price falls outside the band, or if no price can be + resolved at all. --- ## Data Model Changes -### Price List +### PriceList +``` +PriceList +├── Id (Guid) — PK, from Template +├── Name (string) +├── FK_RegionId (Guid?) — nullable, null = global (applies to all regions) +├── EffectiveFrom (DateTime) +├── EffectiveTo (DateTime) +├── IsActive, CreatedAt — from Template +``` -`Name`, `RegionId` (nullable — null means global), `EffectiveFrom`, `EffectiveTo`. - -### Price List Item - -`PriceListId`, `ItemId`, `Price` — overrides `Item.BasePrice` when an applicable, currently- -effective price list exists for the order's region. +### PriceListItem +``` +PriceListItem +├── Id (Guid) — PK, from Template +├── FK_PriceListId (Guid) — required +├── FK_ItemId (Guid) — required +├── Price (decimal) — ceiling/list price, overrides Item.SalePrice for this item while +│ the parent PriceList is active and applicable to the order's region +├── MinPrice (decimal?) — nullable floor for negotiated pricing; null = Price is fixed. +│ Must be <= Price when set. +├── IsActive, CreatedAt — from Template +``` +Unique constraint on `(PriceListId, ItemId)` — one price per item per price list. ### Supplier +``` +Supplier +├── Id (Guid) — PK, from Template +├── Name (string) +├── ContactInfo (string?) — free text (phone/email/address), matches ContactInfo pattern +│ used elsewhere rather than splitting into separate columns +├── PerformanceScore (decimal?) — nullable, populated by 15_procurement.md's evaluateSupplier; +│ this step only defines the column and leaves it null-only +├── IsActive, CreatedAt — from Template +``` -`Name`, `ContactInfo`, `PerformanceScore` (nullable, populated by -[15_procurement.md](./15_procurement.md)'s `evaluateSupplier`). +--- + +## Migrations + +One migration needed: +1. **AddPricingAndSuppliers** — creates `PriceLists`, `PriceListItems`, `Suppliers` tables. --- ## API Endpoints -| Function reference | Endpoint intent | -|---|---| -| `createPriceList(name, region, effectiveDates)` | `POST /api/price-lists` | -| `updateProductPricing(sku, priceListId, price)` | `PUT /api/price-lists/{id}/items/{sku}` | -| `createSupplierMaster(supplierData)` | `POST /api/suppliers` | +> Permission column names the target policy for each route; enforcement is **not implemented yet** +> — see [Permissions to Add to Seed](#permissions-to-add-to-seed). Endpoints require +> authentication only until seeding is turned on. + +### Price Lists +| Method | Route | Permission | Notes | +|---|---|---|---| +| GET | /api/price-lists | pricing.view | Filterable by region, active-on-date | +| GET | /api/price-lists/{id} | pricing.view | Includes items | +| POST | /api/price-lists | pricing.create | `createPriceList(name, region, effectiveDates)` | +| PUT | /api/price-lists/{id} | pricing.update | Rejects if new dates overlap another price list for any shared `(ItemId, RegionId)` pair | +| DELETE | /api/price-lists/{id} | pricing.delete | Soft delete | +| PUT | /api/price-lists/{id}/items/{sku} | pricing.update | `updateProductPricing(sku, priceListId, price)` — upserts the `PriceListItem` row | +| DELETE | /api/price-lists/{id}/items/{sku} | pricing.update | Removes an item's override from the price list | + +### Suppliers +| Method | Route | Permission | Notes | +|---|---|---|---| +| GET | /api/suppliers | suppliers.view | | +| GET | /api/suppliers/{id} | suppliers.view | | +| POST | /api/suppliers | suppliers.create | `createSupplierMaster(supplierData)` | +| PUT | /api/suppliers/{id} | suppliers.update | Cannot set `PerformanceScore` directly — that field is read-only via this endpoint, only 15_procurement.md's `evaluateSupplier` writes it | +| DELETE | /api/suppliers/{id} | suppliers.delete | Soft delete, blocked if any PurchaseOrder references it (enforced once 15_procurement.md exists; no-op check until then) | + +--- + +## Request / Response Shapes + +### POST `/api/price-lists` +```json +{ "name": "North Region Q3", "regionId": "...", "effectiveFrom": "2026-09-01", "effectiveTo": "2026-09-30" } +``` +`regionId` omitted or null = global price list. + +### PUT `/api/price-lists/{id}/items/{sku}` +```json +{ "price": 125.50, "minPrice": 115.00 } +``` +Resolves `sku` to `ItemId`, upserts the `PriceListItem` row. `minPrice` is optional — omit or send +`null` for a fixed, non-negotiable price. Rejected with 409 if `minPrice > price`. + +### POST `/api/suppliers` +```json +{ "name": "Acme Distributors", "contactInfo": "acme@example.com, +91-98765-43210" } +``` --- ## Business Rules -- `applyPricingAndDiscounts` (§1, used in [01_item_catalog.md](./01_item_catalog.md) and - [06_sale_ride.md](./06_sale_ride.md)) resolves price in this order: region-scoped active price - list → global active price list → `Item.BasePrice`. -- Two price lists cannot have overlapping `EffectiveFrom`/`EffectiveTo` ranges for the same - `(ItemId, RegionId)` pair. +1. `applyPricingAndDiscounts` resolves the unit price for an order line in this order: + region-scoped active price list → global active price list → `Item.SalePrice` → reject if all + three are absent (order creation requires an explicit price, per rule 10 of + [01_item_catalog.md](./01_item_catalog.md)). + - "Active" means `EffectiveFrom <= orderDate <= EffectiveTo` and `IsActive = true`. + - "Region-scoped" means `PriceList.RegionId` equals the order's store's region. + - If more than one region-scoped price list is active for the same region (shouldn't happen + given rule 2, but defensively), the most recently created one wins. +2. Two active price lists cannot have overlapping `EffectiveFrom`/`EffectiveTo` ranges for the same + `(ItemId, RegionId)` pair — checked at the `PriceListItem` level (a global list and a region list + with the same item may coexist since region-scoped always wins in resolution, so the overlap + check only compares price lists with the *same* `RegionId` value, including both being null). +3. A `PriceList` cannot be deleted (soft delete) while any `PriceListItem` under it is still active + — delete/deactivate the items first, or cascade-deactivate them in the same transaction (cascade + chosen: deleting a price list deactivates all its `PriceListItem` rows in the same + unit-of-work). +4. `Supplier.PerformanceScore` is null until [15_procurement.md](./15_procurement.md)'s + `evaluateSupplier` sets it; no endpoint in this step writes a non-null value. +5. A `Supplier` cannot be hard-deleted, ever — soft delete only, matching the `Template.IsActive` + convention used across the codebase. +6. `PriceListItem.MinPrice`, when set, must be `<= Price` — enforced on every write via + `PUT /api/price-lists/{id}/items/{sku}` (409 if violated). +7. At order time, a caller-supplied `OrderItemRequest.UnitPrice` must fall within + `[MinPrice ?? Price, Price]` for the item's resolved `PriceListItem` (region-scoped, then + global). The `Item.SalePrice` fallback has no `MinPrice` — always fixed, no negotiation. An + out-of-band price, or no resolvable price at all, rejects the whole order (400). + +--- + +## Permissions to Add to Seed + +**Status: Not implemented for now.** Endpoints in this step are built without permission +enforcement (no `[Authorize(Policy = ...)]` gate) until explicitly requested. The codes and role +assignments below are the target design to wire in later — keep them here as the reference, not as +something to seed yet. + +Target permission codes (not yet in `RoleAndPermissionSeed.cs`): +``` +pricing.view, pricing.create, pricing.update, pricing.delete +suppliers.view, suppliers.create, suppliers.update, suppliers.delete +``` + +Target role assignments (mirrors the [01_item_catalog.md](./01_item_catalog.md) items/categories +pattern), for when seeding is turned on: +- **SalesRep (10)**: pricing.view +- **Supervisor (20)**: pricing.view +- **AreaManager (30)**: pricing.view, pricing.create, pricing.update, suppliers.view +- **AreaSupervisor (40)**: all pricing + supplier permissions +- **RegionalManager (50)**: all pricing + supplier permissions +- **RegionalAgency (60)**: all pricing + supplier permissions --- ## Open Questions -- Are price lists customer/segment-specific as well as region-specific (ties into `Store.Segment` - from [12_store_management.md](./12_store_management.md)), or region-only in v1? +- None. Resolved in planning discussion (2026-08-20): price lists are region-only in v1 + (no `Store.Segment` scoping); deleting a price list cascades to deactivate its items rather than + being blocked by them. --- ## Implementation Notes -> Fill this section in during planning discussion before writing any code. +### File structure created / touched +``` +Features/ + PriceList/ + PriceListController.cs + PriceListDTOs.cs + PriceListService.cs (ResolveUnitPriceAsync — the price-list half of applyPricingAndDiscounts) + IPriceListRepository.cs + PriceListRepository.cs + Supplier/ + SupplierController.cs + SupplierDTOs.cs + SupplierService.cs + ISupplierRepository.cs + SupplierRepository.cs + Order/ + OrderDTOs.cs (extended — OrderItemRequest gained an optional UnitPrice override + for the SalePrice-is-null / no-price-list-match case; OrderItemResponse + now echoes the captured UnitPrice) + OrderService.cs (extended — CreateAsync resolves each line's price via a private + ResolveUnitPriceAsync that calls PriceListService, using the request's + UnitPrice override if supplied; rejects the order (returns null) if no + price can be resolved at all) + Item/ + IItemRepository.cs / ItemRepository.cs (extended — GetBySkuAsync, needed to resolve the + {sku} route segment on the price-list item endpoints) + Store/ + IStoreRepository.cs / StoreRepository.cs (extended — GetByIdWithRegionAsync, includes + Store.Route.Region so OrderService can read the + store's RegionId for price resolution) + +Models/ + PriceList.cs (new) + PriceListItem.cs (new) + Supplier.cs (new) + +Data/AppDBContext.cs + add PriceLists, PriceListItems, Suppliers DbSets; unique index on + PriceListItem(FK_PriceListId, FK_ItemId) + +Migrations/ + AddPricingAndSuppliers (applied) + +Program.cs + register IPriceListRepository/PriceListRepository, ISupplierRepository/SupplierRepository, + PriceListService, SupplierService + +Data/Seed/ + RoleAndPermissionSeed.cs — untouched. Permission enforcement is intentionally deferred (see + Permissions to Add to Seed above); controllers use plain [Authorize] + with no policy for now. +``` + +### Price resolution logic (pseudo) +``` +ResolveUnitPriceAsync(itemId, storeId, orderDate): + regionId = store.RegionId + regionList = active PriceListItem where ItemId = itemId + and PriceList.RegionId = regionId + and PriceList.EffectiveFrom <= orderDate <= PriceList.EffectiveTo + and PriceList.IsActive and PriceListItem.IsActive + order by PriceList.CreatedAt desc, take 1 + if regionList found: return regionList.Price + + globalList = same query with PriceList.RegionId = null + if globalList found: return globalList.Price + + if item.SalePrice != null: return item.SalePrice + return null // caller (OrderService) rejects with 400 if no explicit price was supplied +``` + +### Overlap validation on price list write (pseudo) +``` +On PUT /api/price-lists/{id}/items/{sku} or POST /api/price-lists: + for each ItemId affected, check existing PriceListItem rows joined to PriceList + where PriceList.RegionId = this.RegionId (both null counts as a match) + and PriceList.Id != this.Id + and date ranges overlap (existing.EffectiveFrom <= new.EffectiveTo + and existing.EffectiveTo >= new.EffectiveFrom) + → reject with 400 if any match found +``` + +--- + +## Worked Example + +Item `COKE-330` has `SalePrice = 100`. Store `S1` is in the North region. + +**Set up a negotiable region price list:** +``` +POST /api/price-lists +{ "name": "North Region September", "regionId": "", + "effectiveFrom": "2026-09-01", "effectiveTo": "2026-09-30" } +→ PriceList A (RegionId = North) + +PUT /api/price-lists/{A.Id}/items/COKE-330 +{ "price": 90, "minPrice": 80 } +``` +This publishes a band for `COKE-330` in the North region: ceiling 90, floor 80. + +**Order at the default (no negotiation):** +``` +POST /api/orders +{ "storeId": "S1", "orderDate": "2026-09-15", "items": [{ "itemId": "COKE-330", "quantity": 10 }] } +``` +No `unitPrice` supplied → resolves to the ceiling, **unit price = 90**. + +**Order with a negotiated price inside the band:** +``` +POST /api/orders +{ "storeId": "S1", "orderDate": "2026-09-15", + "items": [{ "itemId": "COKE-330", "quantity": 10, "unitPrice": 83 }] } +``` +83 is within `[80, 90]` → **accepted, unit price = 83**. + +**Order with a price outside the band:** +``` +POST /api/orders +{ "storeId": "S1", "orderDate": "2026-09-15", + "items": [{ "itemId": "COKE-330", "quantity": 10, "unitPrice": 75 }] } +``` +75 is below `MinPrice = 80` → **the whole order is rejected (400)**, same as if no price could be +resolved at all. + +A store in the South region (no region price list, so it falls through to the global list or +`Item.SalePrice = 100`) has no `MinPrice` unless a global `PriceListItem` also sets one — an +override there is rejected unless it equals the fixed price exactly. + +**Supplier example** (unrelated to pricing resolution, same step): +``` +POST /api/suppliers +{ "name": "Acme Distributors", "contactInfo": "acme@example.com, +91-98765-43210" } +→ Supplier { Id, Name: "Acme Distributors", PerformanceScore: null } +``` +`PerformanceScore` stays null until [15_procurement.md](./15_procurement.md)'s `evaluateSupplier` +runs against this supplier. diff --git a/Distribution/docs/mainPlan.md b/Distribution/docs/mainPlan.md index f6bb2fb..0d286f8 100644 --- a/Distribution/docs/mainPlan.md +++ b/Distribution/docs/mainPlan.md @@ -13,6 +13,7 @@ | Order CRUD | Done | Scope-aware (user only sees their assigned stores) | | Unit of Work + Repositories | Done | Transaction support throughout | | Soft Deletes | Done | IsActive pattern on all entities | +| Price Lists / Suppliers | Done | Region-scoped price lists + supplier master; see [14_pricing_and_suppliers.md](./14_pricing_and_suppliers.md) | ## Known Gaps in Existing System (Pre-Work) @@ -46,9 +47,9 @@ They must be resolved before new feature steps begin because later steps depend | 09 | Fraud Controls & Audit Trail | Not Started | 08 | [09_fraud_controls.md](./09_fraud_controls.md) | | 10 | Region Management (Beyond CRUD) | Not Started | 00 | [10_region_management.md](./10_region_management.md) | | 11 | Route & Sales Visit Management | Not Started | 00 | [11_route_sales_management.md](./11_route_sales_management.md) | -| 12 | Store Management (Beyond CRUD) | Not Started | 00 | [12_store_management.md](./12_store_management.md) | +| 12 | Store Management (Beyond CRUD) | In Progress | 00 | [12_store_management.md](./12_store_management.md) | | 13 | Fleet Management (Beyond CRUD) | Not Started | 00 | [13_fleet_management.md](./13_fleet_management.md) | -| 14 | Pricing & Supplier Master Data | Not Started | 01 | [14_pricing_and_suppliers.md](./14_pricing_and_suppliers.md) | +| 14 | Pricing & Supplier Master Data | Done | 01 | [14_pricing_and_suppliers.md](./14_pricing_and_suppliers.md) | | 15 | Procurement / Purchasing | Not Started | 01, 14 | [15_procurement.md](./15_procurement.md) | | 16 | Sales Force Automation / CRM | Not Started | 12 | [16_sfa_crm.md](./16_sfa_crm.md) | | 17 | Promotions & Trade Scheme Management | Not Started | 01, 14 | [17_promotions_schemes.md](./17_promotions_schemes.md) | @@ -79,10 +80,10 @@ here — see `SRS_User_Management_Module.pdf`. | Function | What it does | Status | |---|---|---| -| `createOrder(storeId, items[], salesRepId)` | Validates stock/credit, creates a new order in `pending` state. | Partially implemented — `OrderService.CreateAsync` exists but has no credit/stock validation or state machine yet. | -| `validateCreditLimit(storeId, orderAmount)` | Checks store's outstanding balance + new order value against its credit limit. | Not implemented — no credit limit field on `Store` yet. | +| `createOrder(storeId, items[], salesRepId)` | Validates stock/credit, creates a new order in `pending` state. | Partially implemented - `OrderService.CreateAsync` exists, enforces store scope, blocks inactive stores, and applies the unverified-KYC order threshold from config. It still has no stock validation, credit-limit validation, approval flow, or order state machine. | +| `validateCreditLimit(storeId, orderAmount)` | Checks store's outstanding balance + new order value against its credit limit. | Not implemented - `Store` now has `CreditLimit` and `OutstandingBalance`, but there is no dedicated validator or order-time credit-limit enforcement yet. | | `checkStockAvailability(items[])` | Confirms requested SKUs/quantities are available at the fulfilling warehouse. | Not implemented — depends on [02_stock_ledger.md](./02_stock_ledger.md). | -| `applyPricingAndDiscounts(orderId)` | Runs the active price list and eligible scheme rules against order lines. | Not implemented — depends on §7 Master Data and §11 Promotions below. | +| `applyPricingAndDiscounts(orderId)` | Runs the active price list and eligible scheme rules against order lines. | Partially implemented — `OrderService.CreateAsync` resolves the price-list half via `PriceListService.ResolveUnitPriceAsync` (region-scoped → global → `Item.SalePrice`, or a caller-supplied `UnitPrice`); the scheme-discount half still depends on §11 Promotions below. | | `submitOrderForApproval(orderId)` | Routes the order to the correct approver based on its value/discount threshold. | Not implemented — depends on [08_sales_agent_controls.md](./08_sales_agent_controls.md). | | `approveOrder(orderId, approverId)` / `rejectOrder(orderId, reason)` | Moves order to `approved` or `rejected`, logging the actor. | Not implemented. | | `updateOrderStatus(orderId, status)` | Transitions order through `pending → approved → picked → dispatched → delivered → invoiced`. | Not implemented — `Order` has no status field or state machine today. | @@ -124,15 +125,15 @@ here — see `SRS_User_Management_Module.pdf`. | Function | What it does | Status | |---|---|---| -| `createStore(storeData, kycDocs)` | Onboards a new outlet with required KYC. | Partially implemented — `StoreController` create exists, no KYC document handling. | -| `verifyStoreKyc(storeId)` | Marks KYC as verified/rejected by an approver. | Not implemented. | -| `updateStoreCreditLimit(storeId, newLimit, approverId)` | Changes a store's credit limit, subject to approval authority. | Not implemented — no credit limit field on `Store`. | -| `getStoreOutstandingBalance(storeId)` | Returns current receivables against the store. | Not implemented — depends on §13 Finance & Accounting. | -| `classifyStore(storeId, segment)` | Sets/updates the store's segment (key account, general trade, etc.). | Not implemented — no segment field on `Store`. | +| `createStore(storeData, kycDocs)` | Onboards a new outlet with required KYC. | Partially implemented - store create exists, and KYC documents can now be uploaded/listed via separate `/api/stores/{id}/kyc-documents` endpoints rather than inline on create. | +| `verifyStoreKyc(storeId)` | Marks KYC as verified/rejected by an approver. | Implemented - `PUT /api/stores/{id}/kyc/verify` updates `Store.KycStatus`. | +| `updateStoreCreditLimit(storeId, newLimit, approverId)` | Changes a store's credit limit, subject to approval authority. | Implemented - `PUT /api/stores/{id}/credit-limit` updates `Store.CreditLimit` and requires the `stores.credit.update` permission plus role level >= 20. | +| `getStoreOutstandingBalance(storeId)` | Returns current receivables against the store. | Partially implemented - `GET /api/stores/{id}/outstanding-balance` returns the cached `OutstandingBalance`, `CreditLimit`, and available credit. It is not yet driven by Finance events or invoice/payment records. | +| `classifyStore(storeId, segment)` | Sets/updates the store's segment (key account, general trade, etc.). | Implemented - `PUT /api/stores/{id}/segment` updates the free-text `Store.Segment` field. | | `deactivateStore(storeId, reason)` | Soft-deletes a store, blocking new orders against it. | Partially implemented — `DELETE /api/stores/{id}` soft-deletes via `IsActive`, no reason code captured. | -| `getStoreVisitHistory(storeId)` | Returns visit compliance history from Route Management. | Not implemented — depends on route check-in/check-out (§3). | -| `checkStoreSchemeEligibility(storeId, schemeId)` | Evaluates whether a store qualifies for a given promotion. | Not implemented — depends on §11 Promotions. | -| `getStoreSalesDashboard(storeId, period)` | Store-level sales and outstanding summary. | Not implemented. | +| `getStoreVisitHistory(storeId)` | Returns visit compliance history from Route Management. | Placeholder only - endpoint exists (`GET /api/stores/{id}/visit-history`) but currently returns an empty list until Route/Sales Visit Management lands. | +| `checkStoreSchemeEligibility(storeId, schemeId)` | Evaluates whether a store qualifies for a given promotion. | Placeholder only - endpoint exists (`GET /api/stores/{id}/schemes/{schemeId}/eligibility`) but currently returns a default eligible response until Promotions is implemented. | +| `getStoreSalesDashboard(storeId, period)` | Store-level sales and outstanding summary. | Partially implemented - `GET /api/stores/{id}/dashboard` aggregates order count, total order value, and last order date for the selected month. It does not yet include full sales/outstanding analytics from Finance. | ### 5. Vehicle / Fleet Management @@ -173,9 +174,9 @@ here — see `SRS_User_Management_Module.pdf`. |---|---|---| | `createProduct(skuData)` | Creates a SKU with category, UOM, barcode, pack hierarchy. | Not implemented — `Item` model exists but has no properties; see [01_item_catalog.md](./01_item_catalog.md). | | `deactivateSku(sku, reason)` | Retires a SKU from active ordering. | Not implemented. | -| `createPriceList(name, region, effectiveDates)` | Defines a new price list scoped to a region/date range. | Not implemented — no price list entity exists. | -| `updateProductPricing(sku, priceListId, price)` | Sets/updates the price of a SKU within a price list. | Not implemented. | -| `createSupplierMaster(supplierData)` | Registers a new supplier/vendor. | Not implemented — no `Supplier` entity exists. | +| `createPriceList(name, region, effectiveDates)` | Defines a new price list scoped to a region/date range. | Implemented — `POST /api/price-lists`, see [14_pricing_and_suppliers.md](./14_pricing_and_suppliers.md). | +| `updateProductPricing(sku, priceListId, price)` | Sets/updates the price of a SKU within a price list. | Implemented — `PUT /api/price-lists/{id}/items/{sku}`. | +| `createSupplierMaster(supplierData)` | Registers a new supplier/vendor. | Implemented — `POST /api/suppliers`. `PerformanceScore` stays null until [15_procurement.md](./15_procurement.md)'s `evaluateSupplier` exists. | ### 8. Enterprise-wide Inventory & Stock -- 2.52.0