117 lines
4.7 KiB
C#
117 lines
4.7 KiB
C#
using CMSMicroservice.Domain.Entities;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
|
|
namespace CMSMicroservice.Infrastructure.Persistence.Configurations;
|
|
|
|
/// <summary>
|
|
/// تنظیمات Entity Framework برای حرکات انبار
|
|
/// </summary>
|
|
public class StockMovementConfiguration : IEntityTypeConfiguration<StockMovement>
|
|
{
|
|
public void Configure(EntityTypeBuilder<StockMovement> builder)
|
|
{
|
|
// ========== تنظیمات پایه ==========
|
|
builder.HasQueryFilter(s => !s.IsDeleted);
|
|
builder.Ignore(entity => entity.DomainEvents);
|
|
builder.HasKey(entity => entity.Id);
|
|
builder.Property(entity => entity.Id).UseIdentityColumn();
|
|
|
|
// ========== فیلدهای اصلی ==========
|
|
|
|
// نوع حرکت (enum به int)
|
|
builder.Property(e => e.MovementType)
|
|
.IsRequired()
|
|
.HasConversion<int>();
|
|
|
|
// مقدار تغییر (میتواند منفی باشد)
|
|
builder.Property(e => e.Quantity)
|
|
.IsRequired();
|
|
|
|
// موجودی قبل و بعد
|
|
builder.Property(e => e.QuantityBefore)
|
|
.IsRequired();
|
|
|
|
builder.Property(e => e.QuantityAfter)
|
|
.IsRequired();
|
|
|
|
// ========== فیلدهای اختیاری ==========
|
|
|
|
// شناسه سفارش معمولی
|
|
builder.Property(e => e.OrderId)
|
|
.IsRequired(false);
|
|
|
|
// شناسه سفارش تخفیفی
|
|
builder.Property(e => e.DiscountOrderId)
|
|
.IsRequired(false);
|
|
|
|
// شماره مرجع
|
|
builder.Property(e => e.ReferenceNumber)
|
|
.IsRequired(false)
|
|
.HasMaxLength(100);
|
|
|
|
// یادداشت
|
|
builder.Property(e => e.Note)
|
|
.IsRequired(false)
|
|
.HasMaxLength(500);
|
|
|
|
// کاربر انجامدهنده
|
|
builder.Property(e => e.PerformedByUserId)
|
|
.IsRequired(false);
|
|
|
|
// ========== روابط ==========
|
|
|
|
// رابطه با InventoryItem (اجباری)
|
|
builder.HasOne(e => e.InventoryItem)
|
|
.WithMany(i => i.StockMovements)
|
|
.HasForeignKey(e => e.InventoryItemId)
|
|
.IsRequired()
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
|
|
// ========== Index ها ==========
|
|
|
|
// Index روی InventoryItemId برای جستجوی حرکات یک آیتم
|
|
builder.HasIndex(e => e.InventoryItemId)
|
|
.HasDatabaseName("IX_StockMovements_InventoryItemId");
|
|
|
|
// Index روی MovementType برای فیلتر بر اساس نوع حرکت
|
|
builder.HasIndex(e => e.MovementType)
|
|
.HasDatabaseName("IX_StockMovements_MovementType");
|
|
|
|
// Index روی Created برای مرتبسازی زمانی
|
|
builder.HasIndex(e => e.Created)
|
|
.HasDatabaseName("IX_StockMovements_Created");
|
|
|
|
// Index ترکیبی برای گزارشگیری
|
|
builder.HasIndex(e => new { e.InventoryItemId, e.MovementType, e.Created })
|
|
.HasDatabaseName("IX_StockMovements_Item_Type_Date");
|
|
|
|
// Index روی OrderId برای ردیابی حرکات مرتبط با سفارش
|
|
builder.HasIndex(e => e.OrderId)
|
|
.HasDatabaseName("IX_StockMovements_OrderId")
|
|
.HasFilter("[OrderId] IS NOT NULL");
|
|
|
|
// Index روی DiscountOrderId برای ردیابی حرکات مرتبط با سفارش تخفیفی
|
|
builder.HasIndex(e => e.DiscountOrderId)
|
|
.HasDatabaseName("IX_StockMovements_DiscountOrderId")
|
|
.HasFilter("[DiscountOrderId] IS NOT NULL");
|
|
|
|
// Index روی ReferenceNumber برای جستجوی سریع با شماره مرجع
|
|
builder.HasIndex(e => e.ReferenceNumber)
|
|
.HasDatabaseName("IX_StockMovements_ReferenceNumber")
|
|
.HasFilter("[ReferenceNumber] IS NOT NULL");
|
|
|
|
// ========== محدودیتها ==========
|
|
|
|
// محدودیت: QuantityAfter باید برابر QuantityBefore + Quantity باشد
|
|
builder.HasCheckConstraint("CK_StockMovement_QuantityAfter_Calculation",
|
|
"QuantityAfter = QuantityBefore + Quantity");
|
|
|
|
// محدودیت: QuantityBefore و QuantityAfter نمیتوانند منفی باشند
|
|
builder.HasCheckConstraint("CK_StockMovement_QuantityBefore_NonNegative",
|
|
"QuantityBefore >= 0");
|
|
|
|
builder.HasCheckConstraint("CK_StockMovement_QuantityAfter_NonNegative",
|
|
"QuantityAfter >= 0");
|
|
}
|
|
} |