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");
}
}