Merge pull request 'Dev' (#4) from dev into production
Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
@@ -29,6 +29,7 @@ public class AppDBContext(DbContextOptions<AppDBContext> options) : DbContext(op
|
|||||||
public DbSet<UserStoreScope> UserStoreScopes { get; set; }
|
public DbSet<UserStoreScope> UserStoreScopes { get; set; }
|
||||||
public DbSet<StockBalance> StockBalances { get; set; }
|
public DbSet<StockBalance> StockBalances { get; set; }
|
||||||
public DbSet<StockMovement> StockMovements { get; set; }
|
public DbSet<StockMovement> StockMovements { get; set; }
|
||||||
|
public DbSet<StoreKycDocument> StoreKycDocuments { get; set; }
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ public static class RoleAndPermissionSeed
|
|||||||
("stores.create", "Create stores"),
|
("stores.create", "Create stores"),
|
||||||
("stores.update", "Update stores"),
|
("stores.update", "Update stores"),
|
||||||
("stores.delete", "Delete 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.view", "View warehouses"),
|
||||||
("warehouses.create", "Create 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 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 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 supervisorPerms = salesRepPerms.Concat(["orders.delete", "stores.create", "stores.update", "stores.credit.update"]).ToArray();
|
||||||
var areaManagerPerms = supervisorPerms.Concat(["vehicles.view", "warehouses.view"]).Concat(itemManagePerms).Distinct().ToArray();
|
var areaManagerPerms = supervisorPerms.Concat(["vehicles.view", "warehouses.view", "stores.kyc.verify"]).Concat(itemManagePerms).Distinct().ToArray();
|
||||||
var areaSupervisorPerms = areaManagerPerms.Concat(["routes.create", "routes.update"]).Concat(itemPerms).Distinct().ToArray();
|
var areaSupervisorPerms = areaManagerPerms.Concat(["routes.create", "routes.update", "stores.delete"]).Concat(itemPerms).Distinct().ToArray();
|
||||||
|
|
||||||
var regionalManagerPerms = new[]
|
var regionalManagerPerms = new[]
|
||||||
{
|
{
|
||||||
"orders.view", "orders.create", "orders.update", "orders.delete",
|
"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",
|
"routes.view", "routes.create", "routes.update", "routes.delete",
|
||||||
"vehicles.view", "vehicles.create", "vehicles.update", "vehicles.delete",
|
"vehicles.view", "vehicles.create", "vehicles.update", "vehicles.delete",
|
||||||
"warehouses.view", "warehouses.create", "warehouses.update", "warehouses.delete",
|
"warehouses.view", "warehouses.create", "warehouses.update", "warehouses.delete",
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
|
using Distribution.Features.Store;
|
||||||
using Distribution.Infra.Authorization;
|
using Distribution.Infra.Authorization;
|
||||||
using Distribution.Infra.UoW;
|
using Distribution.Infra.UoW;
|
||||||
|
using Distribution.Models;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
namespace Distribution.Features.Order;
|
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;
|
private const int GlobalScopeRoleLevel = 50;
|
||||||
|
|
||||||
@@ -63,6 +72,14 @@ public class OrderService(IOrderRepository repo, IUnitOfWork uow, ICurrentUserSe
|
|||||||
{
|
{
|
||||||
if (!await HasStoreScopeAsync(request.StoreId)) return null;
|
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
|
var order = new Models.Order
|
||||||
{
|
{
|
||||||
FK_StoreId = request.StoreId,
|
FK_StoreId = request.StoreId,
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ public interface IStoreRepository
|
|||||||
Task AddAsync(Models.Store entity);
|
Task AddAsync(Models.Store entity);
|
||||||
void Update(Models.Store entity);
|
void Update(Models.Store entity);
|
||||||
void Remove(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);
|
var deleted = await service.DeleteAsync(id, ct);
|
||||||
return deleted ? NoContent() : NotFound();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using Distribution.Models;
|
||||||
|
|
||||||
namespace Distribution.Features.Store;
|
namespace Distribution.Features.Store;
|
||||||
|
|
||||||
public record CreateStoreRequest(
|
public record CreateStoreRequest(
|
||||||
@@ -30,5 +32,25 @@ public record StoreResponse(
|
|||||||
decimal Longitude,
|
decimal Longitude,
|
||||||
decimal OneTimeAmount,
|
decimal OneTimeAmount,
|
||||||
decimal CreditAmount,
|
decimal CreditAmount,
|
||||||
|
decimal CreditLimit,
|
||||||
|
decimal OutstandingBalance,
|
||||||
|
string? Segment,
|
||||||
|
KycStatus KycStatus,
|
||||||
bool IsActive,
|
bool IsActive,
|
||||||
DateTime CreatedAt);
|
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;
|
entity.IsActive = false;
|
||||||
context.Stores.Update(entity);
|
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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
using Distribution.Infra.Authorization;
|
using Distribution.Infra.Authorization;
|
||||||
using Distribution.Infra.UoW;
|
using Distribution.Infra.UoW;
|
||||||
|
using Distribution.Models;
|
||||||
|
|
||||||
namespace Distribution.Features.Store;
|
namespace Distribution.Features.Store;
|
||||||
|
|
||||||
public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserService currentUser, IScopeAccessService scopeAccess)
|
public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserService currentUser, IScopeAccessService scopeAccess)
|
||||||
{
|
{
|
||||||
private const int GlobalScopeRoleLevel = 50;
|
private const int GlobalScopeRoleLevel = 50;
|
||||||
|
private const int CreditApproverRoleLevel = 20;
|
||||||
|
|
||||||
private bool HasGlobalScope => currentUser.RoleLevel >= GlobalScopeRoleLevel;
|
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);
|
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()
|
public async Task<List<StoreResponse>> GetAllAsync()
|
||||||
{
|
{
|
||||||
var stores = (await repo.GetAllAsync()).Where(s => s.IsActive).ToList();
|
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();
|
var accessibleStoreIds = (await scopeAccess.GetAccessibleStoreIdsAsync(currentUser.UserId.Value)).ToHashSet();
|
||||||
stores = stores.Where(s => accessibleStoreIds.Contains(s.Id)).ToList();
|
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)
|
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);
|
var store = await repo.GetByIdAsync(id);
|
||||||
if (store is null || !store.IsActive) return null;
|
if (store is null || !store.IsActive) return null;
|
||||||
if (!await HasStoreScopeAsync(id)) 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)
|
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);
|
await uow.RollbackAsync(ct);
|
||||||
throw;
|
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)
|
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);
|
await uow.RollbackAsync(ct);
|
||||||
throw;
|
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)
|
public async Task<bool> DeleteAsync(Guid id, CancellationToken ct = default)
|
||||||
@@ -106,4 +112,131 @@ public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserSe
|
|||||||
}
|
}
|
||||||
return true;
|
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
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000017"),
|
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",
|
Code = "warehouses.view",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "View warehouses",
|
Description = "View warehouses",
|
||||||
@@ -387,7 +403,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000018"),
|
Id = new Guid("20000000-0000-0000-0000-000000000020"),
|
||||||
Code = "warehouses.create",
|
Code = "warehouses.create",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Create warehouses",
|
Description = "Create warehouses",
|
||||||
@@ -395,7 +411,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000019"),
|
Id = new Guid("20000000-0000-0000-0000-000000000021"),
|
||||||
Code = "warehouses.update",
|
Code = "warehouses.update",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Update warehouses",
|
Description = "Update warehouses",
|
||||||
@@ -403,7 +419,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000020"),
|
Id = new Guid("20000000-0000-0000-0000-000000000022"),
|
||||||
Code = "warehouses.delete",
|
Code = "warehouses.delete",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Delete warehouses",
|
Description = "Delete warehouses",
|
||||||
@@ -411,7 +427,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000021"),
|
Id = new Guid("20000000-0000-0000-0000-000000000023"),
|
||||||
Code = "orders.view",
|
Code = "orders.view",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "View orders",
|
Description = "View orders",
|
||||||
@@ -419,7 +435,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000022"),
|
Id = new Guid("20000000-0000-0000-0000-000000000024"),
|
||||||
Code = "orders.create",
|
Code = "orders.create",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Create orders",
|
Description = "Create orders",
|
||||||
@@ -427,7 +443,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000023"),
|
Id = new Guid("20000000-0000-0000-0000-000000000025"),
|
||||||
Code = "orders.update",
|
Code = "orders.update",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Update orders",
|
Description = "Update orders",
|
||||||
@@ -435,7 +451,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000024"),
|
Id = new Guid("20000000-0000-0000-0000-000000000026"),
|
||||||
Code = "orders.delete",
|
Code = "orders.delete",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Delete orders",
|
Description = "Delete orders",
|
||||||
@@ -443,7 +459,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000025"),
|
Id = new Guid("20000000-0000-0000-0000-000000000027"),
|
||||||
Code = "users.view",
|
Code = "users.view",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "View users",
|
Description = "View users",
|
||||||
@@ -451,7 +467,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000026"),
|
Id = new Guid("20000000-0000-0000-0000-000000000028"),
|
||||||
Code = "users.create",
|
Code = "users.create",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Create users",
|
Description = "Create users",
|
||||||
@@ -459,7 +475,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000027"),
|
Id = new Guid("20000000-0000-0000-0000-000000000029"),
|
||||||
Code = "users.update",
|
Code = "users.update",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Update users",
|
Description = "Update users",
|
||||||
@@ -467,7 +483,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000028"),
|
Id = new Guid("20000000-0000-0000-0000-000000000030"),
|
||||||
Code = "users.deactivate",
|
Code = "users.deactivate",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Deactivate users",
|
Description = "Deactivate users",
|
||||||
@@ -475,7 +491,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000029"),
|
Id = new Guid("20000000-0000-0000-0000-000000000031"),
|
||||||
Code = "users.assign_role",
|
Code = "users.assign_role",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Assign a role to a user",
|
Description = "Assign a role to a user",
|
||||||
@@ -483,7 +499,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000030"),
|
Id = new Guid("20000000-0000-0000-0000-000000000032"),
|
||||||
Code = "users.assign_scope",
|
Code = "users.assign_scope",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Assign region/route/store scope to a user",
|
Description = "Assign region/route/store scope to a user",
|
||||||
@@ -491,7 +507,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000031"),
|
Id = new Guid("20000000-0000-0000-0000-000000000033"),
|
||||||
Code = "items.view",
|
Code = "items.view",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "View items, brands and UOMs",
|
Description = "View items, brands and UOMs",
|
||||||
@@ -499,7 +515,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000032"),
|
Id = new Guid("20000000-0000-0000-0000-000000000034"),
|
||||||
Code = "items.create",
|
Code = "items.create",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Create items, brands and UOMs",
|
Description = "Create items, brands and UOMs",
|
||||||
@@ -507,7 +523,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000033"),
|
Id = new Guid("20000000-0000-0000-0000-000000000035"),
|
||||||
Code = "items.update",
|
Code = "items.update",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Update items, brands and UOMs",
|
Description = "Update items, brands and UOMs",
|
||||||
@@ -515,7 +531,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000034"),
|
Id = new Guid("20000000-0000-0000-0000-000000000036"),
|
||||||
Code = "items.delete",
|
Code = "items.delete",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Delete items, brands and UOMs",
|
Description = "Delete items, brands and UOMs",
|
||||||
@@ -523,7 +539,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000035"),
|
Id = new Guid("20000000-0000-0000-0000-000000000037"),
|
||||||
Code = "categories.view",
|
Code = "categories.view",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "View categories",
|
Description = "View categories",
|
||||||
@@ -531,7 +547,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000036"),
|
Id = new Guid("20000000-0000-0000-0000-000000000038"),
|
||||||
Code = "categories.create",
|
Code = "categories.create",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Create categories and subcategories",
|
Description = "Create categories and subcategories",
|
||||||
@@ -539,7 +555,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000037"),
|
Id = new Guid("20000000-0000-0000-0000-000000000039"),
|
||||||
Code = "categories.update",
|
Code = "categories.update",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Update categories and subcategories",
|
Description = "Update categories and subcategories",
|
||||||
@@ -547,7 +563,7 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("20000000-0000-0000-0000-000000000038"),
|
Id = new Guid("20000000-0000-0000-0000-000000000040"),
|
||||||
Code = "categories.delete",
|
Code = "categories.delete",
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Description = "Delete categories and subcategories",
|
Description = "Delete categories and subcategories",
|
||||||
@@ -674,22 +690,6 @@ namespace Distribution.Migrations
|
|||||||
b.ToTable("RolePermissions");
|
b.ToTable("RolePermissions");
|
||||||
|
|
||||||
b.HasData(
|
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
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"),
|
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
@@ -699,6 +699,22 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
||||||
@@ -717,33 +733,17 @@ namespace Distribution.Migrations
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000001"),
|
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),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Id = new Guid("aa120c36-488e-34ba-e10a-2ac45e46e119"),
|
Id = new Guid("320ba3fb-666c-ce57-3e61-95c9824c4048"),
|
||||||
IsActive = true
|
|
||||||
},
|
|
||||||
new
|
|
||||||
{
|
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"),
|
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-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"),
|
|
||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -755,6 +755,22 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
||||||
@@ -773,25 +789,25 @@ namespace Distribution.Migrations
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -812,18 +828,10 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000018"),
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Id = new Guid("0dd5c943-3ace-0560-6fbc-54d8e37ce014"),
|
Id = new Guid("f2c14d55-d557-5cd2-a70a-4a6f58933436"),
|
||||||
IsActive = true
|
|
||||||
},
|
|
||||||
new
|
|
||||||
{
|
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"),
|
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
|
||||||
Id = new Guid("ca97fb3d-132c-d8a5-4ab8-f7b8fc60f5e5"),
|
|
||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -835,6 +843,22 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
||||||
@@ -853,25 +877,25 @@ namespace Distribution.Migrations
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -891,6 +915,14 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"),
|
||||||
@@ -899,6 +931,14 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"),
|
||||||
@@ -909,33 +949,17 @@ namespace Distribution.Migrations
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000003"),
|
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),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Id = new Guid("d49f086e-30f0-6ce8-ae96-4395d5e04472"),
|
Id = new Guid("1e7fe1b6-5150-4b99-38ed-088d9495cfd8"),
|
||||||
IsActive = true
|
|
||||||
},
|
|
||||||
new
|
|
||||||
{
|
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-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"),
|
|
||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -947,6 +971,22 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
||||||
@@ -965,25 +1005,25 @@ namespace Distribution.Migrations
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -1003,6 +1043,14 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000009"),
|
||||||
@@ -1011,6 +1059,14 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000017"),
|
||||||
@@ -1021,17 +1077,17 @@ namespace Distribution.Migrations
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -1053,9 +1109,9 @@ namespace Distribution.Migrations
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
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),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -1067,14 +1123,6 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000038"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000038"),
|
||||||
@@ -1084,18 +1132,18 @@ namespace Distribution.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
|
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000021"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000039"),
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
|
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000022"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000040"),
|
||||||
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
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
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -1115,6 +1163,22 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000013"),
|
||||||
@@ -1147,6 +1211,22 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000005"),
|
||||||
@@ -1211,22 +1291,6 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000019"),
|
||||||
@@ -1243,6 +1307,22 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000001"),
|
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000001"),
|
||||||
@@ -1253,25 +1333,9 @@ namespace Distribution.Migrations
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
|
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),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Id = new Guid("1d227ae7-0eb9-c742-41df-3472718cb077"),
|
Id = new Guid("43a4c7b4-a50f-aa37-b147-a30636d9d65f"),
|
||||||
IsActive = true
|
|
||||||
},
|
|
||||||
new
|
|
||||||
{
|
|
||||||
FK_RoleId = new Guid("10000000-0000-0000-0000-000000000005"),
|
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-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"),
|
|
||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
@@ -1323,6 +1387,22 @@ namespace Distribution.Migrations
|
|||||||
IsActive = true
|
IsActive = true
|
||||||
},
|
},
|
||||||
new
|
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_RoleId = new Guid("10000000-0000-0000-0000-000000000006"),
|
||||||
FK_PermissionId = new Guid("20000000-0000-0000-0000-000000000001"),
|
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),
|
CreatedAt = new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
Id = new Guid("1d6273d4-db6a-d70e-4b5f-98cb634d668a"),
|
Id = new Guid("1d6273d4-db6a-d70e-4b5f-98cb634d668a"),
|
||||||
IsActive = true
|
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")
|
b.Property<decimal>("CreditAmount")
|
||||||
.HasColumnType("decimal(65,30)");
|
.HasColumnType("decimal(65,30)");
|
||||||
|
|
||||||
|
b.Property<decimal>("CreditLimit")
|
||||||
|
.HasColumnType("decimal(65,30)");
|
||||||
|
|
||||||
b.Property<Guid>("FK_RouteId")
|
b.Property<Guid>("FK_RouteId")
|
||||||
.HasColumnType("char(36)");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<bool>("IsActive")
|
b.Property<bool>("IsActive")
|
||||||
.HasColumnType("tinyint(1)");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<int>("KycStatus")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<decimal>("Latitude")
|
b.Property<decimal>("Latitude")
|
||||||
.HasColumnType("decimal(65,30)");
|
.HasColumnType("decimal(65,30)");
|
||||||
|
|
||||||
@@ -1784,10 +1886,16 @@ namespace Distribution.Migrations
|
|||||||
b.Property<decimal>("OneTimeAmount")
|
b.Property<decimal>("OneTimeAmount")
|
||||||
.HasColumnType("decimal(65,30)");
|
.HasColumnType("decimal(65,30)");
|
||||||
|
|
||||||
|
b.Property<decimal>("OutstandingBalance")
|
||||||
|
.HasColumnType("decimal(65,30)");
|
||||||
|
|
||||||
b.Property<string>("OwnerName")
|
b.Property<string>("OwnerName")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Segment")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("StoreAddress")
|
b.Property<string>("StoreAddress")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
@@ -1803,6 +1911,39 @@ namespace Distribution.Migrations
|
|||||||
b.ToTable("Stores");
|
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 =>
|
modelBuilder.Entity("Distribution.Models.SubCategory", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
@@ -2203,6 +2344,17 @@ namespace Distribution.Migrations
|
|||||||
b.Navigation("Route");
|
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 =>
|
modelBuilder.Entity("Distribution.Models.SubCategory", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Distribution.Models.Category", "Category")
|
b.HasOne("Distribution.Models.Category", "Category")
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
namespace Distribution.Models
|
namespace Distribution.Models
|
||||||
{
|
{
|
||||||
public enum LocationType { Warehouse, Vehicle }
|
public enum LocationType
|
||||||
|
{
|
||||||
|
Warehouse,
|
||||||
|
Vehicle
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum KycStatus
|
||||||
|
{
|
||||||
|
Pending,
|
||||||
|
Verified,
|
||||||
|
Rejected }
|
||||||
|
|
||||||
public enum MovementType
|
public enum MovementType
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ namespace Distribution.Models
|
|||||||
public decimal Longitude { get; set; } = 0;
|
public decimal Longitude { get; set; } = 0;
|
||||||
public decimal OneTimeAmount { get; set; } = 0;
|
public decimal OneTimeAmount { get; set; } = 0;
|
||||||
public decimal CreditAmount { 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; }
|
public Guid FK_RouteId { get; set; }
|
||||||
[ForeignKey("FK_RouteId")]
|
[ForeignKey("FK_RouteId")]
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ using Distribution.Features.Region;
|
|||||||
using Distribution.Features.Role;
|
using Distribution.Features.Role;
|
||||||
using Distribution.Features.Route;
|
using Distribution.Features.Route;
|
||||||
using Distribution.Features.Store;
|
using Distribution.Features.Store;
|
||||||
|
using Distribution.Features.Store.Kyc;
|
||||||
using Distribution.Features.Sync;
|
using Distribution.Features.Sync;
|
||||||
using Distribution.Features.Uom;
|
using Distribution.Features.Uom;
|
||||||
using Distribution.Features.User;
|
using Distribution.Features.User;
|
||||||
@@ -46,6 +47,7 @@ builder.Services.AddScoped<IBrandRepository, BrandRepository>();
|
|||||||
builder.Services.AddScoped<IUomRepository, UomRepository>();
|
builder.Services.AddScoped<IUomRepository, UomRepository>();
|
||||||
builder.Services.AddScoped<IItemRepository, ItemRepository>();
|
builder.Services.AddScoped<IItemRepository, ItemRepository>();
|
||||||
builder.Services.AddScoped<IStockRepository, StockRepository>();
|
builder.Services.AddScoped<IStockRepository, StockRepository>();
|
||||||
|
builder.Services.AddScoped<IStoreKycDocumentRepository, StoreKycDocumentRepository>();
|
||||||
|
|
||||||
builder.Services.AddScoped<RegionService>();
|
builder.Services.AddScoped<RegionService>();
|
||||||
builder.Services.AddScoped<RouteService>();
|
builder.Services.AddScoped<RouteService>();
|
||||||
@@ -62,6 +64,7 @@ builder.Services.AddScoped<UomService>();
|
|||||||
builder.Services.AddScoped<ItemService>();
|
builder.Services.AddScoped<ItemService>();
|
||||||
builder.Services.AddScoped<SyncService>();
|
builder.Services.AddScoped<SyncService>();
|
||||||
builder.Services.AddScoped<StockService>();
|
builder.Services.AddScoped<StockService>();
|
||||||
|
builder.Services.AddScoped<StoreKycDocumentService>();
|
||||||
|
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
builder.Services.AddScoped<ICurrentUserService, CurrentUserService>();
|
builder.Services.AddScoped<ICurrentUserService, CurrentUserService>();
|
||||||
|
|||||||
@@ -14,5 +14,8 @@
|
|||||||
"Issuer": "Distribution.Api",
|
"Issuer": "Distribution.Api",
|
||||||
"Audience": "Distribution.Api",
|
"Audience": "Distribution.Api",
|
||||||
"ExpiryMinutes": 120
|
"ExpiryMinutes": 120
|
||||||
|
},
|
||||||
|
"StoreManagement": {
|
||||||
|
"UnverifiedKycOrderThreshold": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,32 @@
|
|||||||
# 12 — Store Management (Beyond CRUD)
|
# 12 — Store Management (Beyond CRUD)
|
||||||
|
|
||||||
**Status**: Not Started
|
**Status**: Done — migration applied to the database
|
||||||
**Depends On**: 00 — Existing Gap Fixes
|
**Depends On**: 00 — Existing Gap Fixes, 10 — Region Management, 11 — Route & Sales Management
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
Store CRUD already exists (`Features/Store`). This step covers everything in
|
Store CRUD already exists (`Features/Store`). This step adds everything in
|
||||||
[mainPlan.md §4](./mainPlan.md#4-store-outlet-management) that isn't
|
[mainPlan.md §4](./mainPlan.md#4-store-outlet-management) that isn't plain CRUD: credit control,
|
||||||
plain CRUD: KYC, credit, segmentation, and dashboarding.
|
KYC verification, segmentation, outstanding balance, visit history, scheme eligibility, and a
|
||||||
|
sales dashboard.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Background / Context
|
## Background / Context
|
||||||
|
|
||||||
`Store` currently has no credit limit, outstanding balance, segment, or KYC fields — flagged as
|
`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
|
### 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`
|
Store (existing, add columns)
|
||||||
(`Pending`, `Verified`, `Rejected`).
|
├── 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
|
```csharp
|
||||||
for this step's data model, just the record).
|
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
|
## API Endpoints
|
||||||
|
|
||||||
| Function reference | Endpoint intent |
|
### Existing (unchanged)
|
||||||
|---|---|
|
| Method | Route | Permission | Notes |
|
||||||
| `createStore(storeData, kycDocs)` | Extends existing `POST /api/stores` with doc upload |
|
|---|---|---|---|
|
||||||
| `verifyStoreKyc(storeId)` | `PUT /api/stores/{id}/kyc/verify` |
|
| GET | /api/stores | stores.view | |
|
||||||
| `updateStoreCreditLimit(storeId, newLimit, approverId)` | `PUT /api/stores/{id}/credit-limit` |
|
| GET | /api/stores/{id} | stores.view | |
|
||||||
| `getStoreOutstandingBalance(storeId)` | `GET /api/stores/{id}/outstanding-balance` |
|
| POST | /api/stores | stores.create | |
|
||||||
| `classifyStore(storeId, segment)` | `PUT /api/stores/{id}/segment` |
|
| PUT | /api/stores/{id} | stores.update | |
|
||||||
| `deactivateStore(storeId, reason)` | Extends existing `DELETE /api/stores/{id}` with a reason field |
|
| DELETE | /api/stores/{id} | stores.delete | Soft delete |
|
||||||
| `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) |
|
### New
|
||||||
| `getStoreSalesDashboard(storeId, period)` | `GET /api/stores/{id}/dashboard?period=...` |
|
| 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
|
## Business Rules
|
||||||
|
|
||||||
- `updateStoreCreditLimit` requires an approver at Supervisor level or above.
|
1. `updateStoreCreditLimit` requires the authenticated caller to have `RoleLevel >= 20`
|
||||||
- A store with `KycStatus != Verified` should not be able to place orders above a configurable
|
(Supervisor or above) — enforced by the `stores.credit.update` policy plus a role-level check
|
||||||
threshold (or at all) — confirm exact rule with the user before implementing.
|
in the service, same pattern as `StoreService.HasGlobalScope`.
|
||||||
- `deactivateStore` blocks new orders against it, matching the existing `IsActive` soft-delete
|
2. A store with `KycStatus != Verified` may only place orders up to
|
||||||
filter already used in `OrderService`.
|
`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
|
## Open Questions
|
||||||
|
|
||||||
- Is `OutstandingBalance` a cached/denormalized field updated on invoice/payment events, or always
|
- None. Resolved in planning discussion (2026-08-20): OutstandingBalance is cached/denormalized;
|
||||||
computed live from Finance records?
|
KYC document type is free text with local disk storage; unverified stores are gated by a
|
||||||
- What document types are required for KYC, and is file storage local, blob, or third-party?
|
configurable order-value threshold rather than a hard block.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Implementation Notes
|
## 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>
|
||||||
|
|||||||
Reference in New Issue
Block a user