Files
BackOffice.BFF/src/BackOffice.BFF.WebApi/Common/Mappings/InventoryProfile.cs
T
masoodafar-web f6f943947c
Build and Deploy / build (push) Successful in 1m46s
feat: Implement Inventory Management Commands and Queries
- Added CreateWarehouseCommand and CreateWarehouseCommandHandler for warehouse creation.
- Introduced RecordLossCommand and RecordLossCommandHandler to handle stock loss recording.
- Created UpdateInventorySettingsCommand and its handler for updating inventory settings.
- Implemented GetAllInventoryItemsQuery and its handler to retrieve inventory items with pagination.
- Added GetAllWarehousesQuery and handler for fetching all warehouses.
- Developed GetLowStockItemsQuery and handler to get items below a specified stock threshold.
- Implemented GetStockMovementsQuery and handler for retrieving stock movement records.
- Created mappings for inventory-related requests and responses in InventoryProfile.
- Developed InventoryService to handle gRPC requests for inventory operations.
- Added Protobuf definitions for inventory management services and messages.
2026-01-03 07:37:32 +03:30

266 lines
12 KiB
C#

using BackOffice.BFF.Application.Common.Models;
using BackOffice.BFF.Application.InventoryCQ.Commands.AddStock;
using BackOffice.BFF.Application.InventoryCQ.Commands.AdjustStock;
using BackOffice.BFF.Application.InventoryCQ.Commands.CreateWarehouse;
using BackOffice.BFF.Application.InventoryCQ.Commands.RecordLoss;
using BackOffice.BFF.Application.InventoryCQ.Commands.UpdateInventorySettings;
using BackOffice.BFF.Application.InventoryCQ.Queries.GetAllInventoryItems;
using BackOffice.BFF.Application.InventoryCQ.Queries.GetAllWarehouses;
using BackOffice.BFF.Application.InventoryCQ.Queries.GetLowStockItems;
using BackOffice.BFF.Application.InventoryCQ.Queries.GetStockMovements;
using Google.Protobuf.WellKnownTypes;
using BffProtos = Foursat.BackOffice.BFF.Inventory.Protos;
namespace BackOffice.BFF.WebApi.Common.Mappings;
public class InventoryProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
// =============================================
// GetAllWarehouses
// =============================================
config.NewConfig<BffProtos.GetAllWarehousesRequest, GetAllWarehousesQuery>()
.MapWith(src => new GetAllWarehousesQuery
{
ActiveOnly = src.ActiveOnly != null ? src.ActiveOnly.Value : null
});
config.NewConfig<GetAllWarehousesResponseDto, BffProtos.GetAllWarehousesResponse>()
.MapWith(src => new BffProtos.GetAllWarehousesResponse
{
Warehouses = { src.Warehouses.Select(w => new BffProtos.WarehouseDto
{
Id = w.Id,
Name = w.Name ?? string.Empty,
Code = w.Code ?? string.Empty,
Address = w.Address ?? string.Empty,
IsDefault = w.IsDefault,
IsActive = w.IsActive
}) }
});
// =============================================
// CreateWarehouse
// =============================================
config.NewConfig<BffProtos.CreateWarehouseRequest, CreateWarehouseCommand>()
.MapWith(src => new CreateWarehouseCommand
{
Name = src.Name,
Code = src.Code,
Address = src.Address,
IsDefault = src.IsDefault,
IsActive = true
});
config.NewConfig<long, BffProtos.CreateWarehouseResponse>()
.MapWith(src => new BffProtos.CreateWarehouseResponse { Id = src });
// =============================================
// GetAllInventoryItems
// =============================================
config.NewConfig<BffProtos.GetAllInventoryItemsRequest, GetAllInventoryItemsQuery>()
.MapWith(src => new GetAllInventoryItemsQuery
{
PageIndex = src.PageIndex > 0 ? src.PageIndex : 1,
PageSize = src.PageSize > 0 ? src.PageSize : 20,
WarehouseId = src.WarehouseId,
ProductType = src.ProductType != BffProtos.ProductType.Unspecified
? (int)src.ProductType
: null,
SearchTerm = string.IsNullOrWhiteSpace(src.SearchTerm) ? null : src.SearchTerm
});
config.NewConfig<GetAllInventoryItemsResponseDto, BffProtos.GetAllInventoryItemsResponse>()
.MapWith(src => new BffProtos.GetAllInventoryItemsResponse
{
TotalCount = src.TotalCount,
MetaData = new BackOffice.BFF.Protobuf.Common.MetaData
{
CurrentPage = src.MetaData.CurrentPage,
PageSize = src.MetaData.PageSize,
TotalCount = src.MetaData.TotalCount,
TotalPage = src.MetaData.TotalPage
},
Items = { src.Items.Select(i => new BffProtos.InventoryItemDto
{
Id = i.Id,
ProductId = i.ProductId.HasValue ? i.ProductId.Value : null,
DiscountProductId = i.DiscountProductId.HasValue ? i.DiscountProductId.Value : null,
ProductType = (BffProtos.ProductType)i.ProductType,
ProductName = i.ProductName ?? string.Empty,
Quantity = i.Quantity,
ReservedQuantity = i.ReservedQuantity,
AvailableQuantity = i.AvailableQuantity,
LowStockThreshold = i.LowStockThreshold,
ReorderPoint = i.ReorderPoint,
MaxStockLevel = i.MaxStockLevel,
LastRestockedAt = i.LastRestockedAt.HasValue
? Timestamp.FromDateTime(DateTime.SpecifyKind(i.LastRestockedAt.Value, DateTimeKind.Utc))
: null,
LastSoldAt = i.LastSoldAt.HasValue
? Timestamp.FromDateTime(DateTime.SpecifyKind(i.LastSoldAt.Value, DateTimeKind.Utc))
: null,
WarehouseId = i.WarehouseId,
WarehouseName = i.WarehouseName ?? string.Empty,
IsLowStock = i.IsLowStock
}) }
});
// =============================================
// GetLowStockItems
// =============================================
config.NewConfig<BffProtos.GetLowStockItemsRequest, GetLowStockItemsQuery>()
.MapWith(src => new GetLowStockItemsQuery
{
Count = src.Count > 0 ? src.Count : 10,
WarehouseId = src.WarehouseId,
ProductType = src.ProductType != BffProtos.ProductType.Unspecified
? (int)src.ProductType
: null
});
config.NewConfig<GetLowStockItemsResponseDto, BffProtos.GetLowStockItemsResponse>()
.MapWith(src => new BffProtos.GetLowStockItemsResponse
{
TotalCount = src.TotalCount,
Items = { src.Items.Select(i => new BffProtos.LowStockItemDto
{
Id = i.Id,
ProductId = i.ProductId.HasValue ? i.ProductId.Value : null,
DiscountProductId = i.DiscountProductId.HasValue ? i.DiscountProductId.Value : null,
ProductType = (BffProtos.ProductType)i.ProductType,
ProductName = i.ProductName ?? string.Empty,
Quantity = i.Quantity,
ReservedQuantity = i.ReservedQuantity,
AvailableQuantity = i.AvailableQuantity,
LowStockThreshold = i.LowStockThreshold,
ReorderPoint = i.ReorderPoint,
WarehouseId = i.WarehouseId,
WarehouseName = i.WarehouseName ?? string.Empty
}) }
});
// =============================================
// GetStockMovements
// =============================================
config.NewConfig<BffProtos.GetStockMovementsRequest, GetStockMovementsQuery>()
.MapWith(src => new GetStockMovementsQuery
{
PageIndex = src.PageIndex > 0 ? src.PageIndex : 1,
PageSize = src.PageSize > 0 ? src.PageSize : 20,
InventoryItemId = src.InventoryItemId,
ProductId = src.ProductId,
ProductType = src.ProductType != BffProtos.ProductType.Unspecified
? (int)src.ProductType
: null,
MovementType = src.MovementType != BffProtos.StockMovementType.Unspecified
? (int)src.MovementType
: null,
FromDate = src.FromDate != null ? src.FromDate.ToDateTime() : null,
ToDate = src.ToDate != null ? src.ToDate.ToDateTime() : null
});
config.NewConfig<GetStockMovementsResponseDto, BffProtos.GetStockMovementsResponse>()
.MapWith(src => new BffProtos.GetStockMovementsResponse
{
TotalCount = src.TotalCount,
MetaData = new BackOffice.BFF.Protobuf.Common.MetaData
{
CurrentPage = src.MetaData.CurrentPage,
PageSize = src.MetaData.PageSize,
TotalCount = src.MetaData.TotalCount,
TotalPage = src.MetaData.TotalPage
},
Movements = { src.Movements.Select(m => new BffProtos.StockMovementDto
{
Id = m.Id,
InventoryItemId = m.InventoryItemId,
ProductName = m.ProductName ?? string.Empty,
MovementType = (BffProtos.StockMovementType)m.MovementType,
MovementTypeName = m.MovementTypeName ?? string.Empty,
Quantity = m.Quantity,
QuantityBefore = m.QuantityBefore,
QuantityAfter = m.QuantityAfter,
OrderId = m.OrderId.HasValue ? m.OrderId.Value : null,
DiscountOrderId = m.DiscountOrderId.HasValue ? m.DiscountOrderId.Value : null,
ReferenceNumber = m.ReferenceNumber ?? string.Empty,
Note = m.Note ?? string.Empty,
PerformedByUserId = m.PerformedByUserId.HasValue ? m.PerformedByUserId.Value : null,
PerformedByUserName = m.PerformedByUserName ?? string.Empty,
CreatedAt = Timestamp.FromDateTime(DateTime.SpecifyKind(m.CreatedAt, DateTimeKind.Utc))
}) }
});
// =============================================
// AddStock
// =============================================
config.NewConfig<BffProtos.AddStockRequest, AddStockCommand>()
.MapWith(src => new AddStockCommand
{
ProductId = src.ProductId,
ProductType = (int)src.ProductType,
Quantity = src.Quantity,
ReferenceNumber = src.ReferenceNumber,
Note = src.Note,
WarehouseId = src.WarehouseId
});
config.NewConfig<AddStockResponseDto, BffProtos.AddStockResponse>()
.MapWith(src => new BffProtos.AddStockResponse
{
Success = src.Success,
InventoryItemId = src.InventoryItemId,
NewQuantity = src.NewQuantity,
Message = src.Message ?? string.Empty
});
// =============================================
// AdjustStock
// =============================================
config.NewConfig<BffProtos.AdjustStockRequest, AdjustStockCommand>()
.MapWith(src => new AdjustStockCommand
{
ProductId = src.ProductId,
ProductType = (int)src.ProductType,
NewQuantity = src.NewQuantity,
Note = src.Note
});
config.NewConfig<AdjustStockResponseDto, BffProtos.AdjustStockResponse>()
.MapWith(src => new BffProtos.AdjustStockResponse
{
Success = src.Success,
OldQuantity = src.OldQuantity,
NewQuantity = src.NewQuantity,
Difference = src.Difference,
Message = src.Message ?? string.Empty
});
// =============================================
// RecordLoss
// =============================================
config.NewConfig<BffProtos.RecordLossRequest, RecordLossCommand>()
.MapWith(src => new RecordLossCommand
{
ProductId = src.ProductId,
ProductType = (int)src.ProductType,
Quantity = src.Quantity,
LossType = 40, // Loss type
Note = src.Reason
});
// =============================================
// UpdateInventorySettings
// =============================================
config.NewConfig<BffProtos.UpdateInventorySettingsRequest, UpdateInventorySettingsCommand>()
.MapWith(src => new UpdateInventorySettingsCommand
{
InventoryItemId = src.InventoryItemId,
LowStockThreshold = src.LowStockThreshold,
ReorderPoint = src.ReorderPoint,
MaxStockLevel = src.MaxStockLevel
});
}
}