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