using CMSMicroservice.Domain.Entities; using CMSMicroservice.Protobuf.Protos.Inventory; using CMSMicroservice.Application.Features.Warehouses.Commands; using CMSMicroservice.Application.Features.Warehouses.Queries; using CMSMicroservice.Application.Features.InventoryItems.Commands; using CMSMicroservice.Application.Features.InventoryItems.Queries; using CMSMicroservice.Application.Features.StockMovements.Commands; using CMSMicroservice.Application.Features.StockMovements.Queries; using Google.Protobuf.WellKnownTypes; using ProtoProductType = CMSMicroservice.Protobuf.Protos.Inventory.ProductType; using DomainProductType = CMSMicroservice.Domain.Enums.ProductType; using ProtoStockMovementType = CMSMicroservice.Protobuf.Protos.Inventory.StockMovementType; using DomainStockMovementType = CMSMicroservice.Domain.Enums.StockMovementType; namespace CMSMicroservice.WebApi.Common.Mappings; /// /// Mapster profile برای Inventory Protobuf به CQRS و Entities به DTOs /// public class InventoryProfile : IRegister { void IRegister.Register(TypeAdapterConfig config) { // ============================================= // Protobuf Request به CQRS Query/Command Mappings // ============================================= // Warehouse Commands config.NewConfig() .MapWith(src => new CreateWarehouseCommand { Name = src.Name, Code = src.Code, Address = src.Address, IsDefault = src.IsDefault }); config.NewConfig() .MapWith(src => new UpdateWarehouseCommand { Id = src.Id, Name = src.Name, Code = src.Code, Address = src.Address, IsActive = src.IsActive }); config.NewConfig() .MapWith(src => new DeleteWarehouseCommand(src.Id)); config.NewConfig() .MapWith(src => new SetDefaultWarehouseCommand(src.Id)); // Warehouse Queries config.NewConfig() .MapWith(src => new GetWarehouseByIdQuery(src.Id)); config.NewConfig() .MapWith(src => new GetAllWarehousesQuery()); // Inventory Item Queries config.NewConfig() .MapWith(src => new GetInventoryItemByIdQuery(src.Id)); config.NewConfig() .MapWith(src => new GetInventoryItemByProductIdQuery(src.ProductId, null)); config.NewConfig() .MapWith(src => new GetInventoryItemByDiscountProductIdQuery(src.ProductId, null)); config.NewConfig() .MapWith(src => new SearchInventoryItemsQuery( null, // SearchTerm null, // ProductType null, // WarehouseId null, // MinQuantity null, // MaxQuantity 0, // Skip 50 // Take )); config.NewConfig() .MapWith(src => new GetLowStockItemsQuery(null, 1)); // Inventory Item Commands config.NewConfig() .MapWith(src => new UpdateInventoryItemCommand { Id = src.Id, LowStockThreshold = src.LowStockThreshold, ReorderPoint = src.ReorderPoint, MaxStockLevel = src.MaxStockLevel }); // Stock Operation Commands config.NewConfig() .MapWith(src => new IncreaseInventoryCommand { ProductId = src.ProductId, ProductType = (DomainProductType)src.ProductType, Quantity = src.Quantity, Note = src.Note, ReferenceNumber = src.ReferenceNumber, WarehouseId = src.WarehouseId?.Value ?? 1 }); config.NewConfig() .MapWith(src => new UpdateInventoryQuantityCommand { ProductId = src.ProductId, ProductType = (DomainProductType)src.ProductType, NewQuantity = src.NewQuantity, Note = src.Note, ReferenceNumber = src.ReferenceNumber, WarehouseId = src.WarehouseId?.Value ?? 1 }); config.NewConfig() .MapWith(src => new ReserveInventoryCommand { ProductId = src.ProductId, ProductType = (DomainProductType)src.ProductType, Quantity = src.Quantity, Note = src.Note, ReferenceNumber = src.ReferenceNumber, OrderId = src.OrderId?.Value, WarehouseId = src.WarehouseId?.Value ?? 1 }); config.NewConfig() .MapWith(src => new ReleaseReservedInventoryCommand { ProductId = src.ProductId, ProductType = (DomainProductType)src.ProductType, Quantity = src.Quantity, Note = src.Note, ReferenceNumber = src.ReferenceNumber, WarehouseId = src.WarehouseId?.Value ?? 1 }); config.NewConfig() .MapWith(src => new ReduceInventoryCommand { ProductId = src.ProductId, ProductType = (DomainProductType)src.ProductType, Quantity = src.Quantity, Note = src.Note, ReferenceNumber = src.ReferenceNumber, OrderId = src.OrderId?.Value, WarehouseId = src.WarehouseId?.Value ?? 1 }); config.NewConfig() .MapWith(src => new IncreaseInventoryCommand { ProductId = src.ProductId, ProductType = (DomainProductType)src.ProductType, Quantity = src.Quantity, Note = !string.IsNullOrEmpty(src.Note) ? src.Note : "Product return", ReferenceNumber = src.ReferenceNumber, OrderId = src.OrderId?.Value, WarehouseId = src.WarehouseId?.Value ?? 1 }); config.NewConfig() .MapWith(src => new CreateStockMovementCommand { ProductId = src.ProductId, ProductType = (DomainProductType)src.ProductType, MovementType = DomainStockMovementType.Loss, Quantity = src.Quantity, Note = !string.IsNullOrEmpty(src.Note) ? src.Note : "Stock loss/damage", ReferenceNumber = src.ReferenceNumber, WarehouseId = src.WarehouseId?.Value ?? 1 }); // Stock Movement Queries config.NewConfig() .MapWith(src => new SearchStockMovementsQuery { InventoryItemId = src.InventoryItemId?.Value, ProductId = src.ProductId?.Value, ProductType = src.ProductType != ProtoProductType.Unspecified ? (DomainProductType?)src.ProductType : null, MovementType = src.MovementType != ProtoStockMovementType.Unspecified ? (DomainStockMovementType?)src.MovementType : null, StartDate = src.StartDate?.ToDateTime(), EndDate = src.EndDate?.ToDateTime(), Skip = src.Skip, Take = src.Take > 0 ? src.Take : 50 }); config.NewConfig() .MapWith(src => new GetInventoryItemMovementHistoryQuery { InventoryItemId = src.InventoryItemId, Skip = (src.Page - 1) * src.PageSize, Take = src.PageSize > 0 ? src.PageSize : 50 }); // ============================================= // Entity به Protobuf DTO Mappings // ============================================= // Warehouse Entity به WarehouseDto config.NewConfig() .Map(dest => dest.Id, src => src.Id) .Map(dest => dest.Name, src => src.Name) .Map(dest => dest.Code, src => src.Code ?? string.Empty) .Map(dest => dest.Address, src => src.Address ?? string.Empty) .Map(dest => dest.IsDefault, src => src.IsDefault) .Map(dest => dest.IsActive, src => src.IsActive); // InventoryItem Entity به InventoryItemDto config.NewConfig() .Map(dest => dest.Id, src => src.Id) .Map(dest => dest.WarehouseId, src => src.WarehouseId) .Map(dest => dest.WarehouseName, src => src.Warehouse != null ? src.Warehouse.Name : string.Empty) .Map(dest => dest.ProductId, src => src.ProductId.HasValue ? new Int64Value { Value = src.ProductId.Value } : null) .Map(dest => dest.DiscountProductId, src => src.DiscountProductId.HasValue ? new Int64Value { Value = src.DiscountProductId.Value } : null) .Map(dest => dest.ProductType, src => (ProtoProductType)src.ProductType) .Map(dest => dest.Quantity, src => src.Quantity) .Map(dest => dest.ReservedQuantity, src => src.ReservedQuantity) .Map(dest => dest.AvailableQuantity, src => src.AvailableQuantity) .Map(dest => dest.LowStockThreshold, src => src.LowStockThreshold) .Map(dest => dest.ReorderPoint, src => src.ReorderPoint) .Map(dest => dest.MaxStockLevel, src => src.MaxStockLevel) .Map(dest => dest.LastRestockedAt, src => src.LastRestockedAt.HasValue ? Timestamp.FromDateTime(src.LastRestockedAt.Value.ToUniversalTime()) : null) .Map(dest => dest.LastSoldAt, src => src.LastSoldAt.HasValue ? Timestamp.FromDateTime(src.LastSoldAt.Value.ToUniversalTime()) : null) .Map(dest => dest.ProductTitle, src => src.Product != null ? src.Product.Title : (src.DiscountProduct != null ? src.DiscountProduct.Title : string.Empty)) .Map(dest => dest.ProductPrice, src => src.Product != null ? src.Product.Price : (src.DiscountProduct != null ? src.DiscountProduct.Price : 0)) .Map(dest => dest.Created, src => Timestamp.FromDateTime(src.Created.ToUniversalTime())); // StockMovement Entity به StockMovementDto config.NewConfig() .Map(dest => dest.Id, src => src.Id) .Map(dest => dest.InventoryItemId, src => src.InventoryItemId) .Map(dest => dest.MovementType, src => (ProtoStockMovementType)src.MovementType) .Map(dest => dest.Quantity, src => src.Quantity) .Map(dest => dest.QuantityBefore, src => src.QuantityBefore) .Map(dest => dest.QuantityAfter, src => src.QuantityAfter) .Map(dest => dest.Note, src => src.Note ?? string.Empty) .Map(dest => dest.ReferenceNumber, src => src.ReferenceNumber ?? string.Empty) .Map(dest => dest.OrderId, src => src.OrderId.HasValue ? new Int64Value { Value = src.OrderId.Value } : null) .Map(dest => dest.DiscountOrderId, src => src.DiscountOrderId.HasValue ? new Int64Value { Value = src.DiscountOrderId.Value } : null) .Map(dest => dest.PerformedByUserId, src => src.PerformedByUserId.HasValue ? new Int64Value { Value = src.PerformedByUserId.Value } : null) .Map(dest => dest.Created, src => Timestamp.FromDateTime(src.Created.ToUniversalTime())) .Map(dest => dest.ProductTitle, src => src.InventoryItem != null && src.InventoryItem.Product != null ? src.InventoryItem.Product.Title : (src.InventoryItem != null && src.InventoryItem.DiscountProduct != null ? src.InventoryItem.DiscountProduct.Title : string.Empty)); } }