using CMSMicroservice.Domain.Entities; using CMSMicroservice.Domain.Entities.DiscountShop; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace CMSMicroservice.Infrastructure.Persistence.Configurations; /// /// تنظیمات Entity Framework برای موجودی کالا /// public class InventoryItemConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { // ========== تنظیمات پایه ========== builder.HasQueryFilter(i => !i.IsDeleted); builder.Ignore(entity => entity.DomainEvents); builder.HasKey(entity => entity.Id); builder.Property(entity => entity.Id).UseIdentityColumn(); // ========== فیلدهای اصلی ========== builder.Property(e => e.ProductType) .IsRequired() .HasConversion(); builder.Property(e => e.Quantity) .IsRequired() .HasDefaultValue(0); builder.Property(e => e.ReservedQuantity) .IsRequired() .HasDefaultValue(0); // ========== تنظیمات انبار ========== builder.Property(e => e.LowStockThreshold) .IsRequired() .HasDefaultValue(10); builder.Property(e => e.ReorderPoint) .IsRequired() .HasDefaultValue(5); builder.Property(e => e.MaxStockLevel) .IsRequired() .HasDefaultValue(1000); // ========== تاریخ‌ها ========== builder.Property(e => e.LastRestockedAt) .IsRequired(false); builder.Property(e => e.LastSoldAt) .IsRequired(false); // ========== انبار ========== builder.Property(e => e.WarehouseId) .IsRequired() .HasDefaultValue(1); // ========== روابط ========== // رابطه با Product (اختیاری) builder.HasOne(e => e.Product) .WithMany() .HasForeignKey(e => e.ProductId) .IsRequired(false) .OnDelete(DeleteBehavior.Cascade); // رابطه با DiscountProduct (اختیاری) builder.HasOne(e => e.DiscountProduct) .WithMany() .HasForeignKey(e => e.DiscountProductId) .IsRequired(false) .OnDelete(DeleteBehavior.Cascade); // رابطه با Warehouse builder.HasOne(e => e.Warehouse) .WithMany(w => w.InventoryItems) .HasForeignKey(e => e.WarehouseId) .IsRequired() .OnDelete(DeleteBehavior.Restrict); // ========== Index ها ========== // Index روی ProductId برای جستجوی سریع محصولات معمولی builder.HasIndex(e => e.ProductId) .HasDatabaseName("IX_InventoryItems_ProductId"); // Index روی DiscountProductId برای جستجوی سریع محصولات تخفیفی builder.HasIndex(e => e.DiscountProductId) .HasDatabaseName("IX_InventoryItems_DiscountProductId"); // Index ترکیبی روی ProductType و Quantity برای گزارش‌گیری builder.HasIndex(e => new { e.ProductType, e.Quantity }) .HasDatabaseName("IX_InventoryItems_ProductType_Quantity"); // Index ساده روی WarehouseId برای انبار builder.HasIndex(e => e.WarehouseId) .HasDatabaseName("IX_InventoryItems_WarehouseId"); // ========== محدودیت‌ها ========== // محدودیت: یا ProductId یا DiscountProductId باید پر باشد (نه هر دو، نه هیچ‌کدام) builder.HasCheckConstraint("CK_InventoryItem_ProductReference", "(ProductId IS NOT NULL AND DiscountProductId IS NULL) OR (ProductId IS NULL AND DiscountProductId IS NOT NULL)"); // محدودیت: ProductType باید با نوع محصول مطابقت داشته باشد builder.HasCheckConstraint("CK_InventoryItem_ProductType_Match", "(ProductType = 1 AND ProductId IS NOT NULL) OR (ProductType = 2 AND DiscountProductId IS NOT NULL)"); // محدودیت: موجودی نمی‌تواند منفی باشد builder.HasCheckConstraint("CK_InventoryItem_Quantity_NonNegative", "Quantity >= 0"); // محدودیت: موجودی رزرو شده نمی‌تواند منفی باشد builder.HasCheckConstraint("CK_InventoryItem_ReservedQuantity_NonNegative", "ReservedQuantity >= 0"); // محدودیت: موجودی رزرو شده نمی‌تواند بیشتر از موجودی کل باشد builder.HasCheckConstraint("CK_InventoryItem_ReservedQuantity_LessOrEqualQuantity", "ReservedQuantity <= Quantity"); } }