Production #10

Merged
DeepnaPooja merged 8 commits from production into dev 2026-08-25 11:12:17 +05:30
22 changed files with 4144 additions and 202 deletions
Showing only changes of commit 83bf715716 - Show all commits
+1
View File
@@ -29,6 +29,7 @@ public class AppDBContext(DbContextOptions<AppDBContext> options) : DbContext(op
public DbSet<UserStoreScope> UserStoreScopes { get; set; }
public DbSet<StockBalance> StockBalances { get; set; }
public DbSet<StockMovement> StockMovements { get; set; }
public DbSet<StoreKycDocument> StoreKycDocuments { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@@ -35,6 +35,8 @@ public static class RoleAndPermissionSeed
("stores.create", "Create stores"),
("stores.update", "Update stores"),
("stores.delete", "Delete stores"),
("stores.kyc.verify", "Verify or reject store KYC documents"),
("stores.credit.update", "Update store credit limit and outstanding balance"),
("warehouses.view", "View warehouses"),
("warehouses.create", "Create warehouses"),
@@ -98,14 +100,14 @@ public static class RoleAndPermissionSeed
var itemPerms = new[] { "items.view", "items.create", "items.update", "items.delete", "categories.view", "categories.create", "categories.update", "categories.delete" };
var salesRepPerms = new[] { "orders.view", "orders.create", "orders.update", "stores.view", "routes.view" }.Concat(itemViewPerms).ToArray();
var supervisorPerms = salesRepPerms.Concat(["orders.delete", "stores.create", "stores.update"]).ToArray();
var areaManagerPerms = supervisorPerms.Concat(["vehicles.view", "warehouses.view"]).Concat(itemManagePerms).Distinct().ToArray();
var areaSupervisorPerms = areaManagerPerms.Concat(["routes.create", "routes.update"]).Concat(itemPerms).Distinct().ToArray();
var supervisorPerms = salesRepPerms.Concat(["orders.delete", "stores.create", "stores.update", "stores.credit.update"]).ToArray();
var areaManagerPerms = supervisorPerms.Concat(["vehicles.view", "warehouses.view", "stores.kyc.verify"]).Concat(itemManagePerms).Distinct().ToArray();
var areaSupervisorPerms = areaManagerPerms.Concat(["routes.create", "routes.update", "stores.delete"]).Concat(itemPerms).Distinct().ToArray();
var regionalManagerPerms = new[]
{
"orders.view", "orders.create", "orders.update", "orders.delete",
"stores.view", "stores.create", "stores.update", "stores.delete",
"stores.view", "stores.create", "stores.update", "stores.delete", "stores.kyc.verify", "stores.credit.update",
"routes.view", "routes.create", "routes.update", "routes.delete",
"vehicles.view", "vehicles.create", "vehicles.update", "vehicles.delete",
"warehouses.view", "warehouses.create", "warehouses.update", "warehouses.delete",
+18 -1
View File
@@ -1,9 +1,18 @@
using Distribution.Features.Store;
using Distribution.Infra.Authorization;
using Distribution.Infra.UoW;
using Distribution.Models;
using Microsoft.Extensions.Configuration;
namespace Distribution.Features.Order;
public class OrderService(IOrderRepository repo, IUnitOfWork uow, ICurrentUserService currentUser, IScopeAccessService scopeAccess)
public class OrderService(
IOrderRepository repo,
IStoreRepository storeRepo,
IUnitOfWork uow,
ICurrentUserService currentUser,
IScopeAccessService scopeAccess,
IConfiguration configuration)
{
private const int GlobalScopeRoleLevel = 50;
@@ -63,6 +72,14 @@ public class OrderService(IOrderRepository repo, IUnitOfWork uow, ICurrentUserSe
{
if (!await HasStoreScopeAsync(request.StoreId)) return null;
var store = await storeRepo.GetByIdAsync(request.StoreId);
if (store is null || !store.IsActive) return null;
if (store.KycStatus != KycStatus.Verified)
{
var threshold = configuration.GetValue<decimal>("StoreManagement:UnverifiedKycOrderThreshold");
if (request.TotalAmount > threshold) return null;
}
var order = new Models.Order
{
FK_StoreId = request.StoreId,
@@ -7,4 +7,5 @@ public interface IStoreRepository
Task AddAsync(Models.Store entity);
void Update(Models.Store entity);
void Remove(Models.Store entity);
Task<List<Models.Order>> GetOrdersForDashboardAsync(Guid storeId, DateTime periodStart, DateTime periodEndExclusive);
}
@@ -0,0 +1,7 @@
namespace Distribution.Features.Store.Kyc;
public interface IStoreKycDocumentRepository
{
Task<List<Models.StoreKycDocument>> GetByStoreIdAsync(Guid storeId);
Task AddAsync(Models.StoreKycDocument entity);
}
@@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Distribution.Features.Store.Kyc;
[ApiController]
[Route("api/stores/{storeId:guid}/kyc-documents")]
[Authorize]
public class StoreKycDocumentController(StoreKycDocumentService service) : ControllerBase
{
[HttpGet]
[Authorize(Policy = "stores.view")]
public async Task<IActionResult> GetByStoreId(Guid storeId)
{
var result = await service.GetByStoreIdAsync(storeId);
return result is null ? NotFound() : Ok(result);
}
[HttpPost]
[Authorize(Policy = "stores.update")]
public async Task<IActionResult> Upload(Guid storeId, [FromForm] UploadKycDocumentRequest request, CancellationToken ct)
{
var result = await service.UploadAsync(storeId, request, ct);
return result is null ? NotFound() : Ok(result);
}
}
@@ -0,0 +1,5 @@
namespace Distribution.Features.Store.Kyc;
public record UploadKycDocumentRequest(string DocumentType, IFormFile File);
public record StoreKycDocumentResponse(Guid Id, Guid StoreId, string DocumentType, string FileReference, DateTime UploadedAt);
@@ -0,0 +1,13 @@
using Distribution.Data;
using Microsoft.EntityFrameworkCore;
namespace Distribution.Features.Store.Kyc;
public class StoreKycDocumentRepository(AppDBContext context) : IStoreKycDocumentRepository
{
public async Task<List<Models.StoreKycDocument>> GetByStoreIdAsync(Guid storeId) =>
await context.StoreKycDocuments.Where(d => d.FK_StoreId == storeId && d.IsActive).ToListAsync();
public async Task AddAsync(Models.StoreKycDocument entity) =>
await context.StoreKycDocuments.AddAsync(entity);
}
@@ -0,0 +1,71 @@
using Distribution.Infra.Authorization;
using Distribution.Infra.UoW;
namespace Distribution.Features.Store.Kyc;
public class StoreKycDocumentService(
IStoreKycDocumentRepository repo,
IStoreRepository storeRepo,
IUnitOfWork uow,
ICurrentUserService currentUser,
IScopeAccessService scopeAccess,
IWebHostEnvironment env)
{
private const int GlobalScopeRoleLevel = 50;
private bool HasGlobalScope => currentUser.RoleLevel >= GlobalScopeRoleLevel;
private async Task<bool> HasStoreScopeAsync(Guid storeId)
{
if (HasGlobalScope || currentUser.UserId is null) return HasGlobalScope;
return await scopeAccess.HasStoreScopeAsync(currentUser.UserId.Value, storeId);
}
private static StoreKycDocumentResponse ToResponse(Models.StoreKycDocument d) =>
new(d.Id, d.FK_StoreId, d.DocumentType, d.FileReference, d.UploadedAt);
public async Task<List<StoreKycDocumentResponse>?> GetByStoreIdAsync(Guid storeId)
{
if (!await HasStoreScopeAsync(storeId)) return null;
var docs = await repo.GetByStoreIdAsync(storeId);
return docs.Select(ToResponse).ToList();
}
public async Task<StoreKycDocumentResponse?> UploadAsync(Guid storeId, UploadKycDocumentRequest request, CancellationToken ct = default)
{
var store = await storeRepo.GetByIdAsync(storeId);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(storeId)) return null;
var uploadsRoot = Path.Combine(env.ContentRootPath, "wwwroot", "uploads", "kyc", storeId.ToString());
Directory.CreateDirectory(uploadsRoot);
var fileName = $"{Guid.NewGuid()}{Path.GetExtension(request.File.FileName)}";
var filePath = Path.Combine(uploadsRoot, fileName);
await using (var stream = new FileStream(filePath, FileMode.Create))
{
await request.File.CopyToAsync(stream, ct);
}
var fileReference = $"uploads/kyc/{storeId}/{fileName}";
var doc = new Models.StoreKycDocument
{
FK_StoreId = storeId,
DocumentType = request.DocumentType,
FileReference = fileReference,
UploadedAt = DateTime.Now
};
await uow.BeginAsync(ct);
try
{
await repo.AddAsync(doc);
await uow.CommitAsync(ct);
}
catch
{
await uow.RollbackAsync(ct);
throw;
}
return ToResponse(doc);
}
}
@@ -44,4 +44,68 @@ public class StoreController(StoreService service) : ControllerBase
var deleted = await service.DeleteAsync(id, ct);
return deleted ? NoContent() : NotFound();
}
[HttpPut("{id:guid}/credit-limit")]
[Authorize(Policy = "stores.credit.update")]
public async Task<IActionResult> UpdateCreditLimit(Guid id, UpdateCreditLimitRequest request, CancellationToken ct)
{
var result = await service.UpdateCreditLimitAsync(id, request, ct);
return result is null ? Forbid() : Ok(result);
}
[HttpPut("{id:guid}/outstanding-balance")]
[Authorize(Policy = "stores.credit.update")]
public async Task<IActionResult> UpdateOutstandingBalance(Guid id, UpdateOutstandingBalanceRequest request, CancellationToken ct)
{
var result = await service.UpdateOutstandingBalanceAsync(id, request, ct);
return result is null ? Forbid() : Ok(result);
}
[HttpGet("{id:guid}/outstanding-balance")]
[Authorize(Policy = "stores.view")]
public async Task<IActionResult> GetOutstandingBalance(Guid id)
{
var result = await service.GetOutstandingBalanceAsync(id);
return result is null ? NotFound() : Ok(result);
}
[HttpPut("{id:guid}/kyc/verify")]
[Authorize(Policy = "stores.kyc.verify")]
public async Task<IActionResult> VerifyKyc(Guid id, VerifyKycRequest request, CancellationToken ct)
{
var result = await service.VerifyKycAsync(id, request, ct);
return result is null ? NotFound() : Ok(result);
}
[HttpPut("{id:guid}/segment")]
[Authorize(Policy = "stores.update")]
public async Task<IActionResult> ClassifySegment(Guid id, ClassifySegmentRequest request, CancellationToken ct)
{
var result = await service.ClassifySegmentAsync(id, request, ct);
return result is null ? NotFound() : Ok(result);
}
[HttpGet("{id:guid}/visit-history")]
[Authorize(Policy = "stores.view")]
public async Task<IActionResult> GetVisitHistory(Guid id)
{
var result = await service.GetVisitHistoryAsync(id);
return result is null ? NotFound() : Ok(result);
}
[HttpGet("{id:guid}/schemes/{schemeId:guid}/eligibility")]
[Authorize(Policy = "stores.view")]
public async Task<IActionResult> CheckSchemeEligibility(Guid id, Guid schemeId)
{
var result = await service.CheckSchemeEligibilityAsync(id, schemeId);
return result is null ? NotFound() : Ok(result);
}
[HttpGet("{id:guid}/dashboard")]
[Authorize(Policy = "stores.view")]
public async Task<IActionResult> GetDashboard(Guid id, [FromQuery] string period)
{
var result = await service.GetDashboardAsync(id, period);
return result is null ? NotFound() : Ok(result);
}
}
+22
View File
@@ -1,3 +1,5 @@
using Distribution.Models;
namespace Distribution.Features.Store;
public record CreateStoreRequest(
@@ -30,5 +32,25 @@ public record StoreResponse(
decimal Longitude,
decimal OneTimeAmount,
decimal CreditAmount,
decimal CreditLimit,
decimal OutstandingBalance,
string? Segment,
KycStatus KycStatus,
bool IsActive,
DateTime CreatedAt);
public record UpdateCreditLimitRequest(decimal NewLimit, Guid ApproverId);
public record UpdateOutstandingBalanceRequest(decimal NewBalance);
public record VerifyKycRequest(KycStatus Status, string? Notes);
public record ClassifySegmentRequest(string Segment);
public record OutstandingBalanceResponse(Guid StoreId, decimal CreditLimit, decimal OutstandingBalance, decimal AvailableCredit);
public record StoreVisitHistoryItem(Guid VisitId, DateTime VisitDate, Guid RepUserId, string Outcome);
public record SchemeEligibilityResponse(bool Eligible, string? Reason);
public record StoreDashboardResponse(Guid StoreId, string Period, int OrderCount, decimal TotalOrderValue, DateTime? LastOrderDate);
@@ -22,4 +22,9 @@ public class StoreRepository(AppDBContext context) : IStoreRepository
entity.IsActive = false;
context.Stores.Update(entity);
}
public async Task<List<Models.Order>> GetOrdersForDashboardAsync(Guid storeId, DateTime periodStart, DateTime periodEndExclusive) =>
await context.Orders
.Where(o => o.FK_StoreId == storeId && o.IsActive && o.OrderDate >= periodStart && o.OrderDate < periodEndExclusive)
.ToListAsync();
}
+137 -4
View File
@@ -1,11 +1,13 @@
using Distribution.Infra.Authorization;
using Distribution.Infra.UoW;
using Distribution.Models;
namespace Distribution.Features.Store;
public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserService currentUser, IScopeAccessService scopeAccess)
{
private const int GlobalScopeRoleLevel = 50;
private const int CreditApproverRoleLevel = 20;
private bool HasGlobalScope => currentUser.RoleLevel >= GlobalScopeRoleLevel;
@@ -15,6 +17,10 @@ public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserSe
return await scopeAccess.HasStoreScopeAsync(currentUser.UserId.Value, storeId);
}
private static StoreResponse ToResponse(Models.Store s) =>
new(s.Id, s.FK_RouteId, s.OwnerName, s.StoreName, s.StoreAddress, s.Latitude, s.Longitude, s.OneTimeAmount, s.CreditAmount,
s.CreditLimit, s.OutstandingBalance, s.Segment, s.KycStatus, s.IsActive, s.CreatedAt);
public async Task<List<StoreResponse>> GetAllAsync()
{
var stores = (await repo.GetAllAsync()).Where(s => s.IsActive).ToList();
@@ -23,7 +29,7 @@ public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserSe
var accessibleStoreIds = (await scopeAccess.GetAccessibleStoreIdsAsync(currentUser.UserId.Value)).ToHashSet();
stores = stores.Where(s => accessibleStoreIds.Contains(s.Id)).ToList();
}
return stores.Select(s => new StoreResponse(s.Id, s.FK_RouteId, s.OwnerName, s.StoreName, s.StoreAddress, s.Latitude, s.Longitude, s.OneTimeAmount, s.CreditAmount, s.IsActive, s.CreatedAt)).ToList();
return stores.Select(ToResponse).ToList();
}
public async Task<StoreResponse?> GetByIdAsync(Guid id)
@@ -31,7 +37,7 @@ public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserSe
var store = await repo.GetByIdAsync(id);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(id)) return null;
return new StoreResponse(store.Id, store.FK_RouteId, store.OwnerName, store.StoreName, store.StoreAddress, store.Latitude, store.Longitude, store.OneTimeAmount, store.CreditAmount, store.IsActive, store.CreatedAt);
return ToResponse(store);
}
public async Task<StoreResponse> CreateAsync(CreateStoreRequest request, CancellationToken ct = default)
@@ -58,7 +64,7 @@ public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserSe
await uow.RollbackAsync(ct);
throw;
}
return new StoreResponse(store.Id, store.FK_RouteId, store.OwnerName, store.StoreName, store.StoreAddress, store.Latitude, store.Longitude, store.OneTimeAmount, store.CreditAmount, store.IsActive, store.CreatedAt);
return ToResponse(store);
}
public async Task<StoreResponse?> UpdateAsync(Guid id, UpdateStoreRequest request, CancellationToken ct = default)
@@ -85,7 +91,7 @@ public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserSe
await uow.RollbackAsync(ct);
throw;
}
return new StoreResponse(store.Id, store.FK_RouteId, store.OwnerName, store.StoreName, store.StoreAddress, store.Latitude, store.Longitude, store.OneTimeAmount, store.CreditAmount, store.IsActive, store.CreatedAt);
return ToResponse(store);
}
public async Task<bool> DeleteAsync(Guid id, CancellationToken ct = default)
@@ -106,4 +112,131 @@ public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserSe
}
return true;
}
public async Task<StoreResponse?> UpdateCreditLimitAsync(Guid id, UpdateCreditLimitRequest request, CancellationToken ct = default)
{
if (currentUser.RoleLevel < CreditApproverRoleLevel) return null;
var store = await repo.GetByIdAsync(id);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(id)) return null;
store.CreditLimit = request.NewLimit;
await uow.BeginAsync(ct);
try
{
repo.Update(store);
await uow.CommitAsync(ct);
}
catch
{
await uow.RollbackAsync(ct);
throw;
}
return ToResponse(store);
}
public async Task<StoreResponse?> UpdateOutstandingBalanceAsync(Guid id, UpdateOutstandingBalanceRequest request, CancellationToken ct = default)
{
if (currentUser.RoleLevel < CreditApproverRoleLevel) return null;
var store = await repo.GetByIdAsync(id);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(id)) return null;
store.OutstandingBalance = request.NewBalance;
await uow.BeginAsync(ct);
try
{
repo.Update(store);
await uow.CommitAsync(ct);
}
catch
{
await uow.RollbackAsync(ct);
throw;
}
return ToResponse(store);
}
public async Task<OutstandingBalanceResponse?> GetOutstandingBalanceAsync(Guid id)
{
var store = await repo.GetByIdAsync(id);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(id)) return null;
return new OutstandingBalanceResponse(store.Id, store.CreditLimit, store.OutstandingBalance, store.CreditLimit - store.OutstandingBalance);
}
public async Task<StoreResponse?> VerifyKycAsync(Guid id, VerifyKycRequest request, CancellationToken ct = default)
{
var store = await repo.GetByIdAsync(id);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(id)) return null;
store.KycStatus = request.Status;
await uow.BeginAsync(ct);
try
{
repo.Update(store);
await uow.CommitAsync(ct);
}
catch
{
await uow.RollbackAsync(ct);
throw;
}
return ToResponse(store);
}
public async Task<StoreResponse?> ClassifySegmentAsync(Guid id, ClassifySegmentRequest request, CancellationToken ct = default)
{
var store = await repo.GetByIdAsync(id);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(id)) return null;
store.Segment = request.Segment;
await uow.BeginAsync(ct);
try
{
repo.Update(store);
await uow.CommitAsync(ct);
}
catch
{
await uow.RollbackAsync(ct);
throw;
}
return ToResponse(store);
}
public async Task<List<StoreVisitHistoryItem>?> GetVisitHistoryAsync(Guid id)
{
var store = await repo.GetByIdAsync(id);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(id)) return null;
// Wired to Step 11 (Route & Sales Management) once ride/visit tracking exists.
return [];
}
public async Task<SchemeEligibilityResponse?> CheckSchemeEligibilityAsync(Guid id, Guid schemeId)
{
var store = await repo.GetByIdAsync(id);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(id)) return null;
// Wired to Step 17 (Promotions & Schemes) once scheme rules exist.
return new SchemeEligibilityResponse(true, null);
}
public async Task<StoreDashboardResponse?> GetDashboardAsync(Guid id, string period)
{
var store = await repo.GetByIdAsync(id);
if (store is null || !store.IsActive) return null;
if (!await HasStoreScopeAsync(id)) return null;
if (!DateTime.TryParseExact(period, "yyyy-MM", null, System.Globalization.DateTimeStyles.None, out var periodStart))
periodStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
var periodEndExclusive = periodStart.AddMonths(1);
var orders = await repo.GetOrdersForDashboardAsync(id, periodStart, periodEndExclusive);
return new StoreDashboardResponse(
id,
periodStart.ToString("yyyy-MM"),
orders.Count,
orders.Sum(o => o.TotalAmount),
orders.Count == 0 ? null : orders.Max(o => o.OrderDate));
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,716 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace Distribution.Migrations
{
/// <inheritdoc />
public partial class AddStoreCreditAndKyc : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000001") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000001") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000001") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000035"), new Guid("10000000-0000-0000-0000-000000000001") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000002") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000002") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000002") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000035"), new Guid("10000000-0000-0000-0000-000000000002") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000032"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000032"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000005") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000032"), new Guid("10000000-0000-0000-0000-000000000005") });
migrationBuilder.AddColumn<decimal>(
name: "CreditLimit",
table: "Stores",
type: "decimal(65,30)",
nullable: false,
defaultValue: 0m);
migrationBuilder.AddColumn<int>(
name: "KycStatus",
table: "Stores",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<decimal>(
name: "OutstandingBalance",
table: "Stores",
type: "decimal(65,30)",
nullable: false,
defaultValue: 0m);
migrationBuilder.AddColumn<string>(
name: "Segment",
table: "Stores",
type: "longtext",
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "StoreKycDocuments",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
FK_StoreId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
DocumentType = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
FileReference = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
UploadedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_StoreKycDocuments", x => x.Id);
table.ForeignKey(
name: "FK_StoreKycDocuments_Stores_FK_StoreId",
column: x => x.FK_StoreId,
principalTable: "Stores",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000017"),
columns: new[] { "Code", "Description" },
values: new object[] { "stores.kyc.verify", "Verify or reject store KYC documents" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000018"),
columns: new[] { "Code", "Description" },
values: new object[] { "stores.credit.update", "Update store credit limit and outstanding balance" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000019"),
columns: new[] { "Code", "Description" },
values: new object[] { "warehouses.view", "View warehouses" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000020"),
columns: new[] { "Code", "Description" },
values: new object[] { "warehouses.create", "Create warehouses" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000021"),
columns: new[] { "Code", "Description" },
values: new object[] { "warehouses.update", "Update warehouses" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000022"),
columns: new[] { "Code", "Description" },
values: new object[] { "warehouses.delete", "Delete warehouses" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000023"),
columns: new[] { "Code", "Description" },
values: new object[] { "orders.view", "View orders" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000024"),
columns: new[] { "Code", "Description" },
values: new object[] { "orders.create", "Create orders" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000025"),
columns: new[] { "Code", "Description" },
values: new object[] { "orders.update", "Update orders" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000026"),
columns: new[] { "Code", "Description" },
values: new object[] { "orders.delete", "Delete orders" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000027"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.view", "View users" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000028"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.create", "Create users" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000029"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.update", "Update users" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000030"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.deactivate", "Deactivate users" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000031"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.assign_role", "Assign a role to a user" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000032"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.assign_scope", "Assign region/route/store scope to a user" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000033"),
columns: new[] { "Code", "Description" },
values: new object[] { "items.view", "View items, brands and UOMs" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000034"),
columns: new[] { "Code", "Description" },
values: new object[] { "items.create", "Create items, brands and UOMs" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000035"),
columns: new[] { "Code", "Description" },
values: new object[] { "items.update", "Update items, brands and UOMs" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000036"),
columns: new[] { "Code", "Description" },
values: new object[] { "items.delete", "Delete items, brands and UOMs" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000037"),
columns: new[] { "Code", "Description" },
values: new object[] { "categories.view", "View categories" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000038"),
columns: new[] { "Code", "Description" },
values: new object[] { "categories.create", "Create categories and subcategories" });
migrationBuilder.InsertData(
table: "Permissions",
columns: new[] { "Id", "Code", "CreatedAt", "Description", "IsActive" },
values: new object[,]
{
{ new Guid("20000000-0000-0000-0000-000000000039"), "categories.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update categories and subcategories", true },
{ new Guid("20000000-0000-0000-0000-000000000040"), "categories.delete", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Delete categories and subcategories", true }
});
migrationBuilder.InsertData(
table: "RolePermissions",
columns: new[] { "FK_PermissionId", "FK_RoleId", "CreatedAt", "Id", "IsActive" },
values: new object[,]
{
{ new Guid("20000000-0000-0000-0000-000000000024"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("c0739b84-50a2-0971-429b-02bab8354c51"), true },
{ new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("c268a531-44eb-0f29-82ba-18394ac2dcb5"), true },
{ new Guid("20000000-0000-0000-0000-000000000033"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("ddb2d04d-19b0-20b1-2639-b157d12a9eec"), true },
{ new Guid("20000000-0000-0000-0000-000000000037"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("320ba3fb-666c-ce57-3e61-95c9824c4048"), true },
{ new Guid("20000000-0000-0000-0000-000000000018"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("f2c14d55-d557-5cd2-a70a-4a6f58933436"), true },
{ new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("1b126bb0-e582-3e84-4728-a7ab5628fe7b"), true },
{ new Guid("20000000-0000-0000-0000-000000000026"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("f50b201c-6c8d-0df8-85ad-08cb137bc213"), true },
{ new Guid("20000000-0000-0000-0000-000000000033"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("0f291826-e169-c06a-0735-bd06cbb2062d"), true },
{ new Guid("20000000-0000-0000-0000-000000000037"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("10dd0249-ce04-c5d9-8f94-ccb348c1d979"), true },
{ new Guid("20000000-0000-0000-0000-000000000018"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d92d572f-f1bf-9e7d-1d4d-7c7b0d575c8e"), true },
{ new Guid("20000000-0000-0000-0000-000000000019"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("f367f6f6-3d26-7a6c-888b-da1a240b59af"), true },
{ new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("929950da-d51b-ad5d-c4e5-55175908fb43"), true },
{ new Guid("20000000-0000-0000-0000-000000000026"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("a9a49749-f99d-3166-5d92-b7e380fcabb2"), true },
{ new Guid("20000000-0000-0000-0000-000000000034"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("b17df3df-022c-c903-6ce0-e6423e648dc8"), true },
{ new Guid("20000000-0000-0000-0000-000000000037"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("a41f94ba-c24d-93dc-9f25-c462df19785a"), true },
{ new Guid("20000000-0000-0000-0000-000000000016"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("e0b27435-f505-43f5-7ed9-4711f2248495"), true },
{ new Guid("20000000-0000-0000-0000-000000000018"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("5e10d61c-2d7a-3388-722f-45232d2cfb71"), true },
{ new Guid("20000000-0000-0000-0000-000000000019"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d8257363-d838-fe7e-57a5-51b626dbfc83"), true },
{ new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("04ece77e-b36f-8ed0-4ef9-2f6962b6f9c6"), true },
{ new Guid("20000000-0000-0000-0000-000000000026"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("bf2a2f96-04ed-905d-5a8a-9047d814aa3e"), true },
{ new Guid("20000000-0000-0000-0000-000000000026"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("4d287b19-ba40-7d4d-3d39-291be64197f8"), true },
{ new Guid("20000000-0000-0000-0000-000000000027"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("43a4c7b4-a50f-aa37-b147-a30636d9d65f"), true },
{ new Guid("20000000-0000-0000-0000-000000000039"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("a66f3854-5a8f-95c2-cb1c-b2b2e67ee226"), true },
{ new Guid("20000000-0000-0000-0000-000000000040"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("14bcecd1-b1a2-6da3-155a-233611484467"), true },
{ new Guid("20000000-0000-0000-0000-000000000039"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("aeb29e0e-e819-1446-6cc6-1fb64b5ecc6b"), true },
{ new Guid("20000000-0000-0000-0000-000000000040"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("e18a6eca-1009-bcc6-35e9-ead943c1649f"), true },
{ new Guid("20000000-0000-0000-0000-000000000039"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("3f32cdac-6925-23f2-064e-8226d781d4a3"), true },
{ new Guid("20000000-0000-0000-0000-000000000040"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("dc3dd9ff-b123-a8d4-dcea-b4f5f8ff171e"), true }
});
migrationBuilder.CreateIndex(
name: "IX_StoreKycDocuments_FK_StoreId",
table: "StoreKycDocuments",
column: "FK_StoreId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "StoreKycDocuments");
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000024"), new Guid("10000000-0000-0000-0000-000000000001") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000001") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000033"), new Guid("10000000-0000-0000-0000-000000000001") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000037"), new Guid("10000000-0000-0000-0000-000000000001") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000018"), new Guid("10000000-0000-0000-0000-000000000002") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000002") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000026"), new Guid("10000000-0000-0000-0000-000000000002") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000033"), new Guid("10000000-0000-0000-0000-000000000002") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000037"), new Guid("10000000-0000-0000-0000-000000000002") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000018"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000019"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000026"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000034"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000037"), new Guid("10000000-0000-0000-0000-000000000003") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000016"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000018"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000019"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000026"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000039"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000040"), new Guid("10000000-0000-0000-0000-000000000004") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000026"), new Guid("10000000-0000-0000-0000-000000000005") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000027"), new Guid("10000000-0000-0000-0000-000000000005") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000039"), new Guid("10000000-0000-0000-0000-000000000005") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000040"), new Guid("10000000-0000-0000-0000-000000000005") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000039"), new Guid("10000000-0000-0000-0000-000000000006") });
migrationBuilder.DeleteData(
table: "RolePermissions",
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000040"), new Guid("10000000-0000-0000-0000-000000000006") });
migrationBuilder.DeleteData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000039"));
migrationBuilder.DeleteData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000040"));
migrationBuilder.DropColumn(
name: "CreditLimit",
table: "Stores");
migrationBuilder.DropColumn(
name: "KycStatus",
table: "Stores");
migrationBuilder.DropColumn(
name: "OutstandingBalance",
table: "Stores");
migrationBuilder.DropColumn(
name: "Segment",
table: "Stores");
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000017"),
columns: new[] { "Code", "Description" },
values: new object[] { "warehouses.view", "View warehouses" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000018"),
columns: new[] { "Code", "Description" },
values: new object[] { "warehouses.create", "Create warehouses" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000019"),
columns: new[] { "Code", "Description" },
values: new object[] { "warehouses.update", "Update warehouses" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000020"),
columns: new[] { "Code", "Description" },
values: new object[] { "warehouses.delete", "Delete warehouses" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000021"),
columns: new[] { "Code", "Description" },
values: new object[] { "orders.view", "View orders" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000022"),
columns: new[] { "Code", "Description" },
values: new object[] { "orders.create", "Create orders" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000023"),
columns: new[] { "Code", "Description" },
values: new object[] { "orders.update", "Update orders" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000024"),
columns: new[] { "Code", "Description" },
values: new object[] { "orders.delete", "Delete orders" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000025"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.view", "View users" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000026"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.create", "Create users" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000027"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.update", "Update users" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000028"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.deactivate", "Deactivate users" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000029"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.assign_role", "Assign a role to a user" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000030"),
columns: new[] { "Code", "Description" },
values: new object[] { "users.assign_scope", "Assign region/route/store scope to a user" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000031"),
columns: new[] { "Code", "Description" },
values: new object[] { "items.view", "View items, brands and UOMs" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000032"),
columns: new[] { "Code", "Description" },
values: new object[] { "items.create", "Create items, brands and UOMs" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000033"),
columns: new[] { "Code", "Description" },
values: new object[] { "items.update", "Update items, brands and UOMs" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000034"),
columns: new[] { "Code", "Description" },
values: new object[] { "items.delete", "Delete items, brands and UOMs" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000035"),
columns: new[] { "Code", "Description" },
values: new object[] { "categories.view", "View categories" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000036"),
columns: new[] { "Code", "Description" },
values: new object[] { "categories.create", "Create categories and subcategories" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000037"),
columns: new[] { "Code", "Description" },
values: new object[] { "categories.update", "Update categories and subcategories" });
migrationBuilder.UpdateData(
table: "Permissions",
keyColumn: "Id",
keyValue: new Guid("20000000-0000-0000-0000-000000000038"),
columns: new[] { "Code", "Description" },
values: new object[] { "categories.delete", "Delete categories and subcategories" });
migrationBuilder.InsertData(
table: "RolePermissions",
columns: new[] { "FK_PermissionId", "FK_RoleId", "CreatedAt", "Id", "IsActive" },
values: new object[,]
{
{ new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("85ef4e27-8643-9c43-71f6-da56f66a5c47"), true },
{ new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("1e353909-d682-58f6-df5c-8e57fa2512c9"), true },
{ new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7596f703-c6ab-316c-7c80-3f4e3daa174e"), true },
{ new Guid("20000000-0000-0000-0000-000000000035"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("aa120c36-488e-34ba-e10a-2ac45e46e119"), true },
{ new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("e4648655-7267-141e-51fa-f7d5fe3d2356"), true },
{ new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d427b9ea-2c9b-d93e-0843-02dfa1ae8887"), true },
{ new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("b7dee5e3-f329-95a5-75c1-d02c3e40e229"), true },
{ new Guid("20000000-0000-0000-0000-000000000035"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("e5506b30-527d-08f9-6caa-8a45d3d02999"), true },
{ new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("0dd5c943-3ace-0560-6fbc-54d8e37ce014"), true },
{ new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("ca97fb3d-132c-d8a5-4ab8-f7b8fc60f5e5"), true },
{ new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7780d277-9597-84ff-1a1a-f63fc6b4d3cb"), true },
{ new Guid("20000000-0000-0000-0000-000000000032"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("8083c659-9506-0bd9-b793-3d6148ce9192"), true },
{ new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("5c00e972-a697-d71a-6545-1fd8618826cf"), true },
{ new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("e9b6af8e-7947-7290-9c92-2d9b6239f395"), true },
{ new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("a701da28-aa75-3c1d-abdb-4317404f8df6"), true },
{ new Guid("20000000-0000-0000-0000-000000000032"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("2c025310-765f-7d07-ab9a-50524c13d1d3"), true },
{ new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("69f93a29-1df1-7b20-9d5c-94c264f8c4b8"), true },
{ new Guid("20000000-0000-0000-0000-000000000032"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("070813f7-4053-2889-0d14-d0d5834208c2"), true }
});
}
}
}
@@ -380,6 +380,22 @@ namespace Distribution.Migrations
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",
@@ -387,7 +403,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000018"),
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",
@@ -395,7 +411,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000019"),
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",
@@ -403,7 +419,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000020"),
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",
@@ -411,7 +427,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000021"),
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",
@@ -419,7 +435,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000022"),
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",
@@ -427,7 +443,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000023"),
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",
@@ -435,7 +451,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000024"),
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",
@@ -443,7 +459,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000025"),
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",
@@ -451,7 +467,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000026"),
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",
@@ -459,7 +475,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000027"),
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",
@@ -467,7 +483,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000028"),
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",
@@ -475,7 +491,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000029"),
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",
@@ -483,7 +499,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000030"),
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",
@@ -491,7 +507,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000031"),
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",
@@ -499,7 +515,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000032"),
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",
@@ -507,7 +523,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000033"),
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",
@@ -515,7 +531,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000034"),
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",
@@ -523,7 +539,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000035"),
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",
@@ -531,7 +547,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000036"),
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",
@@ -539,7 +555,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000037"),
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",
@@ -547,7 +563,7 @@ namespace Distribution.Migrations
},
new
{
Id = new Guid("20000000-0000-0000-0000-000000000038"),
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",
@@ -674,22 +690,6 @@ namespace Distribution.Migrations
b.ToTable("RolePermissions");
b.HasData(
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("85ef4e27-8643-9c43-71f6-da56f66a5c47"),
IsActive = true
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("1e353909-d682-58f6-df5c-8e57fa2512c9"),
IsActive = true
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"),
@@ -699,6 +699,22 @@ namespace Distribution.Migrations
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"),
@@ -717,33 +733,17 @@ namespace Distribution.Migrations
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000031"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("7596f703-c6ab-316c-7c80-3f4e3daa174e"),
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-000000000035"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("aa120c36-488e-34ba-e10a-2ac45e46e119"),
IsActive = true
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("e4648655-7267-141e-51fa-f7d5fe3d2356"),
IsActive = true
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("d427b9ea-2c9b-d93e-0843-02dfa1ae8887"),
Id = new Guid("320ba3fb-666c-ce57-3e61-95c9824c4048"),
IsActive = true
},
new
@@ -755,6 +755,22 @@ namespace Distribution.Migrations
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"),
@@ -773,25 +789,25 @@ namespace Distribution.Migrations
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000031"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("b7dee5e3-f329-95a5-75c1-d02c3e40e229"),
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-000000000035"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("e5506b30-527d-08f9-6caa-8a45d3d02999"),
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-000000000024"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("357c36de-9b6c-1c9a-4926-c18a9bccf0ca"),
Id = new Guid("f50b201c-6c8d-0df8-85ad-08cb137bc213"),
IsActive = true
},
new
@@ -812,18 +828,10 @@ namespace Distribution.Migrations
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"),
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("0dd5c943-3ace-0560-6fbc-54d8e37ce014"),
IsActive = true
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("ca97fb3d-132c-d8a5-4ab8-f7b8fc60f5e5"),
Id = new Guid("f2c14d55-d557-5cd2-a70a-4a6f58933436"),
IsActive = true
},
new
@@ -835,6 +843,22 @@ namespace Distribution.Migrations
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"),
@@ -853,25 +877,25 @@ namespace Distribution.Migrations
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000031"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("7780d277-9597-84ff-1a1a-f63fc6b4d3cb"),
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-000000000035"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("1e7fe1b6-5150-4b99-38ed-088d9495cfd8"),
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-000000000024"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("73e00ce7-c124-4677-4369-1eb9876852c0"),
Id = new Guid("a9a49749-f99d-3166-5d92-b7e380fcabb2"),
IsActive = true
},
new
@@ -891,6 +915,14 @@ namespace Distribution.Migrations
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"),
@@ -899,6 +931,14 @@ namespace Distribution.Migrations
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"),
@@ -909,33 +949,17 @@ namespace Distribution.Migrations
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000032"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("8083c659-9506-0bd9-b793-3d6148ce9192"),
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-000000000033"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"),
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-000000000004"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("5c00e972-a697-d71a-6545-1fd8618826cf"),
IsActive = true
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("e9b6af8e-7947-7290-9c92-2d9b6239f395"),
Id = new Guid("1e7fe1b6-5150-4b99-38ed-088d9495cfd8"),
IsActive = true
},
new
@@ -947,6 +971,22 @@ namespace Distribution.Migrations
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"),
@@ -965,25 +1005,25 @@ namespace Distribution.Migrations
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000031"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000033"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("a701da28-aa75-3c1d-abdb-4317404f8df6"),
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-000000000035"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000037"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("9afe507e-191e-bdee-0c5a-cfbcbf1efb3e"),
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-000000000024"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000026"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("7b4f3482-b8bd-d348-e4c1-ae6dc93a3771"),
Id = new Guid("bf2a2f96-04ed-905d-5a8a-9047d814aa3e"),
IsActive = true
},
new
@@ -1003,6 +1043,14 @@ namespace Distribution.Migrations
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"),
@@ -1011,6 +1059,14 @@ namespace Distribution.Migrations
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"),
@@ -1021,17 +1077,17 @@ namespace Distribution.Migrations
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000032"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("2c025310-765f-7d07-ab9a-50524c13d1d3"),
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-000000000033"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000035"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("7c392a13-1a57-0d85-dffa-2fb9e892abe9"),
Id = new Guid("9afe507e-191e-bdee-0c5a-cfbcbf1efb3e"),
IsActive = true
},
new
@@ -1053,9 +1109,9 @@ namespace Distribution.Migrations
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000034"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000016"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("97708eed-6ce4-7710-abde-01d00c0c879b"),
Id = new Guid("e0b27435-f505-43f5-7ed9-4711f2248495"),
IsActive = true
},
new
@@ -1067,14 +1123,6 @@ namespace Distribution.Migrations
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-000000000038"),
@@ -1084,18 +1132,18 @@ namespace Distribution.Migrations
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"),
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("08de9913-8cfc-4ab4-2cb9-2bc9217fbb6e"),
Id = new Guid("a66f3854-5a8f-95c2-cb1c-b2b2e67ee226"),
IsActive = true
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"),
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("f3c8f315-3b2f-f923-e3cd-f3e575010138"),
Id = new Guid("14bcecd1-b1a2-6da3-155a-233611484467"),
IsActive = true
},
new
@@ -1115,6 +1163,22 @@ namespace Distribution.Migrations
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"),
@@ -1147,6 +1211,22 @@ namespace Distribution.Migrations
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"),
@@ -1211,22 +1291,6 @@ namespace Distribution.Migrations
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-000000000019"),
@@ -1243,6 +1307,22 @@ namespace Distribution.Migrations
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"),
@@ -1253,25 +1333,9 @@ namespace Distribution.Migrations
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000025"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000027"),
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-000000000031"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("69f93a29-1df1-7b20-9d5c-94c264f8c4b8"),
IsActive = true
},
new
{
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000032"),
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
Id = new Guid("070813f7-4053-2889-0d14-d0d5834208c2"),
Id = new Guid("43a4c7b4-a50f-aa37-b147-a30636d9d65f"),
IsActive = true
},
new
@@ -1323,6 +1387,22 @@ namespace Distribution.Migrations
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"),
@@ -1625,6 +1705,22 @@ namespace Distribution.Migrations
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
});
});
@@ -1769,12 +1865,18 @@ namespace Distribution.Migrations
b.Property<decimal>("CreditAmount")
.HasColumnType("decimal(65,30)");
b.Property<decimal>("CreditLimit")
.HasColumnType("decimal(65,30)");
b.Property<Guid>("FK_RouteId")
.HasColumnType("char(36)");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<int>("KycStatus")
.HasColumnType("int");
b.Property<decimal>("Latitude")
.HasColumnType("decimal(65,30)");
@@ -1784,10 +1886,16 @@ namespace Distribution.Migrations
b.Property<decimal>("OneTimeAmount")
.HasColumnType("decimal(65,30)");
b.Property<decimal>("OutstandingBalance")
.HasColumnType("decimal(65,30)");
b.Property<string>("OwnerName")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Segment")
.HasColumnType("longtext");
b.Property<string>("StoreAddress")
.IsRequired()
.HasColumnType("longtext");
@@ -1803,6 +1911,39 @@ namespace Distribution.Migrations
b.ToTable("Stores");
});
modelBuilder.Entity("Distribution.Models.StoreKycDocument", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("DocumentType")
.IsRequired()
.HasColumnType("longtext");
b.Property<Guid>("FK_StoreId")
.HasColumnType("char(36)");
b.Property<string>("FileReference")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("UploadedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("FK_StoreId");
b.ToTable("StoreKycDocuments");
});
modelBuilder.Entity("Distribution.Models.SubCategory", b =>
{
b.Property<Guid>("Id")
@@ -2203,6 +2344,17 @@ namespace Distribution.Migrations
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")
+11 -1
View File
@@ -1,6 +1,16 @@
namespace Distribution.Models
{
public enum LocationType { Warehouse, Vehicle }
public enum LocationType
{
Warehouse,
Vehicle
}
public enum KycStatus
{
Pending,
Verified,
Rejected }
public enum MovementType
{
+4
View File
@@ -11,6 +11,10 @@ namespace Distribution.Models
public decimal Longitude { get; set; } = 0;
public decimal OneTimeAmount { get; set; } = 0;
public decimal CreditAmount { get; set; } = 0;
public decimal CreditLimit { get; set; } = 0;
public decimal OutstandingBalance { get; set; } = 0;
public String? Segment { get; set; } //Gold ,silver,key Account,high risk
public KycStatus KycStatus { get; set; } = KycStatus.Pending;
public Guid FK_RouteId { get; set; }
[ForeignKey("FK_RouteId")]
+14
View File
@@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Distribution.Models
{
public class StoreKycDocument : Template
{
public Guid FK_StoreId { get; set; }
[ForeignKey("FK_StoreId")]
public Store Store { get; set; }
public String DocumentType { get; set; }
public String FileReference { get; set; }
public DateTime UploadedAt { get; set; } = DateTime.Now;
}
}
+3
View File
@@ -9,6 +9,7 @@ using Distribution.Features.Region;
using Distribution.Features.Role;
using Distribution.Features.Route;
using Distribution.Features.Store;
using Distribution.Features.Store.Kyc;
using Distribution.Features.Sync;
using Distribution.Features.Uom;
using Distribution.Features.User;
@@ -46,6 +47,7 @@ builder.Services.AddScoped<IBrandRepository, BrandRepository>();
builder.Services.AddScoped<IUomRepository, UomRepository>();
builder.Services.AddScoped<IItemRepository, ItemRepository>();
builder.Services.AddScoped<IStockRepository, StockRepository>();
builder.Services.AddScoped<IStoreKycDocumentRepository, StoreKycDocumentRepository>();
builder.Services.AddScoped<RegionService>();
builder.Services.AddScoped<RouteService>();
@@ -62,6 +64,7 @@ builder.Services.AddScoped<UomService>();
builder.Services.AddScoped<ItemService>();
builder.Services.AddScoped<SyncService>();
builder.Services.AddScoped<StockService>();
builder.Services.AddScoped<StoreKycDocumentService>();
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<ICurrentUserService, CurrentUserService>();
+3
View File
@@ -14,5 +14,8 @@
"Issuer": "Distribution.Api",
"Audience": "Distribution.Api",
"ExpiryMinutes": 120
},
"StoreManagement": {
"UnverifiedKycOrderThreshold": 0
}
}
+215 -32
View File
@@ -1,22 +1,32 @@
# 12 — Store Management (Beyond CRUD)
**Status**: Not Started
**Depends On**: 00 — Existing Gap Fixes
**Status**: Done — migration applied to the database
**Depends On**: 00 — Existing Gap Fixes, 10 — Region Management, 11 — Route & Sales Management
---
## Goal
Store CRUD already exists (`Features/Store`). This step covers everything in
[mainPlan.md §4](./mainPlan.md#4-store-outlet-management) that isn't
plain CRUD: KYC, credit, segmentation, and dashboarding.
Store CRUD already exists (`Features/Store`). This step adds everything in
[mainPlan.md §4](./mainPlan.md#4-store-outlet-management) that isn't plain CRUD: credit control,
KYC verification, segmentation, outstanding balance, visit history, scheme eligibility, and a
sales dashboard.
---
## Background / Context
`Store` currently has no credit limit, outstanding balance, segment, or KYC fields — flagged as
gap #8 in [00_existing_gaps.md](./00_existing_gaps.md).
gap #8 in [00_existing_gaps.md](./00_existing_gaps.md). Credit fields exist informally today as
`OneTimeAmount` / `CreditAmount`, which stay as-is; this step adds the real credit-limit +
outstanding-balance + KYC-gated-ordering flow on top.
`getStoreVisitHistory` and `checkStoreSchemeEligibility` are read-only integration points into
modules that don't exist yet ([11_route_sales_management.md](./11_route_sales_management.md) for
visits, [17_promotions_schemes.md](./17_promotions_schemes.md) for schemes). Implement them now
with the query shape defined below; wire the actual join once those modules land — return an empty
list / `eligible: true` (no active schemes to check) until then, guarded by a `NotImplementedYet`
style short-circuit, not a broken query.
---
@@ -24,51 +34,224 @@ gap #8 in [00_existing_gaps.md](./00_existing_gaps.md).
### Store — New Fields
`CreditLimit` (decimal), `OutstandingBalance` (decimal, derived/cached from Finance ledger once
[19_finance_accounting.md](./19_finance_accounting.md) exists), `Segment` (string), `KycStatus`
(`Pending`, `Verified`, `Rejected`).
```
Store (existing, add columns)
├── CreditLimit (decimal) — default 0. Max outstanding allowed before new orders are blocked.
├── OutstandingBalance (decimal) — default 0. Cached/denormalized. Updated by Finance module
│ (step 19) on invoice/payment events via UpdateOutstandingBalanceAsync.
│ Until Finance exists, only moved by manual adjustment endpoint.
├── Segment (string?) — free text, e.g. "Gold", "Silver", "Key Account", "High Risk".
├── KycStatus (enum) — Pending | Verified | Rejected. Default Pending.
```
### KYC Document
### New Enum — KycStatus
`StoreId`, `DocumentType`, `FileReference`, `UploadedAt` — file storage mechanism TBD (out of scope
for this step's data model, just the record).
```csharp
public enum KycStatus { Pending, Verified, Rejected }
```
### New Entity — StoreKycDocument
```
StoreKycDocument
├── Id (Guid) — PK, from Template
├── FK_StoreId (Guid) — required
├── DocumentType (string) — free text, e.g. "GST Certificate", "PAN Card", "Shop License,NIC"
├── FileReference (string) — relative path under wwwroot/uploads/kyc/{storeId}/
├── UploadedAt (DateTime)
├── IsActive, CreatedAt — from Template
```
### AppSettings — New Config Key
```
StoreManagement:UnverifiedKycOrderThreshold (decimal) — default 0.
Max single-order value a store with KycStatus != Verified may place.
0 disables ordering entirely for unverified stores; set higher to allow small orders through.
```
---
## Migrations
One migration needed:
1. **AddStoreCreditAndKyc** — adds `CreditLimit`, `OutstandingBalance`, `Segment`, `KycStatus`
columns to `Stores`; creates `StoreKycDocuments` table.
---
## API Endpoints
| Function reference | Endpoint intent |
|---|---|
| `createStore(storeData, kycDocs)` | Extends existing `POST /api/stores` with doc upload |
| `verifyStoreKyc(storeId)` | `PUT /api/stores/{id}/kyc/verify` |
| `updateStoreCreditLimit(storeId, newLimit, approverId)` | `PUT /api/stores/{id}/credit-limit` |
| `getStoreOutstandingBalance(storeId)` | `GET /api/stores/{id}/outstanding-balance` |
| `classifyStore(storeId, segment)` | `PUT /api/stores/{id}/segment` |
| `deactivateStore(storeId, reason)` | Extends existing `DELETE /api/stores/{id}` with a reason field |
| `getStoreVisitHistory(storeId)` | `GET /api/stores/{id}/visit-history` — reads from [11_route_sales_management.md](./11_route_sales_management.md) |
| `checkStoreSchemeEligibility(storeId, schemeId)` | `GET /api/stores/{id}/schemes/{schemeId}/eligibility` — depends on [17_promotions_schemes.md](./17_promotions_schemes.md) |
| `getStoreSalesDashboard(storeId, period)` | `GET /api/stores/{id}/dashboard?period=...` |
### Existing (unchanged)
| Method | Route | Permission | Notes |
|---|---|---|---|
| GET | /api/stores | stores.view | |
| GET | /api/stores/{id} | stores.view | |
| POST | /api/stores | stores.create | |
| PUT | /api/stores/{id} | stores.update | |
| DELETE | /api/stores/{id} | stores.delete | Soft delete |
### New
| Method | Route | Permission | Notes |
|---|---|---|---|
| POST | /api/stores/{id}/kyc-documents | stores.update | Multipart upload, appends a KYC document |
| GET | /api/stores/{id}/kyc-documents | stores.view | Lists documents for a store |
| PUT | /api/stores/{id}/kyc/verify | stores.kyc.verify | Sets KycStatus, body carries `status` (Verified/Rejected) + optional `notes` |
| PUT | /api/stores/{id}/credit-limit | stores.credit.update | Requires Supervisor (roleLevel ≥ 20) or above |
| PUT | /api/stores/{id}/outstanding-balance | stores.credit.update | Manual adjustment until Finance owns this; same permission as credit-limit |
| GET | /api/stores/{id}/outstanding-balance | stores.view | Returns cached value + CreditLimit + available credit |
| PUT | /api/stores/{id}/segment | stores.update | Body: `{ "segment": "Gold" }` |
| GET | /api/stores/{id}/visit-history | stores.view | Paginated. Empty list until Step 11 wiring lands |
| GET | /api/stores/{id}/schemes/{schemeId}/eligibility | stores.view | Returns `{ eligible: true, reason: null }` until Step 17 wiring lands |
| GET | /api/stores/{id}/dashboard?period=... | stores.view | Aggregates order count/value for the period from existing Order tables |
---
## Request / Response Shapes
### POST `/api/stores/{id}/kyc-documents` (multipart/form-data)
Fields: `documentType` (string), `file` (binary).
Response:
```json
{ "id": "...", "storeId": "...", "documentType": "GST Certificate", "fileReference": "uploads/kyc/{storeId}/{guid}.pdf", "uploadedAt": "2026-08-20T10:00:00" }
```
### PUT `/api/stores/{id}/kyc/verify` request
```json
{ "status": "Verified", "notes": "GST + PAN checked against ERP records" }
```
### PUT `/api/stores/{id}/credit-limit` request
```json
{ "newLimit": 50000, "approverId": "..." }
```
`approverId` must resolve to a user with `RoleLevel >= 20` (Supervisor or above); enforced
server-side from the authenticated caller, not trusted from the body — the field is echoed back
for audit display only.
### GET `/api/stores/{id}/outstanding-balance` response
```json
{ "storeId": "...", "creditLimit": 50000, "outstandingBalance": 32000, "availableCredit": 18000 }
```
### GET `/api/stores/{id}/dashboard` response
```json
{
"storeId": "...",
"period": "2026-08",
"orderCount": 12,
"totalOrderValue": 145000,
"lastOrderDate": "2026-08-18T09:00:00"
}
```
---
## Business Rules
- `updateStoreCreditLimit` requires an approver at Supervisor level or above.
- A store with `KycStatus != Verified` should not be able to place orders above a configurable
threshold (or at all) — confirm exact rule with the user before implementing.
- `deactivateStore` blocks new orders against it, matching the existing `IsActive` soft-delete
filter already used in `OrderService`.
1. `updateStoreCreditLimit` requires the authenticated caller to have `RoleLevel >= 20`
(Supervisor or above) — enforced by the `stores.credit.update` policy plus a role-level check
in the service, same pattern as `StoreService.HasGlobalScope`.
2. A store with `KycStatus != Verified` may only place orders up to
`StoreManagement:UnverifiedKycOrderThreshold`. `OrderService` must check this at order creation
time; orders exceeding the threshold are rejected with a 400. This mirrors the stock-ledger
pattern of rejecting at the point of the write, not after.
3. `deactivateStore` (existing `DELETE /api/stores/{id}`) blocks new orders against the store,
matching the existing `IsActive` soft-delete filter already used in `OrderService`. No separate
reason field is added — soft delete already covers it via the existing `Template.IsActive` flag.
4. `OutstandingBalance` is never edited directly by client-supplied arbitrary values outside the
dedicated endpoint — always through `UpdateOutstandingBalanceAsync`, so Finance (step 19) has a
single integration point to call into later.
5. KYC documents are append-only from the API's perspective — no update endpoint. To replace a
document, upload a new one; old ones stay for audit trail (soft-deletable via `IsActive` if
ever needed).
6. Scope rules for all new endpoints follow the existing `StoreService` pattern: global-scope roles
(`RoleLevel >= 50`) see everything, others are checked via `IScopeAccessService.HasStoreScopeAsync`.
---
## Permissions to Add to Seed
New permission codes to add to the existing seed:
```
stores.kyc.verify, stores.credit.update
```
(`stores.view`, `stores.create`, `stores.update`, `stores.delete` already exist.)
Role assignments:
- **SalesRep (10)**: stores.view (unchanged)
- **Supervisor (20)**: stores.view, stores.update, stores.credit.update
- **AreaManager (30)**: stores.view, stores.update, stores.credit.update, stores.kyc.verify
- **AreaSupervisor (40)**: all store permissions
- **RegionalManager (50)**: all store permissions
- **RegionalAgency (60)**: all store permissions
---
## Open Questions
- Is `OutstandingBalance` a cached/denormalized field updated on invoice/payment events, or always
computed live from Finance records?
- What document types are required for KYC, and is file storage local, blob, or third-party?
- None. Resolved in planning discussion (2026-08-20): OutstandingBalance is cached/denormalized;
KYC document type is free text with local disk storage; unverified stores are gated by a
configurable order-value threshold rather than a hard block.
---
## Implementation Notes
> Fill this section in during planning discussion before writing any code.
### File structure created / touched
```
Features/
Store/
StoreController.cs (extended — credit-limit, balance, kyc/verify, segment,
visit-history, scheme-eligibility, dashboard endpoints)
StoreDTOs.cs (extended — new request/response records)
StoreService.cs (extended — new methods, RoleLevel >= 20 credit-approver check)
IStoreRepository.cs (extended — GetOrdersForDashboardAsync)
StoreRepository.cs (extended)
Kyc/
StoreKycDocumentController.cs
StoreKycDocumentDTOs.cs
StoreKycDocumentService.cs
IStoreKycDocumentRepository.cs
StoreKycDocumentRepository.cs
Order/
OrderService.cs (extended — KycStatus + UnverifiedKycOrderThreshold gate in CreateAsync)
Models/
Store.cs (add CreditLimit, OutstandingBalance, Segment, KycStatus columns)
StoreKycDocument.cs (new)
Enums.cs (add KycStatus enum)
Migrations/
AddStoreCreditAndKyc
appsettings.json
add "StoreManagement": { "UnverifiedKycOrderThreshold": 0 }
Program.cs
register IStoreKycDocumentRepository, StoreKycDocumentRepository, StoreKycDocumentService
```
KYC documents live as a sub-namespace `Features/Store/Kyc/` rather than a top-level feature,
matching the one-feature-per-folder convention (`Features/Store`, `Features/Stock`) — they only
ever belong to a Store and have no independent lifecycle.
### KYC upload logic (pseudo)
```
POST /api/stores/{id}/kyc-documents — multipart (documentType, file):
1. Load Store by id, reject if missing/inactive or caller lacks store scope
2. Ensure wwwroot/uploads/kyc/{storeId}/ exists
3. Save file as {guid}.{ext}, record FileReference = "uploads/kyc/{storeId}/{guid}.{ext}"
4. Insert StoreKycDocument row, commit in the same UoW transaction
```
### Order-creation KYC gate (pseudo)
```
OrderService.CreateAsync — before inserting the order:
1. Load Store by request.StoreId
2. If Store.KycStatus != Verified:
threshold = config["StoreManagement:UnverifiedKycOrderThreshold"]
if request.TotalAmount > threshold: reject (return null → 403 at controller)
```
</content>