Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f95fda3806 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=187.127.102.190;Port=3306;Database=distribution_db;User=kalana;Password=kalana@hexdive"
|
||||
"DefaultConnection": "Server=187.127.102.190;Port=3306;Database=distribution;User=kalana;Password=kalana@hexdive"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
|
||||
@@ -13,7 +13,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("Distribution.Tests")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+397af8fd597bb7dd2d4372bf717d06c8e49552b7")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+aa7ea37ab61a149a38d83283c5dabd76bf5a39b3")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("Distribution.Tests")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("Distribution.Tests")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
569664876b2d87d1ec65add142012e5eae24d860ed90b6cc736c1cb4bae13b9a
|
||||
5c052f1f25bc37b6a51a3abe0e2b79d99d21422d5ab89151faea450c0ddb9cc0
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -27,6 +27,8 @@ public class AppDBContext(DbContextOptions<AppDBContext> options) : DbContext(op
|
||||
public DbSet<UserRegionScope> UserRegionScopes { get; set; }
|
||||
public DbSet<UserRouteScope> UserRouteScopes { get; set; }
|
||||
public DbSet<UserStoreScope> UserStoreScopes { get; set; }
|
||||
public DbSet<StockBalance> StockBalances { get; set; }
|
||||
public DbSet<StockMovement> StockMovements { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -51,6 +53,10 @@ public class AppDBContext(DbContextOptions<AppDBContext> options) : DbContext(op
|
||||
.HasForeignKey(u => u.FK_ReportsToUserId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
modelBuilder.Entity<StockBalance>()
|
||||
.HasIndex(sb => new { sb.FK_ItemId, sb.LocationId })
|
||||
.IsUnique();
|
||||
|
||||
Seed.RoleAndPermissionSeed.Apply(modelBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using Distribution.Models;
|
||||
|
||||
namespace Distribution.Features.Stock;
|
||||
|
||||
public interface IStockRepository
|
||||
{
|
||||
// Balance
|
||||
Task<StockBalance?> GetBalanceAsync(Guid itemId, Guid locationId);
|
||||
Task<List<StockBalance>> GetBalancesAsync(Guid? locationId, LocationType? locationType, Guid? itemId, int page, int pageSize);
|
||||
Task<int> GetBalancesCountAsync(Guid? locationId, LocationType? locationType, Guid? itemId);
|
||||
Task<List<StockBalance>> GetBalancesByItemAsync(Guid itemId);
|
||||
Task AddBalanceAsync(StockBalance balance);
|
||||
void UpdateBalance(StockBalance balance);
|
||||
|
||||
// Movements
|
||||
Task AddMovementAsync(StockMovement movement);
|
||||
Task<List<StockMovement>> GetMovementsAsync(Guid? locationId, Guid? itemId, MovementType? type, DateTime? from, DateTime? to, int page, int pageSize);
|
||||
Task<int> GetMovementsCountAsync(Guid? locationId, Guid? itemId, MovementType? type, DateTime? from, DateTime? to);
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using Distribution.Infra.Authorization;
|
||||
using Distribution.Models;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Distribution.Features.Stock;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/stock")]
|
||||
[Authorize]
|
||||
public class StockController(StockService service, ICurrentUserService currentUser) : ControllerBase
|
||||
{
|
||||
// ── Query ──────────────────────────────────────────────────────────────
|
||||
|
||||
[HttpGet("balances")]
|
||||
public async Task<IActionResult> GetBalances(
|
||||
[FromQuery] Guid? locationId,
|
||||
[FromQuery] LocationType? locationType,
|
||||
[FromQuery] Guid? itemId,
|
||||
[FromQuery] int page = 1,
|
||||
[FromQuery] int pageSize = 20)
|
||||
{
|
||||
var result = await service.GetBalancesAsync(locationId, locationType, itemId, page, pageSize);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("balances/{itemId}/total")]
|
||||
public async Task<IActionResult> GetItemTotal(Guid itemId)
|
||||
{
|
||||
var result = await service.GetItemTotalAsync(itemId);
|
||||
if (result is null) return NotFound();
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("movements")]
|
||||
public async Task<IActionResult> GetMovements(
|
||||
[FromQuery] Guid? locationId,
|
||||
[FromQuery] Guid? itemId,
|
||||
[FromQuery] MovementType? type,
|
||||
[FromQuery] DateTime? from,
|
||||
[FromQuery] DateTime? to,
|
||||
[FromQuery] int page = 1,
|
||||
[FromQuery] int pageSize = 20)
|
||||
{
|
||||
var result = await service.GetMovementsAsync(locationId, itemId, type, from, to, page, pageSize);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
// ── Write ──────────────────────────────────────────────────────────────
|
||||
|
||||
[HttpPost("transfer")]
|
||||
public async Task<IActionResult> Transfer(TransferRequest request, CancellationToken ct)
|
||||
{
|
||||
if (currentUser.UserId is null) return Unauthorized();
|
||||
try
|
||||
{
|
||||
var result = await service.TransferAsync(request, currentUser.UserId.Value, ct);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (InvalidOperationException ex) { return BadRequest(ex.Message); }
|
||||
}
|
||||
|
||||
[HttpPost("damage")]
|
||||
public async Task<IActionResult> RecordDamage(DamageRequest request, CancellationToken ct)
|
||||
{
|
||||
if (currentUser.UserId is null) return Unauthorized();
|
||||
try
|
||||
{
|
||||
var result = await service.RecordDamageAsync(request, currentUser.UserId.Value, ct);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (InvalidOperationException ex) { return BadRequest(ex.Message); }
|
||||
}
|
||||
|
||||
[HttpPost("customer-return")]
|
||||
public async Task<IActionResult> RecordCustomerReturn(CustomerReturnRequest request, CancellationToken ct)
|
||||
{
|
||||
if (currentUser.UserId is null) return Unauthorized();
|
||||
try
|
||||
{
|
||||
var result = await service.RecordCustomerReturnAsync(request, currentUser.UserId.Value, ct);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (InvalidOperationException ex) { return BadRequest(ex.Message); }
|
||||
}
|
||||
|
||||
[HttpPost("adjustment")]
|
||||
public async Task<IActionResult> Adjust(AdjustmentRequest request, CancellationToken ct)
|
||||
{
|
||||
if (currentUser.UserId is null) return Unauthorized();
|
||||
try
|
||||
{
|
||||
var result = await service.AdjustAsync(request, currentUser.UserId.Value, ct);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (InvalidOperationException ex) { return BadRequest(ex.Message); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using Distribution.Models;
|
||||
|
||||
namespace Distribution.Features.Stock;
|
||||
|
||||
// Shared pagination wrapper
|
||||
public record PagedResponse<T>(int Page, int PageSize, int Total, List<T> Items);
|
||||
|
||||
// Balance
|
||||
public record StockBalanceResponse(
|
||||
Guid ItemId,
|
||||
string ItemName,
|
||||
Guid LocationId,
|
||||
LocationType LocationType,
|
||||
decimal Quantity,
|
||||
DateTime UpdatedAt);
|
||||
|
||||
public record StockTotalResponse(
|
||||
Guid ItemId,
|
||||
string ItemName,
|
||||
decimal TotalQuantity,
|
||||
List<StockBalanceResponse> Breakdown);
|
||||
|
||||
// Movement
|
||||
public record StockMovementResponse(
|
||||
Guid Id,
|
||||
Guid ItemId,
|
||||
string ItemName,
|
||||
Guid? FromLocationId,
|
||||
LocationType? FromLocationType,
|
||||
Guid? ToLocationId,
|
||||
LocationType? ToLocationType,
|
||||
decimal Quantity,
|
||||
MovementType Type,
|
||||
string? ReasonCode,
|
||||
Guid? ReferenceId,
|
||||
DateTime CreatedAt,
|
||||
Guid CreatedBy);
|
||||
|
||||
// Write requests
|
||||
public record TransferRequest(
|
||||
Guid ItemId,
|
||||
Guid FromLocationId,
|
||||
LocationType FromLocationType,
|
||||
Guid ToLocationId,
|
||||
LocationType ToLocationType,
|
||||
decimal Quantity,
|
||||
Guid? ReferenceId);
|
||||
|
||||
public record DamageRequest(
|
||||
Guid ItemId,
|
||||
Guid LocationId,
|
||||
LocationType LocationType,
|
||||
decimal Quantity,
|
||||
string ReasonCode);
|
||||
|
||||
public record CustomerReturnRequest(
|
||||
Guid ItemId,
|
||||
Guid VehicleId,
|
||||
decimal Quantity,
|
||||
Guid? ReferenceId);
|
||||
|
||||
public record AdjustmentRequest(
|
||||
Guid ItemId,
|
||||
Guid LocationId,
|
||||
LocationType LocationType,
|
||||
decimal Quantity,
|
||||
string ReasonCode);
|
||||
@@ -0,0 +1,70 @@
|
||||
using Distribution.Data;
|
||||
using Distribution.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Distribution.Features.Stock;
|
||||
|
||||
public class StockRepository(AppDBContext db) : IStockRepository
|
||||
{
|
||||
public Task<StockBalance?> GetBalanceAsync(Guid itemId, Guid locationId) =>
|
||||
db.StockBalances
|
||||
.Include(b => b.Item)
|
||||
.FirstOrDefaultAsync(b => b.FK_ItemId == itemId && b.LocationId == locationId);
|
||||
|
||||
public Task<List<StockBalance>> GetBalancesAsync(Guid? locationId, LocationType? locationType, Guid? itemId, int page, int pageSize)
|
||||
{
|
||||
var query = db.StockBalances.Include(b => b.Item).AsQueryable();
|
||||
if (locationId.HasValue) query = query.Where(b => b.LocationId == locationId.Value);
|
||||
if (locationType.HasValue) query = query.Where(b => b.LocationType == locationType.Value);
|
||||
if (itemId.HasValue) query = query.Where(b => b.FK_ItemId == itemId.Value);
|
||||
return query.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync();
|
||||
}
|
||||
|
||||
public Task<int> GetBalancesCountAsync(Guid? locationId, LocationType? locationType, Guid? itemId)
|
||||
{
|
||||
var query = db.StockBalances.AsQueryable();
|
||||
if (locationId.HasValue) query = query.Where(b => b.LocationId == locationId.Value);
|
||||
if (locationType.HasValue) query = query.Where(b => b.LocationType == locationType.Value);
|
||||
if (itemId.HasValue) query = query.Where(b => b.FK_ItemId == itemId.Value);
|
||||
return query.CountAsync();
|
||||
}
|
||||
|
||||
public Task<List<StockBalance>> GetBalancesByItemAsync(Guid itemId) =>
|
||||
db.StockBalances
|
||||
.Include(b => b.Item)
|
||||
.Where(b => b.FK_ItemId == itemId)
|
||||
.ToListAsync();
|
||||
|
||||
public async Task AddBalanceAsync(StockBalance balance) =>
|
||||
await db.StockBalances.AddAsync(balance);
|
||||
|
||||
public void UpdateBalance(StockBalance balance) =>
|
||||
db.StockBalances.Update(balance);
|
||||
|
||||
public async Task AddMovementAsync(StockMovement movement) =>
|
||||
await db.StockMovements.AddAsync(movement);
|
||||
|
||||
public Task<List<StockMovement>> GetMovementsAsync(Guid? locationId, Guid? itemId, MovementType? type, DateTime? from, DateTime? to, int page, int pageSize)
|
||||
{
|
||||
var query = db.StockMovements.Include(m => m.Item).AsQueryable();
|
||||
if (locationId.HasValue)
|
||||
query = query.Where(m => m.FromLocationId == locationId.Value || m.ToLocationId == locationId.Value);
|
||||
if (itemId.HasValue) query = query.Where(m => m.FK_ItemId == itemId.Value);
|
||||
if (type.HasValue) query = query.Where(m => m.Type == type.Value);
|
||||
if (from.HasValue) query = query.Where(m => m.CreatedAt >= from.Value);
|
||||
if (to.HasValue) query = query.Where(m => m.CreatedAt <= to.Value);
|
||||
return query.OrderByDescending(m => m.CreatedAt).Skip((page - 1) * pageSize).Take(pageSize).ToListAsync();
|
||||
}
|
||||
|
||||
public Task<int> GetMovementsCountAsync(Guid? locationId, Guid? itemId, MovementType? type, DateTime? from, DateTime? to)
|
||||
{
|
||||
var query = db.StockMovements.AsQueryable();
|
||||
if (locationId.HasValue)
|
||||
query = query.Where(m => m.FromLocationId == locationId.Value || m.ToLocationId == locationId.Value);
|
||||
if (itemId.HasValue) query = query.Where(m => m.FK_ItemId == itemId.Value);
|
||||
if (type.HasValue) query = query.Where(m => m.Type == type.Value);
|
||||
if (from.HasValue) query = query.Where(m => m.CreatedAt >= from.Value);
|
||||
if (to.HasValue) query = query.Where(m => m.CreatedAt <= to.Value);
|
||||
return query.CountAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
using Distribution.Features.Category;
|
||||
using Distribution.Features.Item;
|
||||
using Distribution.Infra.UoW;
|
||||
using Distribution.Models;
|
||||
|
||||
namespace Distribution.Features.Stock;
|
||||
|
||||
public class StockService(IStockRepository repo, IItemRepository itemRepo, ICategoryRepository categoryRepo, IUnitOfWork uow)
|
||||
{
|
||||
private static StockBalanceResponse MapBalance(StockBalance b) =>
|
||||
new(b.FK_ItemId, b.Item.Name, b.LocationId, b.LocationType, b.Quantity, b.UpdatedAt);
|
||||
|
||||
private static StockMovementResponse MapMovement(StockMovement m) =>
|
||||
new(m.Id, m.FK_ItemId, m.Item.Name, m.FromLocationId, m.FromLocationType,
|
||||
m.ToLocationId, m.ToLocationType, m.Quantity, m.Type, m.ReasonCode,
|
||||
m.ReferenceId, m.CreatedAt, m.CreatedBy);
|
||||
|
||||
// ── Queries ────────────────────────────────────────────────────────────
|
||||
|
||||
public async Task<PagedResponse<StockBalanceResponse>> GetBalancesAsync(
|
||||
Guid? locationId, LocationType? locationType, Guid? itemId, int page, int pageSize)
|
||||
{
|
||||
var items = await repo.GetBalancesAsync(locationId, locationType, itemId, page, pageSize);
|
||||
var total = await repo.GetBalancesCountAsync(locationId, locationType, itemId);
|
||||
return new PagedResponse<StockBalanceResponse>(page, pageSize, total, items.Select(MapBalance).ToList());
|
||||
}
|
||||
|
||||
public async Task<StockTotalResponse?> GetItemTotalAsync(Guid itemId)
|
||||
{
|
||||
var item = await itemRepo.GetByIdAsync(itemId);
|
||||
if (item is null || !item.IsActive) return null;
|
||||
|
||||
var balances = await repo.GetBalancesByItemAsync(itemId);
|
||||
var total = balances.Sum(b => b.Quantity);
|
||||
return new StockTotalResponse(itemId, item.Name, total, balances.Select(MapBalance).ToList());
|
||||
}
|
||||
|
||||
public async Task<PagedResponse<StockMovementResponse>> GetMovementsAsync(
|
||||
Guid? locationId, Guid? itemId, MovementType? type, DateTime? from, DateTime? to, int page, int pageSize)
|
||||
{
|
||||
var items = await repo.GetMovementsAsync(locationId, itemId, type, from, to, page, pageSize);
|
||||
var total = await repo.GetMovementsCountAsync(locationId, itemId, type, from, to);
|
||||
return new PagedResponse<StockMovementResponse>(page, pageSize, total, items.Select(MapMovement).ToList());
|
||||
}
|
||||
|
||||
// ── Writes ─────────────────────────────────────────────────────────────
|
||||
|
||||
public async Task<StockMovementResponse> TransferAsync(TransferRequest request, Guid userId, CancellationToken ct = default)
|
||||
{
|
||||
await EnsureStockAsync(request.ItemId, request.FromLocationId, request.Quantity);
|
||||
|
||||
var movement = new StockMovement
|
||||
{
|
||||
FK_ItemId = request.ItemId,
|
||||
FromLocationId = request.FromLocationId,
|
||||
FromLocationType = request.FromLocationType,
|
||||
ToLocationId = request.ToLocationId,
|
||||
ToLocationType = request.ToLocationType,
|
||||
Quantity = request.Quantity,
|
||||
Type = MovementType.Transfer,
|
||||
ReferenceId = request.ReferenceId,
|
||||
CreatedBy = userId
|
||||
};
|
||||
|
||||
await uow.BeginAsync(ct);
|
||||
try
|
||||
{
|
||||
await ApplyTransferAsync(request.ItemId, request.FromLocationId, request.ToLocationId, request.ToLocationType, request.Quantity);
|
||||
await repo.AddMovementAsync(movement);
|
||||
await uow.CommitAsync(ct);
|
||||
}
|
||||
catch { await uow.RollbackAsync(ct); throw; }
|
||||
|
||||
return MapMovement(movement);
|
||||
}
|
||||
|
||||
public async Task<StockMovementResponse> RecordDamageAsync(DamageRequest request, Guid userId, CancellationToken ct = default)
|
||||
{
|
||||
await EnsureStockAsync(request.ItemId, request.LocationId, request.Quantity);
|
||||
|
||||
var movement = new StockMovement
|
||||
{
|
||||
FK_ItemId = request.ItemId,
|
||||
FromLocationId = request.LocationId,
|
||||
FromLocationType = request.LocationType,
|
||||
Quantity = request.Quantity,
|
||||
Type = MovementType.Damage,
|
||||
ReasonCode = request.ReasonCode,
|
||||
CreatedBy = userId
|
||||
};
|
||||
|
||||
await uow.BeginAsync(ct);
|
||||
try
|
||||
{
|
||||
await DebitBalanceAsync(request.ItemId, request.LocationId, request.Quantity);
|
||||
await repo.AddMovementAsync(movement);
|
||||
await uow.CommitAsync(ct);
|
||||
}
|
||||
catch { await uow.RollbackAsync(ct); throw; }
|
||||
|
||||
return MapMovement(movement);
|
||||
}
|
||||
|
||||
public async Task<StockMovementResponse> RecordCustomerReturnAsync(CustomerReturnRequest request, Guid userId, CancellationToken ct = default)
|
||||
{
|
||||
var item = await itemRepo.GetByIdAsync(request.ItemId)
|
||||
?? throw new InvalidOperationException("Item not found.");
|
||||
|
||||
var category = await categoryRepo.GetByIdAsync(item.FK_CategoryId)
|
||||
?? throw new InvalidOperationException("Category not found.");
|
||||
|
||||
if (!category.AllowCustomerReturn)
|
||||
throw new InvalidOperationException($"Customer returns are not allowed for category '{category.Name}'.");
|
||||
|
||||
var movement = new StockMovement
|
||||
{
|
||||
FK_ItemId = request.ItemId,
|
||||
ToLocationId = request.VehicleId,
|
||||
ToLocationType = LocationType.Vehicle,
|
||||
Quantity = request.Quantity,
|
||||
Type = MovementType.CustomerReturn,
|
||||
ReferenceId = request.ReferenceId,
|
||||
CreatedBy = userId
|
||||
};
|
||||
|
||||
await uow.BeginAsync(ct);
|
||||
try
|
||||
{
|
||||
await CreditBalanceAsync(request.ItemId, request.VehicleId, LocationType.Vehicle, request.Quantity);
|
||||
await repo.AddMovementAsync(movement);
|
||||
await uow.CommitAsync(ct);
|
||||
}
|
||||
catch { await uow.RollbackAsync(ct); throw; }
|
||||
|
||||
return MapMovement(movement);
|
||||
}
|
||||
|
||||
public async Task<StockMovementResponse> AdjustAsync(AdjustmentRequest request, Guid userId, CancellationToken ct = default)
|
||||
{
|
||||
var balance = await repo.GetBalanceAsync(request.ItemId, request.LocationId);
|
||||
if (balance is not null && balance.Quantity + request.Quantity < 0)
|
||||
throw new InvalidOperationException("Adjustment would result in negative stock.");
|
||||
|
||||
var movement = new StockMovement
|
||||
{
|
||||
FK_ItemId = request.ItemId,
|
||||
FromLocationId = request.Quantity < 0 ? request.LocationId : null,
|
||||
FromLocationType = request.Quantity < 0 ? request.LocationType : null,
|
||||
ToLocationId = request.Quantity > 0 ? request.LocationId : null,
|
||||
ToLocationType = request.Quantity > 0 ? request.LocationType : null,
|
||||
Quantity = Math.Abs(request.Quantity),
|
||||
Type = MovementType.Adjustment,
|
||||
ReasonCode = request.ReasonCode,
|
||||
CreatedBy = userId
|
||||
};
|
||||
|
||||
await uow.BeginAsync(ct);
|
||||
try
|
||||
{
|
||||
if (balance is null)
|
||||
{
|
||||
await repo.AddBalanceAsync(new StockBalance
|
||||
{
|
||||
FK_ItemId = request.ItemId,
|
||||
LocationId = request.LocationId,
|
||||
LocationType = request.LocationType,
|
||||
Quantity = request.Quantity
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
balance.Quantity += request.Quantity;
|
||||
balance.UpdatedAt = DateTime.Now;
|
||||
repo.UpdateBalance(balance);
|
||||
}
|
||||
await repo.AddMovementAsync(movement);
|
||||
await uow.CommitAsync(ct);
|
||||
}
|
||||
catch { await uow.RollbackAsync(ct); throw; }
|
||||
|
||||
return MapMovement(movement);
|
||||
}
|
||||
|
||||
// ── Helpers ────────────────────────────────────────────────────────────
|
||||
|
||||
private async Task EnsureStockAsync(Guid itemId, Guid locationId, decimal quantity)
|
||||
{
|
||||
var balance = await repo.GetBalanceAsync(itemId, locationId);
|
||||
if (balance is null || balance.Quantity < quantity)
|
||||
throw new InvalidOperationException("Insufficient stock at the specified location.");
|
||||
}
|
||||
|
||||
private async Task DebitBalanceAsync(Guid itemId, Guid locationId, decimal quantity)
|
||||
{
|
||||
var balance = await repo.GetBalanceAsync(itemId, locationId)
|
||||
?? throw new InvalidOperationException("No stock balance found.");
|
||||
balance.Quantity -= quantity;
|
||||
balance.UpdatedAt = DateTime.Now;
|
||||
repo.UpdateBalance(balance);
|
||||
}
|
||||
|
||||
private async Task CreditBalanceAsync(Guid itemId, Guid locationId, LocationType locationType, decimal quantity)
|
||||
{
|
||||
var balance = await repo.GetBalanceAsync(itemId, locationId);
|
||||
if (balance is null)
|
||||
{
|
||||
await repo.AddBalanceAsync(new StockBalance
|
||||
{
|
||||
FK_ItemId = itemId,
|
||||
LocationId = locationId,
|
||||
LocationType = locationType,
|
||||
Quantity = quantity
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
balance.Quantity += quantity;
|
||||
balance.UpdatedAt = DateTime.Now;
|
||||
repo.UpdateBalance(balance);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ApplyTransferAsync(Guid itemId, Guid fromLocationId, Guid toLocationId, LocationType toLocationType, decimal quantity)
|
||||
{
|
||||
await DebitBalanceAsync(itemId, fromLocationId, quantity);
|
||||
await CreditBalanceAsync(itemId, toLocationId, toLocationType, quantity);
|
||||
}
|
||||
}
|
||||
@@ -1,362 +0,0 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Distribution.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Distribution.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDBContext))]
|
||||
[Migration("20260818065939_initialDbCreate")]
|
||||
partial class initialDbCreate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "10.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.DeliveryRun", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<Guid>("FK_RouteId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("FK_VehicleId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int>("Meterend")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Meterstart")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FK_RouteId");
|
||||
|
||||
b.HasIndex("FK_VehicleId");
|
||||
|
||||
b.ToTable("DeliveryRuns");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Item", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Order", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<Guid>("FK_StoreId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<DateTime>("OrderDate")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<decimal>("TotalAmount")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FK_StoreId");
|
||||
|
||||
b.ToTable("Orders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.OrderItem", b =>
|
||||
{
|
||||
b.Property<Guid>("FK_OrderId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("FK_ItemId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<Guid>("Id")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int>("Quantity")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("FK_OrderId", "FK_ItemId");
|
||||
|
||||
b.HasIndex("FK_ItemId");
|
||||
|
||||
b.ToTable("OrderItems");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Region", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Regions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Route", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("EndPoint")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<decimal>("Length")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.Property<string>("RouteName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StartPoint")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Routes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.SaleRoute", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SaleRoutes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Store", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<decimal>("CreditAmount")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<decimal>("Latitude")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.Property<decimal>("Longitude")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.Property<decimal>("OneTimeAmount")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.Property<string>("OwnerName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StoreAddress")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StoreName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Stores");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Vehicle", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("NumberPlate")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("RegNumber")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Vehicles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Warehouse", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Location")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid?>("VehicleId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("VehicleId");
|
||||
|
||||
b.ToTable("Warehouses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.DeliveryRun", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Route", "Route")
|
||||
.WithMany()
|
||||
.HasForeignKey("FK_RouteId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Distribution.Models.Vehicle", "Vehicle")
|
||||
.WithMany()
|
||||
.HasForeignKey("FK_VehicleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Route");
|
||||
|
||||
b.Navigation("Vehicle");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Order", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Store", "Store")
|
||||
.WithMany()
|
||||
.HasForeignKey("FK_StoreId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Store");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.OrderItem", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Item", "Item")
|
||||
.WithMany()
|
||||
.HasForeignKey("FK_ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Distribution.Models.Order", "Order")
|
||||
.WithMany()
|
||||
.HasForeignKey("FK_OrderId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
|
||||
b.Navigation("Order");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Warehouse", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Vehicle", "Vehicle")
|
||||
.WithMany()
|
||||
.HasForeignKey("VehicleId");
|
||||
|
||||
b.Navigation("Vehicle");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,281 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Distribution.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class initialDbCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterDatabase()
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Items",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", 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_Items", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Regions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Name = table.Column<string>(type: "longtext", 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_Regions", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Routes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
RouteName = table.Column<string>(type: "longtext", nullable: false),
|
||||
StartPoint = table.Column<string>(type: "longtext", nullable: false),
|
||||
EndPoint = table.Column<string>(type: "longtext", nullable: false),
|
||||
Length = table.Column<decimal>(type: "decimal(18,2)", 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_Routes", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SaleRoutes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", 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_SaleRoutes", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Stores",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
OwnerName = table.Column<string>(type: "longtext", nullable: false),
|
||||
StoreName = table.Column<string>(type: "longtext", nullable: false),
|
||||
StoreAddress = table.Column<string>(type: "longtext", nullable: false),
|
||||
Latitude = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
|
||||
Longitude = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
|
||||
OneTimeAmount = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
|
||||
CreditAmount = table.Column<decimal>(type: "decimal(18,2)", 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_Stores", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Vehicles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
RegNumber = table.Column<string>(type: "longtext", nullable: false),
|
||||
NumberPlate = table.Column<string>(type: "longtext", nullable: false),
|
||||
Type = table.Column<int>(type: "int", 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_Vehicles", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Orders",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
OrderDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
FK_StoreId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
TotalAmount = table.Column<decimal>(type: "decimal(18,2)", 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_Orders", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Orders_Stores_FK_StoreId",
|
||||
column: x => x.FK_StoreId,
|
||||
principalTable: "Stores",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DeliveryRuns",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_VehicleId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Meterstart = table.Column<int>(type: "int", nullable: false),
|
||||
Meterend = table.Column<int>(type: "int", nullable: false),
|
||||
FK_RouteId = table.Column<Guid>(type: "char(36)", 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_DeliveryRuns", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_DeliveryRuns_Routes_FK_RouteId",
|
||||
column: x => x.FK_RouteId,
|
||||
principalTable: "Routes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_DeliveryRuns_Vehicles_FK_VehicleId",
|
||||
column: x => x.FK_VehicleId,
|
||||
principalTable: "Vehicles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Warehouses",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false),
|
||||
Location = table.Column<string>(type: "longtext", nullable: false),
|
||||
Type = table.Column<int>(type: "int", nullable: false),
|
||||
VehicleId = table.Column<Guid>(type: "char(36)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Warehouses", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Warehouses_Vehicles_VehicleId",
|
||||
column: x => x.VehicleId,
|
||||
principalTable: "Vehicles",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OrderItems",
|
||||
columns: table => new
|
||||
{
|
||||
FK_OrderId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_ItemId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Quantity = table.Column<int>(type: "int", nullable: false),
|
||||
Id = table.Column<Guid>(type: "char(36)", 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_OrderItems", x => new { x.FK_OrderId, x.FK_ItemId });
|
||||
table.ForeignKey(
|
||||
name: "FK_OrderItems_Items_FK_ItemId",
|
||||
column: x => x.FK_ItemId,
|
||||
principalTable: "Items",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_OrderItems_Orders_FK_OrderId",
|
||||
column: x => x.FK_OrderId,
|
||||
principalTable: "Orders",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DeliveryRuns_FK_RouteId",
|
||||
table: "DeliveryRuns",
|
||||
column: "FK_RouteId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DeliveryRuns_FK_VehicleId",
|
||||
table: "DeliveryRuns",
|
||||
column: "FK_VehicleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OrderItems_FK_ItemId",
|
||||
table: "OrderItems",
|
||||
column: "FK_ItemId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Orders_FK_StoreId",
|
||||
table: "Orders",
|
||||
column: "FK_StoreId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Warehouses_VehicleId",
|
||||
table: "Warehouses",
|
||||
column: "VehicleId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "DeliveryRuns");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "OrderItems");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Regions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SaleRoutes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Warehouses");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Routes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Items");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Orders");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Vehicles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Stores");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,456 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
|
||||
|
||||
namespace Distribution.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddUserManagement : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "FK_RouteId",
|
||||
table: "Stores",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "FK_RegionId",
|
||||
table: "Routes",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Permissions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Code = table.Column<string>(type: "longtext", nullable: false),
|
||||
Description = table.Column<string>(type: "longtext", 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_Permissions", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Roles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false),
|
||||
Level = table.Column<int>(type: "int", 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_Roles", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RolePermissions",
|
||||
columns: table => new
|
||||
{
|
||||
FK_RoleId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_PermissionId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Id = table.Column<Guid>(type: "char(36)", 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_RolePermissions", x => new { x.FK_RoleId, x.FK_PermissionId });
|
||||
table.ForeignKey(
|
||||
name: "FK_RolePermissions_Permissions_FK_PermissionId",
|
||||
column: x => x.FK_PermissionId,
|
||||
principalTable: "Permissions",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_RolePermissions_Roles_FK_RoleId",
|
||||
column: x => x.FK_RoleId,
|
||||
principalTable: "Roles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Users",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Username = table.Column<string>(type: "longtext", nullable: false),
|
||||
PasswordHash = table.Column<string>(type: "longtext", nullable: false),
|
||||
FullName = table.Column<string>(type: "longtext", nullable: false),
|
||||
FK_RoleId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_ReportsToUserId = table.Column<Guid>(type: "char(36)", nullable: true),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Users", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Users_Roles_FK_RoleId",
|
||||
column: x => x.FK_RoleId,
|
||||
principalTable: "Roles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Users_Users_FK_ReportsToUserId",
|
||||
column: x => x.FK_ReportsToUserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserRegionScopes",
|
||||
columns: table => new
|
||||
{
|
||||
FK_UserId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_RegionId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Id = table.Column<Guid>(type: "char(36)", 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_UserRegionScopes", x => new { x.FK_UserId, x.FK_RegionId });
|
||||
table.ForeignKey(
|
||||
name: "FK_UserRegionScopes_Regions_FK_RegionId",
|
||||
column: x => x.FK_RegionId,
|
||||
principalTable: "Regions",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserRegionScopes_Users_FK_UserId",
|
||||
column: x => x.FK_UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserRouteScopes",
|
||||
columns: table => new
|
||||
{
|
||||
FK_UserId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_RouteId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Id = table.Column<Guid>(type: "char(36)", 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_UserRouteScopes", x => new { x.FK_UserId, x.FK_RouteId });
|
||||
table.ForeignKey(
|
||||
name: "FK_UserRouteScopes_Routes_FK_RouteId",
|
||||
column: x => x.FK_RouteId,
|
||||
principalTable: "Routes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserRouteScopes_Users_FK_UserId",
|
||||
column: x => x.FK_UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserStoreScopes",
|
||||
columns: table => new
|
||||
{
|
||||
FK_UserId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_StoreId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Id = table.Column<Guid>(type: "char(36)", 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_UserStoreScopes", x => new { x.FK_UserId, x.FK_StoreId });
|
||||
table.ForeignKey(
|
||||
name: "FK_UserStoreScopes_Stores_FK_StoreId",
|
||||
column: x => x.FK_StoreId,
|
||||
principalTable: "Stores",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserStoreScopes_Users_FK_UserId",
|
||||
column: x => x.FK_UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "Permissions",
|
||||
columns: new[] { "Id", "Code", "CreatedAt", "Description", "IsActive" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("20000000-0000-0000-0000-000000000001"), "regions.view", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "View regions", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000002"), "regions.create", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Create regions", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000003"), "regions.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update regions", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000004"), "regions.delete", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Delete regions", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000005"), "routes.view", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "View routes", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000006"), "routes.create", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Create routes", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000007"), "routes.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update routes", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000008"), "routes.delete", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Delete routes", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000009"), "vehicles.view", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "View vehicles", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000010"), "vehicles.create", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Create vehicles", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000011"), "vehicles.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update vehicles", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000012"), "vehicles.delete", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Delete vehicles", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000013"), "stores.view", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "View stores", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000014"), "stores.create", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Create stores", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000015"), "stores.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update stores", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000016"), "stores.delete", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Delete stores", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000017"), "warehouses.view", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "View warehouses", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000018"), "warehouses.create", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Create warehouses", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000019"), "warehouses.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update warehouses", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000020"), "warehouses.delete", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Delete warehouses", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000021"), "orders.view", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "View orders", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000022"), "orders.create", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Create orders", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000023"), "orders.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update orders", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000024"), "orders.delete", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Delete orders", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000025"), "users.view", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "View users", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000026"), "users.create", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Create users", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000027"), "users.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update users", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000028"), "users.deactivate", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Deactivate users", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000029"), "users.assign_role", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Assign a role to a user", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000030"), "users.assign_scope", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Assign region/route/store scope to a user", true }
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "Roles",
|
||||
columns: new[] { "Id", "CreatedAt", "IsActive", "Level", "Name" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), true, 10, "SalesRep" },
|
||||
{ new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), true, 20, "Supervisor" },
|
||||
{ new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), true, 30, "AreaManager" },
|
||||
{ new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), true, 40, "AreaSupervisor" },
|
||||
{ new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), true, 50, "RegionalManager" },
|
||||
{ new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), true, 60, "RegionalAgency" }
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "RolePermissions",
|
||||
columns: new[] { "FK_PermissionId", "FK_RoleId", "CreatedAt", "Id", "IsActive" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("20000000-0000-0000-0000-000000000005"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("75737fa8-fed0-d97a-8c24-5716758a7222"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000013"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("0e0613fd-d62c-1e87-a5b6-8bd2c3697c2a"), true },
|
||||
{ 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-000000000023"), new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("dfe4bb14-1047-219c-cabe-a2b49b105d86"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000005"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7ee233b9-3758-e005-7bb2-5ad1edf36e21"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000013"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("eb4ffa50-b09a-f0a5-1994-3fc2ae3a35d0"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000014"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("5adb4d1a-eba8-16cb-8603-c3443d4ee8c8"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000015"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("23105bb1-ef1f-6e19-1a48-d62ccaec1db4"), 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-000000000023"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("e1f39dc4-6c33-45f4-8c23-3ad8ae5784a8"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000024"), new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("357c36de-9b6c-1c9a-4926-c18a9bccf0ca"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000005"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("e9c8355a-26a9-4107-504e-d61722f9e7cd"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000009"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7fef12f3-6875-14bb-9554-0c9d82f02a37"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000013"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("680b582c-dbc9-cfde-f54b-58c3ad5a57b6"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000014"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("0b7d47cf-efd9-9589-682b-78df22062e5a"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000015"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("4aaa0f3d-4360-5f11-41c1-5257662428af"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000017"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("38ea5531-a29d-a6bb-eebe-a18f3afe066d"), 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-000000000023"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("5cee999e-1b77-cb87-5148-6a793af7c44e"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000024"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("73e00ce7-c124-4677-4369-1eb9876852c0"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000005"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("c6d74049-3f46-88af-1067-c9ae133132f7"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000006"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("29d71000-6715-de8a-a3af-814938d50dfb"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000007"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("f58f4242-af91-0b8d-5be5-4b07b4367e8c"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000009"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("dafe8f7e-e527-5863-5cde-92599c4ba9eb"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000013"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("76f58da8-09f6-c4e2-01bd-ddd94809c1f5"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000014"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("c99adad6-94e8-0d5b-3d35-086f393207fb"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000015"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("b22d4f78-7a21-da50-5351-553bdf06c9c2"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000017"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("3cb22998-b618-c13f-48cd-9e7416f324fc"), 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-000000000023"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("db15215a-0a16-ef1f-5c82-6bb902a2b319"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000024"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7b4f3482-b8bd-d348-e4c1-ae6dc93a3771"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000001"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("3e3e6f06-72c8-42fa-f7e6-8feeaca36d60"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000005"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d95e7d5a-b12c-12b8-fee9-39576c905fed"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000006"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d97abb20-e53d-c970-d337-3764584874fa"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000007"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("a63446ad-14a9-6239-8791-0a1f86813903"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000008"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7f9502a2-feb4-f0ef-cb71-a62d00570fd0"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000009"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d1f4316a-72a0-66af-2a8a-1fdbdb4f8c3a"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000010"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("30e94e9b-c70c-2df3-0813-e99ce4511838"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000011"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("94f2f2ec-94b7-b768-76a4-9ee4256d95c1"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000012"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7201efa2-f829-8035-6607-174214f8fdba"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000013"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("fcc6af61-cc43-066c-5634-2ddc24a8460d"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000014"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("2f994b6b-b055-28c2-2fb1-99a0076a0e3f"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000015"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("55e84a29-428d-bf95-d589-793ecd8bac6e"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000016"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("43ec940a-44d2-9c47-a37d-049f2cfb2615"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000017"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("ee175c87-23bd-5529-ed18-6ce46985c6ed"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000018"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("2ae2eba4-4427-ab1e-cf03-e59a3925ef89"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000019"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("c88131d2-51b2-2bac-ad15-c7c130eb26f8"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000020"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("3a2ccc28-7416-388d-17f2-424d0520049f"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("08de9913-8cfc-4ab4-2cb9-2bc9217fbb6e"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("f3c8f315-3b2f-f923-e3cd-f3e575010138"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000023"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("4d682c93-d6df-4214-436d-85f76a3ade93"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000024"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("4b2c3b3b-c27d-410c-c1fc-7e43e280242f"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("1d227ae7-0eb9-c742-41df-3472718cb077"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000001"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("f64e20e2-f9ca-7ea5-42f4-c1256b0c0798"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000002"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7b6765bc-1510-cfc6-55ae-ac689caf0dcc"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000003"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d9e06d2d-82d6-84e8-e9ba-5406e9b4122d"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000004"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("b53e01bb-4e54-3270-87b1-0d54f947e09b"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000005"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("111b7d3c-3640-66e6-0757-b9fb67572943"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000006"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7ee06ff0-8557-b5bd-02dc-c4ff99e76348"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000007"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d20bcba0-a5af-de47-919d-a8645a828d27"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000008"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("b3ef35de-afc2-d80a-115f-77ba954f9586"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000009"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d1b7e0a2-149f-b56b-8c63-bb8d10bfcc1e"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000010"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("51e06fd0-cd20-ceeb-04cc-7dc79388c4a1"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000011"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("25639115-7083-1324-c3bd-3ad90fcfa1a0"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000012"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("51011cb7-5753-14ad-280c-86a6bd33124f"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000013"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("51ce3fad-cdbc-cfad-6cf0-52b47ec3f200"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000014"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("4a080973-c23f-3d1b-9883-6b7e06025a77"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000015"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("3f78910a-76ee-f34b-52d3-af79d7f3b724"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000016"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("812cbb8d-e268-aad3-373e-42b8720f0f45"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000017"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("046cd13e-77f1-78c7-fa52-d49ea7fb9855"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000018"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("96f24adf-386d-14d0-46fe-a22ceff2f79b"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000019"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("9b5f23fb-2396-3f43-1d3e-97551eb4248d"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000020"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("30397d69-3b96-56e7-0ca1-1e612dfb64f1"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000021"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("91260fa1-3754-ad7e-10d8-2a8fd9b208ff"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000022"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("8b993e65-b066-198a-385d-602660ed85ac"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000023"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("248d6092-c2e5-5f8f-5ef0-cd60dc94cbc8"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000024"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("5f6e3c68-27d2-e00f-d5c9-4ce9e2b9587f"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000025"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("96a4ac9e-cfea-6391-8020-75b2980bf2a3"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000026"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("6eb59953-807d-aa61-29e3-1699c0aebda9"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000027"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("1095440c-ce52-235b-b95f-6b28c5d1b3a8"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000028"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("3a56ab5c-f0c5-a37b-0795-de061597628f"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000029"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("104ebcfb-ca82-3f95-d75e-35a943618176"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000030"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("ace990cf-6654-5e68-3dc8-1e62347e0946"), true }
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Stores_FK_RouteId",
|
||||
table: "Stores",
|
||||
column: "FK_RouteId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Routes_FK_RegionId",
|
||||
table: "Routes",
|
||||
column: "FK_RegionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RolePermissions_FK_PermissionId",
|
||||
table: "RolePermissions",
|
||||
column: "FK_PermissionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserRegionScopes_FK_RegionId",
|
||||
table: "UserRegionScopes",
|
||||
column: "FK_RegionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserRouteScopes_FK_RouteId",
|
||||
table: "UserRouteScopes",
|
||||
column: "FK_RouteId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Users_FK_ReportsToUserId",
|
||||
table: "Users",
|
||||
column: "FK_ReportsToUserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Users_FK_RoleId",
|
||||
table: "Users",
|
||||
column: "FK_RoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserStoreScopes_FK_StoreId",
|
||||
table: "UserStoreScopes",
|
||||
column: "FK_StoreId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Routes_Regions_FK_RegionId",
|
||||
table: "Routes",
|
||||
column: "FK_RegionId",
|
||||
principalTable: "Regions",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Stores_Routes_FK_RouteId",
|
||||
table: "Stores",
|
||||
column: "FK_RouteId",
|
||||
principalTable: "Routes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Routes_Regions_FK_RegionId",
|
||||
table: "Routes");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Stores_Routes_FK_RouteId",
|
||||
table: "Stores");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "RolePermissions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserRegionScopes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserRouteScopes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserStoreScopes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Permissions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Users");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Roles");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Stores_FK_RouteId",
|
||||
table: "Stores");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Routes_FK_RegionId",
|
||||
table: "Routes");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FK_RouteId",
|
||||
table: "Stores");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FK_RegionId",
|
||||
table: "Routes");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,621 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
|
||||
|
||||
namespace Distribution.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddItemCatalog : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<decimal>(
|
||||
name: "UnitPrice",
|
||||
table: "OrderItems",
|
||||
type: "decimal(18,2)",
|
||||
nullable: false,
|
||||
defaultValue: 0m);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Description",
|
||||
table: "Items",
|
||||
type: "longtext",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "ExternalErpItemId",
|
||||
table: "Items",
|
||||
type: "int",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "FK_BaseUomId",
|
||||
table: "Items",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "FK_BrandId",
|
||||
table: "Items",
|
||||
type: "char(36)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "FK_CategoryId",
|
||||
table: "Items",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "FK_SubCategoryId",
|
||||
table: "Items",
|
||||
type: "char(36)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "LastSyncedAt",
|
||||
table: "Items",
|
||||
type: "datetime(6)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Name",
|
||||
table: "Items",
|
||||
type: "longtext",
|
||||
nullable: false);
|
||||
|
||||
migrationBuilder.AddColumn<decimal>(
|
||||
name: "SalePrice",
|
||||
table: "Items",
|
||||
type: "decimal(18,2)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Sku",
|
||||
table: "Items",
|
||||
type: "longtext",
|
||||
nullable: false);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "SyncSource",
|
||||
table: "Items",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Brands",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false),
|
||||
ExternalErpId = table.Column<int>(type: "int", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Brands", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Categories",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false),
|
||||
ExternalErpId = table.Column<int>(type: "int", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Categories", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Uoms",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false),
|
||||
ExternalErpId = table.Column<int>(type: "int", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Uoms", x => x.Id);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SubCategories",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false),
|
||||
FK_CategoryId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
ExternalErpId = table.Column<int>(type: "int", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SubCategories", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_SubCategories_Categories_FK_CategoryId",
|
||||
column: x => x.FK_CategoryId,
|
||||
principalTable: "Categories",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UomConversions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_ItemId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_FromUomId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
FK_ToUomId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Factor = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UomConversions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_UomConversions_Items_FK_ItemId",
|
||||
column: x => x.FK_ItemId,
|
||||
principalTable: "Items",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_UomConversions_Uoms_FK_FromUomId",
|
||||
column: x => x.FK_FromUomId,
|
||||
principalTable: "Uoms",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_UomConversions_Uoms_FK_ToUomId",
|
||||
column: x => x.FK_ToUomId,
|
||||
principalTable: "Uoms",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "Permissions",
|
||||
columns: new[] { "Id", "Code", "CreatedAt", "Description", "IsActive" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("20000000-0000-0000-0000-000000000031"), "items.view", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "View items, brands and UOMs", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000032"), "items.create", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Create items, brands and UOMs", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000033"), "items.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update items, brands and UOMs", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000034"), "items.delete", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Delete items, brands and UOMs", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000035"), "categories.view", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "View categories", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000036"), "categories.create", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Create categories and subcategories", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000037"), "categories.update", new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), "Update categories and subcategories", true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000038"), "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-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-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-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-000000000033"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d49f086e-30f0-6ce8-ae96-4395d5e04472"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000035"), new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("1e7fe1b6-5150-4b99-38ed-088d9495cfd8"), 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-000000000033"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("7c392a13-1a57-0d85-dffa-2fb9e892abe9"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000034"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("97708eed-6ce4-7710-abde-01d00c0c879b"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000035"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("9afe507e-191e-bdee-0c5a-cfbcbf1efb3e"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000036"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("9c278616-4289-96fb-944d-b8f1495ccb00"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000037"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d1dcef02-d4c3-caba-372f-dab82011e9c1"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000038"), new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("9cc36229-dfba-49b9-1d6e-8929546e894d"), 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 },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000033"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("0efa7259-aadb-0019-4be5-38d3f8f4cd54"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000034"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("9e60e7d7-8bd6-c1c7-4bf1-4de2c9dcb91c"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000035"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("5df82318-bc01-1947-09ef-60508e02b257"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000036"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("34f478f4-6c96-4b31-b68a-28c7942c0789"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000037"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("69598e0e-b7ad-477b-c587-7abf6189162d"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000038"), new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("b36fb2d4-43df-44f8-ff51-de6d88644c94"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000031"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("bd209f90-6671-8ea0-eb20-aa151faec6a0"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000032"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("4cc32686-8391-0214-5747-db14f53c5b6f"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000033"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("26c6d86a-835d-6f0d-3730-66a46ea26b11"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000034"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("e8039d9c-a286-fb74-5abb-b5c6c67f243a"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000035"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("d9e038cb-bcff-cce1-5d34-b4e63a9ce694"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000036"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("343e71f0-da6b-2489-5571-f8d7c6378ee7"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000037"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("ac894328-a935-8e6e-8427-6c0f36ac75da"), true },
|
||||
{ new Guid("20000000-0000-0000-0000-000000000038"), new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 8, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new Guid("1d6273d4-db6a-d70e-4b5f-98cb634d668a"), true }
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Items_FK_BaseUomId",
|
||||
table: "Items",
|
||||
column: "FK_BaseUomId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Items_FK_BrandId",
|
||||
table: "Items",
|
||||
column: "FK_BrandId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Items_FK_CategoryId",
|
||||
table: "Items",
|
||||
column: "FK_CategoryId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Items_FK_SubCategoryId",
|
||||
table: "Items",
|
||||
column: "FK_SubCategoryId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SubCategories_FK_CategoryId",
|
||||
table: "SubCategories",
|
||||
column: "FK_CategoryId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UomConversions_FK_FromUomId",
|
||||
table: "UomConversions",
|
||||
column: "FK_FromUomId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UomConversions_FK_ItemId",
|
||||
table: "UomConversions",
|
||||
column: "FK_ItemId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UomConversions_FK_ToUomId",
|
||||
table: "UomConversions",
|
||||
column: "FK_ToUomId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Items_Brands_FK_BrandId",
|
||||
table: "Items",
|
||||
column: "FK_BrandId",
|
||||
principalTable: "Brands",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Items_Categories_FK_CategoryId",
|
||||
table: "Items",
|
||||
column: "FK_CategoryId",
|
||||
principalTable: "Categories",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Items_SubCategories_FK_SubCategoryId",
|
||||
table: "Items",
|
||||
column: "FK_SubCategoryId",
|
||||
principalTable: "SubCategories",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Items_Uoms_FK_BaseUomId",
|
||||
table: "Items",
|
||||
column: "FK_BaseUomId",
|
||||
principalTable: "Uoms",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Items_Brands_FK_BrandId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Items_Categories_FK_CategoryId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Items_SubCategories_FK_SubCategoryId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Items_Uoms_FK_BaseUomId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Brands");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SubCategories");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UomConversions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Categories");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Uoms");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Items_FK_BaseUomId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Items_FK_BrandId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Items_FK_CategoryId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Items_FK_SubCategoryId",
|
||||
table: "Items");
|
||||
|
||||
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-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-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-000000000033"), 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-000000000035"), 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-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-000000000033"), 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-000000000034"), 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-000000000035"), 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-000000000036"), 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-000000000037"), 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-000000000038"), 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.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-000000000005") });
|
||||
|
||||
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-000000000005") });
|
||||
|
||||
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-000000000005") });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "RolePermissions",
|
||||
keyColumns: new[] { "FK_PermissionId", "FK_RoleId" },
|
||||
keyValues: new object[] { new Guid("20000000-0000-0000-0000-000000000036"), 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-000000000037"), 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-000000000038"), 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-000000000031"), 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-000000000032"), 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-000000000033"), 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-000000000034"), 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-000000000035"), 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-000000000036"), 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-000000000037"), 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-000000000038"), new Guid("10000000-0000-0000-0000-000000000006") });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "Permissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("20000000-0000-0000-0000-000000000031"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "Permissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("20000000-0000-0000-0000-000000000032"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "Permissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("20000000-0000-0000-0000-000000000033"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "Permissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("20000000-0000-0000-0000-000000000034"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "Permissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("20000000-0000-0000-0000-000000000035"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "Permissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("20000000-0000-0000-0000-000000000036"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "Permissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("20000000-0000-0000-0000-000000000037"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "Permissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("20000000-0000-0000-0000-000000000038"));
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "UnitPrice",
|
||||
table: "OrderItems");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Description",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ExternalErpItemId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FK_BaseUomId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FK_BrandId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FK_CategoryId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FK_SubCategoryId",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LastSyncedAt",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Name",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "SalePrice",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Sku",
|
||||
table: "Items");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "SyncSource",
|
||||
table: "Items");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Distribution.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class item_catalog : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "Factor",
|
||||
table: "UomConversions",
|
||||
type: "decimal(65,30)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(18,2)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "OneTimeAmount",
|
||||
table: "Stores",
|
||||
type: "decimal(65,30)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(18,2)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "Longitude",
|
||||
table: "Stores",
|
||||
type: "decimal(65,30)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(18,2)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "Latitude",
|
||||
table: "Stores",
|
||||
type: "decimal(65,30)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(18,2)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "CreditAmount",
|
||||
table: "Stores",
|
||||
type: "decimal(65,30)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(18,2)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "Length",
|
||||
table: "Routes",
|
||||
type: "decimal(65,30)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(18,2)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "TotalAmount",
|
||||
table: "Orders",
|
||||
type: "decimal(65,30)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(18,2)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "UnitPrice",
|
||||
table: "OrderItems",
|
||||
type: "decimal(65,30)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(18,2)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "SalePrice",
|
||||
table: "Items",
|
||||
type: "decimal(65,30)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(18,2)",
|
||||
oldNullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "Factor",
|
||||
table: "UomConversions",
|
||||
type: "decimal(18,2)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(65,30)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "OneTimeAmount",
|
||||
table: "Stores",
|
||||
type: "decimal(18,2)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(65,30)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "Longitude",
|
||||
table: "Stores",
|
||||
type: "decimal(18,2)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(65,30)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "Latitude",
|
||||
table: "Stores",
|
||||
type: "decimal(18,2)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(65,30)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "CreditAmount",
|
||||
table: "Stores",
|
||||
type: "decimal(18,2)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(65,30)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "Length",
|
||||
table: "Routes",
|
||||
type: "decimal(18,2)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(65,30)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "TotalAmount",
|
||||
table: "Orders",
|
||||
type: "decimal(18,2)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(65,30)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "UnitPrice",
|
||||
table: "OrderItems",
|
||||
type: "decimal(18,2)",
|
||||
nullable: false,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(65,30)");
|
||||
|
||||
migrationBuilder.AlterColumn<decimal>(
|
||||
name: "SalePrice",
|
||||
table: "Items",
|
||||
type: "decimal(18,2)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(decimal),
|
||||
oldType: "decimal(65,30)",
|
||||
oldNullable: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+102
-2
@@ -12,8 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
namespace Distribution.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDBContext))]
|
||||
[Migration("20260819074545_item_catalog")]
|
||||
partial class item_catalog
|
||||
[Migration("20260819163125_init")]
|
||||
partial class init
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
@@ -55,6 +55,9 @@ namespace Distribution.Migrations
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<bool>("AllowCustomerReturn")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
@@ -1682,6 +1685,81 @@ namespace Distribution.Migrations
|
||||
b.ToTable("SaleRoutes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.StockBalance", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("FK_ItemId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("LocationId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<int>("LocationType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<decimal>("Quantity")
|
||||
.HasColumnType("decimal(65,30)");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FK_ItemId", "LocationId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("StockBalances");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.StockMovement", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<Guid>("CreatedBy")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("FK_ItemId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid?>("FromLocationId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<int?>("FromLocationType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<decimal>("Quantity")
|
||||
.HasColumnType("decimal(65,30)");
|
||||
|
||||
b.Property<string>("ReasonCode")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid?>("ReferenceId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid?>("ToLocationId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<int?>("ToLocationType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FK_ItemId");
|
||||
|
||||
b.ToTable("StockMovements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Store", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -2095,6 +2173,28 @@ namespace Distribution.Migrations
|
||||
b.Navigation("Region");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.StockBalance", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Item", "Item")
|
||||
.WithMany()
|
||||
.HasForeignKey("FK_ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.StockMovement", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Item", "Item")
|
||||
.WithMany()
|
||||
.HasForeignKey("FK_ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Store", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Route", "Route")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,9 @@ namespace Distribution.Migrations
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<bool>("AllowCustomerReturn")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
@@ -1679,6 +1682,81 @@ namespace Distribution.Migrations
|
||||
b.ToTable("SaleRoutes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.StockBalance", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("FK_ItemId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("LocationId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<int>("LocationType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<decimal>("Quantity")
|
||||
.HasColumnType("decimal(65,30)");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FK_ItemId", "LocationId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("StockBalances");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.StockMovement", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<Guid>("CreatedBy")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("FK_ItemId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid?>("FromLocationId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<int?>("FromLocationType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<decimal>("Quantity")
|
||||
.HasColumnType("decimal(65,30)");
|
||||
|
||||
b.Property<string>("ReasonCode")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid?>("ReferenceId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid?>("ToLocationId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<int?>("ToLocationType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FK_ItemId");
|
||||
|
||||
b.ToTable("StockMovements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Store", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -2092,6 +2170,28 @@ namespace Distribution.Migrations
|
||||
b.Navigation("Region");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.StockBalance", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Item", "Item")
|
||||
.WithMany()
|
||||
.HasForeignKey("FK_ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.StockMovement", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Item", "Item")
|
||||
.WithMany()
|
||||
.HasForeignKey("FK_ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Distribution.Models.Store", b =>
|
||||
{
|
||||
b.HasOne("Distribution.Models.Route", "Route")
|
||||
|
||||
@@ -4,5 +4,6 @@ namespace Distribution.Models
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int? ExternalErpId { get; set; }
|
||||
public bool AllowCustomerReturn { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Distribution.Models
|
||||
{
|
||||
public enum LocationType { Warehouse, Vehicle }
|
||||
|
||||
public enum MovementType
|
||||
{
|
||||
Sale,
|
||||
CustomerReturn,
|
||||
Transfer,
|
||||
Damage,
|
||||
Adjustment
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Distribution.Models
|
||||
{
|
||||
public class StockBalance
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public Guid FK_ItemId { get; set; }
|
||||
[ForeignKey("FK_ItemId")]
|
||||
public Item Item { get; set; }
|
||||
|
||||
public Guid LocationId { get; set; }
|
||||
public LocationType LocationType { get; set; }
|
||||
|
||||
public decimal Quantity { get; set; }
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.Now;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Distribution.Models
|
||||
{
|
||||
public class StockMovement
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public Guid FK_ItemId { get; set; }
|
||||
[ForeignKey("FK_ItemId")]
|
||||
public Item Item { get; set; }
|
||||
|
||||
public Guid? FromLocationId { get; set; }
|
||||
public LocationType? FromLocationType { get; set; }
|
||||
|
||||
public Guid? ToLocationId { get; set; }
|
||||
public LocationType? ToLocationType { get; set; }
|
||||
|
||||
public decimal Quantity { get; set; }
|
||||
public MovementType Type { get; set; }
|
||||
|
||||
public string? ReasonCode { get; set; }
|
||||
public Guid? ReferenceId { get; set; }
|
||||
|
||||
public DateTime CreatedAt { get; set; } = DateTime.Now;
|
||||
public Guid CreatedBy { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ using Distribution.Features.Sync;
|
||||
using Distribution.Features.Uom;
|
||||
using Distribution.Features.User;
|
||||
using Distribution.Features.Vehicle;
|
||||
using Distribution.Features.Stock;
|
||||
using Distribution.Features.Warehouse;
|
||||
using Distribution.Infra.Authorization;
|
||||
using Distribution.Infra.UoW;
|
||||
@@ -44,6 +45,7 @@ builder.Services.AddScoped<ISubCategoryRepository, SubCategoryRepository>();
|
||||
builder.Services.AddScoped<IBrandRepository, BrandRepository>();
|
||||
builder.Services.AddScoped<IUomRepository, UomRepository>();
|
||||
builder.Services.AddScoped<IItemRepository, ItemRepository>();
|
||||
builder.Services.AddScoped<IStockRepository, StockRepository>();
|
||||
|
||||
builder.Services.AddScoped<RegionService>();
|
||||
builder.Services.AddScoped<RouteService>();
|
||||
@@ -59,6 +61,7 @@ builder.Services.AddScoped<BrandService>();
|
||||
builder.Services.AddScoped<UomService>();
|
||||
builder.Services.AddScoped<ItemService>();
|
||||
builder.Services.AddScoped<SyncService>();
|
||||
builder.Services.AddScoped<StockService>();
|
||||
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddScoped<ICurrentUserService, CurrentUserService>();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=187.127.102.190;Port=3306;Database=distribution_db;User=kalana;Password=kalana@hexdive"
|
||||
"DefaultConnection": "Server=187.127.102.190;Port=3306;Database=distribution;User=kalana;Password=kalana@hexdive"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
|
||||
@@ -1,62 +1,258 @@
|
||||
# 02 — Stock Ledger
|
||||
|
||||
**Status**: Not Started
|
||||
**Status**: Done
|
||||
**Depends On**: 01 — Item Catalog
|
||||
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
|
||||
Introduce stock tracking per location. Every warehouse and vehicle holds a quantity of each item.
|
||||
Stock is never edited directly — all changes happen through movement transactions.
|
||||
The current balance is always the materialized sum kept in sync with the transaction log.
|
||||
|
||||
---
|
||||
|
||||
## Background / Context
|
||||
|
||||
Two tables work together:
|
||||
|
||||
- **StockBalance** — one row per (ItemId, LocationId). Updated atomically on every movement. Used for fast reads and enforcing stock limits (e.g. driver can't sell more than loaded).
|
||||
- **StockMovement** — append-only transaction log. Source of truth. Used for audit, reconciliation at ride close (Step 07), and re-deriving balance if drift is ever suspected.
|
||||
|
||||
Both are updated in the same UoW commit. They must always agree.
|
||||
|
||||
**Location abstraction:** A single `LocationId` (+ `LocationType` enum) covers both warehouses and vehicles. Same query pattern regardless of location type.
|
||||
|
||||
---
|
||||
|
||||
## Data Model Changes
|
||||
|
||||
### Stock Balance (per location)
|
||||
### New Enum — LocationType
|
||||
|
||||
```csharp
|
||||
public enum LocationType { Warehouse, Vehicle }
|
||||
```
|
||||
|
||||
### New Enum — MovementType
|
||||
|
||||
### Stock Movement Transaction
|
||||
```csharp
|
||||
public enum MovementType
|
||||
{
|
||||
Sale,
|
||||
CustomerReturn,
|
||||
Transfer, // covers: warehouse→vehicle (load), vehicle→warehouse (driver return), warehouse→warehouse
|
||||
Damage,
|
||||
Adjustment
|
||||
}
|
||||
```
|
||||
|
||||
### New Entity — StockBalance
|
||||
|
||||
One row per (ItemId, LocationId). Updated on every movement.
|
||||
|
||||
### Location Abstraction (Warehouse vs Vehicle)
|
||||
| Column | Type | Notes |
|
||||
|---|---|---|
|
||||
| Id | Guid | PK |
|
||||
| FK_ItemId | Guid | FK → Item |
|
||||
| LocationId | Guid | FK → Warehouse or Vehicle |
|
||||
| LocationType | LocationType | Warehouse or Vehicle |
|
||||
| Quantity | decimal | Current balance. Never goes below 0 |
|
||||
| UpdatedAt | DateTime | Last movement time |
|
||||
|
||||
No `IsActive` / no soft delete — balance rows are permanent once created.
|
||||
Composite unique index on `(FK_ItemId, LocationId)`.
|
||||
|
||||
### New Entity — StockMovement
|
||||
|
||||
Append-only. Never updated or deleted.
|
||||
|
||||
| Column | Type | Notes |
|
||||
|---|---|---|
|
||||
| Id | Guid | PK |
|
||||
| FK_ItemId | Guid | FK → Item |
|
||||
| FromLocationId | Guid? | Null for Sale, Damage, Adjustment (single-location) |
|
||||
| FromLocationType | LocationType? | Null when FromLocationId is null |
|
||||
| ToLocationId | Guid? | Null for Sale, Damage (stock leaves system) |
|
||||
| ToLocationType | LocationType? | Null when ToLocationId is null |
|
||||
| Quantity | decimal | Always positive — direction implied by movement type |
|
||||
| Type | MovementType | |
|
||||
| ReasonCode | string? | Required for Adjustment and Damage |
|
||||
| ReferenceId | Guid? | Links to the originating business event (OrderId, RideId, etc.) |
|
||||
| CreatedAt | DateTime | |
|
||||
| CreatedBy | Guid | UserId of who triggered this |
|
||||
|
||||
---
|
||||
|
||||
## Category Configuration
|
||||
|
||||
`Category` gets one new flag to support configurable customer returns:
|
||||
|
||||
| Column | Type | Notes |
|
||||
|---|---|---|
|
||||
| AllowCustomerReturn | bool | Default false. If false, CustomerReturn movements are rejected for items in this category |
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
Base route: `/api/stock`
|
||||
|
||||
### Query
|
||||
|
||||
| Method | Route | Description |
|
||||
|---|---|---|
|
||||
| GET | `/balances` | Get all stock balances (paginated). Filter by `locationId`, `locationType`, `itemId` |
|
||||
| GET | `/balances/{itemId}/total` | Total stock of one item across all locations |
|
||||
| GET | `/movements` | Get movement history (paginated). Filter by `locationId`, `itemId`, `type`, `from`, `to` |
|
||||
|
||||
### Write
|
||||
|
||||
| Method | Route | Description |
|
||||
|---|---|---|
|
||||
| POST | `/transfer` | Move stock between two locations |
|
||||
| POST | `/damage` | Record damaged stock at a location |
|
||||
| POST | `/customer-return` | Record a customer return to a vehicle |
|
||||
| POST | `/adjustment` | Manual correction at a location (requires reason code) |
|
||||
|
||||
---
|
||||
|
||||
## Request / Response Shapes
|
||||
|
||||
### GET `/balances` response (paginated)
|
||||
|
||||
```json
|
||||
{
|
||||
"page": 1,
|
||||
"pageSize": 20,
|
||||
"total": 85,
|
||||
"items": [
|
||||
{
|
||||
"itemId": "...",
|
||||
"itemName": "Sprite 330ml",
|
||||
"locationId": "...",
|
||||
"locationType": "Warehouse",
|
||||
"quantity": 120,
|
||||
"updatedAt": "2026-08-19T10:00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### GET `/balances/{itemId}/total` response
|
||||
|
||||
```json
|
||||
{
|
||||
"itemId": "...",
|
||||
"itemName": "Sprite 330ml",
|
||||
"totalQuantity": 340,
|
||||
"breakdown": [
|
||||
{ "locationId": "...", "locationType": "Warehouse", "quantity": 200 },
|
||||
{ "locationId": "...", "locationType": "Vehicle", "quantity": 140 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### GET `/movements` response (paginated)
|
||||
|
||||
```json
|
||||
{
|
||||
"page": 1,
|
||||
"pageSize": 20,
|
||||
"total": 412,
|
||||
"items": [
|
||||
{
|
||||
"id": "...",
|
||||
"itemId": "...",
|
||||
"itemName": "Sprite 330ml",
|
||||
"fromLocationId": "...",
|
||||
"fromLocationType": "Warehouse",
|
||||
"toLocationId": "...",
|
||||
"toLocationType": "Vehicle",
|
||||
"quantity": 50,
|
||||
"type": "Transfer",
|
||||
"reasonCode": null,
|
||||
"referenceId": "...",
|
||||
"createdAt": "2026-08-19T08:00:00",
|
||||
"createdBy": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### POST `/transfer` request
|
||||
|
||||
```json
|
||||
{
|
||||
"itemId": "...",
|
||||
"fromLocationId": "...",
|
||||
"fromLocationType": "Warehouse",
|
||||
"toLocationId": "...",
|
||||
"toLocationType": "Vehicle",
|
||||
"quantity": 50,
|
||||
"referenceId": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### POST `/damage` request
|
||||
|
||||
```json
|
||||
{
|
||||
"itemId": "...",
|
||||
"locationId": "...",
|
||||
"locationType": "Warehouse",
|
||||
"quantity": 3,
|
||||
"reasonCode": "Broken during handling"
|
||||
}
|
||||
```
|
||||
|
||||
### POST `/customer-return` request
|
||||
|
||||
```json
|
||||
{
|
||||
"itemId": "...",
|
||||
"vehicleId": "...",
|
||||
"quantity": 2,
|
||||
"referenceId": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### POST `/adjustment` request
|
||||
|
||||
```json
|
||||
{
|
||||
"itemId": "...",
|
||||
"locationId": "...",
|
||||
"locationType": "Warehouse",
|
||||
"quantity": -2,
|
||||
"reasonCode": "Counting error corrected after audit"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Business Rules
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Fraud / Control Considerations
|
||||
|
||||
|
||||
1. `StockBalance.Quantity` must never go below 0. Any movement that would result in negative stock is rejected with a 400.
|
||||
2. `Adjustment` and `Damage` require a non-empty `ReasonCode`.
|
||||
3. `CustomerReturn` is rejected if `Category.AllowCustomerReturn = false` for the item's category.
|
||||
4. `Transfer` debits `FromLocation` and credits `ToLocation` atomically.
|
||||
5. Both `StockBalance` update and `StockMovement` insert happen in the same transaction — never one without the other.
|
||||
6. `StockMovement` rows are never updated or deleted. Wrong entries are corrected by a counter-movement.
|
||||
7. All list endpoints return paginated responses.
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
|
||||
None — all design decisions resolved in planning discussion.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
> Fill this section in during planning discussion before writing any code.
|
||||
**Feature folder:** `Features/Stock/`
|
||||
**Entities:** `StockBalance.cs`, `StockMovement.cs` in `Models/`
|
||||
**Migration:** Add after entities and DbContext are updated
|
||||
**Service layer:** One `StockService` handles all movement types. Each write method: begins transaction → validates stock → inserts movement → updates balance → commits.
|
||||
**Category change:** Add `AllowCustomerReturn` column to existing `Category` entity and migration.
|
||||
|
||||
@@ -36,7 +36,7 @@ They must be resolved before new feature steps begin because later steps depend
|
||||
|---|---|---|---|---|
|
||||
| 00 | Existing Gap Fixes | Done | — | [00_existing_gaps.md](./00_existing_gaps.md) |
|
||||
| 01 | Item Catalog | Done | 00 | [01_item_catalog.md](./01_item_catalog.md) |
|
||||
| 02 | Stock Ledger | Not Started | 01 | [02_stock_ledger.md](./02_stock_ledger.md) |
|
||||
| 02 | Stock Ledger | Done | 01 | [02_stock_ledger.md](./02_stock_ledger.md) |
|
||||
| 03 | Ride Lifecycle | Not Started | 02 | [03_ride_lifecycle.md](./03_ride_lifecycle.md) |
|
||||
| 04 | Loading Event | Not Started | 03 | [04_loading_event.md](./04_loading_event.md) |
|
||||
| 05 | Delivery Ride Execution | Not Started | 04 | [05_delivery_ride.md](./05_delivery_ride.md) |
|
||||
|
||||
Reference in New Issue
Block a user