feat: Implement Inventory Management Commands and Queries
Build and Deploy / build (push) Successful in 1m46s

- 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.
This commit is contained in:
masoodafar-web
2026-01-03 07:37:32 +03:30
parent 0c63b3c83c
commit f6f943947c
26 changed files with 1285 additions and 0 deletions
@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>true</IsPackable>
<PackageId>Foursat.BackOffice.BFF.Inventory.Protobuf</PackageId>
<Version>0.0.1</Version>
<Authors>FourSat</Authors>
<Company>FourSat</Company>
<Product>Foursat.BackOffice.BFF.Inventory.Protobuf</Product>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.23.3" />
<PackageReference Include="Grpc.Core.Api" Version="2.54.0" />
<PackageReference Include="Grpc.Tools" Version="2.72.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.2.2" />
<PackageReference Include="Google.Api.CommonProtos" Version="2.10.0" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\inventory.proto" ProtoRoot="Protos\" GrpcServices="Both" AdditionalImportDirs="..\BackOffice.BFF.Common.Protobuf\Protos"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BackOffice.BFF.Common.Protobuf\BackOffice.BFF.Common.Protobuf.csproj" />
</ItemGroup>
<Target Name="PushToFourSat" AfterTargets="Pack">
<PropertyGroup>
<NugetPackagePath>$(PackageOutputPath)$(PackageId).$(Version).nupkg</NugetPackagePath>
<PushCommand>
dotnet nuget push **/*.nupkg --source https://git.afrino.co/api/packages/FourSat/nuget/index.json --api-key 061a5cb15517c6da39c16cfce8556c55ae104d0d --skip-duplicate
</PushCommand>
</PropertyGroup>
<Exec Command="$(PushCommand)" />
</Target>
</Project>
@@ -0,0 +1,241 @@
syntax = "proto3";
package inventory;
import "public_messages.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/timestamp.proto";
option csharp_namespace = "Foursat.BackOffice.BFF.Inventory.Protos";
// =============================================
// Service Definition
// =============================================
service InventoryBFFContract
{
// Warehouse Management
rpc GetAllWarehouses(GetAllWarehousesRequest) returns (GetAllWarehousesResponse);
rpc CreateWarehouse(CreateWarehouseRequest) returns (CreateWarehouseResponse);
// Inventory Items
rpc GetAllInventoryItems(GetAllInventoryItemsRequest) returns (GetAllInventoryItemsResponse);
rpc GetLowStockItems(GetLowStockItemsRequest) returns (GetLowStockItemsResponse);
rpc GetStockMovements(GetStockMovementsRequest) returns (GetStockMovementsResponse);
// Stock Operations
rpc AddStock(AddStockRequest) returns (AddStockResponse);
rpc AdjustStock(AdjustStockRequest) returns (AdjustStockResponse);
rpc RecordLoss(RecordLossRequest) returns (google.protobuf.Empty);
rpc UpdateInventorySettings(UpdateInventorySettingsRequest) returns (google.protobuf.Empty);
}
// =============================================
// Enums
// =============================================
enum ProductType {
PRODUCT_TYPE_UNSPECIFIED = 0;
REGULAR = 1;
DISCOUNT = 2;
}
enum StockMovementType {
STOCK_MOVEMENT_TYPE_UNSPECIFIED = 0;
INITIAL_STOCK = 1;
RESTOCK = 2;
RETURN = 3;
SALE = 4;
ADJUSTMENT_INCREASE = 5;
ADJUSTMENT_DECREASE = 6;
RESERVED = 7;
RELEASED = 8;
LOSS = 9;
DAMAGED = 10;
EXPIRED = 11;
TRANSFER_OUT = 12;
TRANSFER_IN = 13;
}
// =============================================
// Warehouse Messages
// =============================================
message GetAllWarehousesRequest {
google.protobuf.BoolValue active_only = 1;
}
message GetAllWarehousesResponse {
repeated WarehouseDto warehouses = 1;
}
message WarehouseDto {
int64 id = 1;
string name = 2;
string code = 3;
string address = 4;
bool is_default = 5;
bool is_active = 6;
google.protobuf.Timestamp created = 7;
}
message CreateWarehouseRequest {
string name = 1;
string code = 2;
string address = 3;
bool is_default = 4;
}
message CreateWarehouseResponse {
int64 id = 1;
}
// =============================================
// Inventory Item Messages
// =============================================
message GetAllInventoryItemsRequest {
int32 page_index = 1;
int32 page_size = 2;
google.protobuf.Int64Value warehouse_id = 3;
ProductType product_type = 4;
string search_term = 5;
}
message GetAllInventoryItemsResponse {
int32 total_count = 1;
messages.MetaData meta_data = 2;
repeated InventoryItemDto items = 3;
}
message InventoryItemDto {
int64 id = 1;
google.protobuf.Int64Value product_id = 2;
google.protobuf.Int64Value discount_product_id = 3;
ProductType product_type = 4;
string product_name = 5;
int32 quantity = 6;
int32 reserved_quantity = 7;
int32 available_quantity = 8;
int32 low_stock_threshold = 9;
int32 reorder_point = 10;
int32 max_stock_level = 11;
google.protobuf.Timestamp last_restocked_at = 12;
google.protobuf.Timestamp last_sold_at = 13;
int64 warehouse_id = 14;
string warehouse_name = 15;
bool is_low_stock = 16;
}
// =============================================
// Low Stock Messages
// =============================================
message GetLowStockItemsRequest {
int32 count = 1;
google.protobuf.Int64Value warehouse_id = 2;
ProductType product_type = 3;
}
message GetLowStockItemsResponse {
int32 total_count = 1;
repeated LowStockItemDto items = 2;
}
message LowStockItemDto {
int64 id = 1;
google.protobuf.Int64Value product_id = 2;
google.protobuf.Int64Value discount_product_id = 3;
ProductType product_type = 4;
string product_name = 5;
int32 quantity = 6;
int32 reserved_quantity = 7;
int32 available_quantity = 8;
int32 low_stock_threshold = 9;
int32 reorder_point = 10;
int64 warehouse_id = 11;
string warehouse_name = 12;
}
// =============================================
// Stock Movement Messages
// =============================================
message GetStockMovementsRequest {
int32 page_index = 1;
int32 page_size = 2;
google.protobuf.Int64Value inventory_item_id = 3;
google.protobuf.Int64Value product_id = 4;
ProductType product_type = 5;
StockMovementType movement_type = 6;
google.protobuf.Timestamp from_date = 7;
google.protobuf.Timestamp to_date = 8;
}
message GetStockMovementsResponse {
int32 total_count = 1;
messages.MetaData meta_data = 2;
repeated StockMovementDto movements = 3;
}
message StockMovementDto {
int64 id = 1;
int64 inventory_item_id = 2;
string product_name = 3;
StockMovementType movement_type = 4;
string movement_type_name = 5;
int32 quantity = 6;
int32 quantity_before = 7;
int32 quantity_after = 8;
google.protobuf.Int64Value order_id = 9;
google.protobuf.Int64Value discount_order_id = 10;
string reference_number = 11;
string note = 12;
google.protobuf.Int64Value performed_by_user_id = 13;
string performed_by_user_name = 14;
google.protobuf.Timestamp created_at = 15;
}
// =============================================
// Stock Operation Messages
// =============================================
message AddStockRequest {
int64 product_id = 1;
ProductType product_type = 2;
int32 quantity = 3;
string reference_number = 4;
string note = 5;
google.protobuf.Int64Value warehouse_id = 6;
}
message AddStockResponse {
bool success = 1;
int64 inventory_item_id = 2;
int32 new_quantity = 3;
string message = 4;
}
message AdjustStockRequest {
int64 product_id = 1;
ProductType product_type = 2;
int32 new_quantity = 3;
string note = 4;
}
message AdjustStockResponse {
bool success = 1;
int32 old_quantity = 2;
int32 new_quantity = 3;
int32 difference = 4;
string message = 5;
}
message RecordLossRequest {
int64 product_id = 1;
ProductType product_type = 2;
int32 quantity = 3;
string reason = 4;
string reference_number = 5;
}
message UpdateInventorySettingsRequest {
int64 inventory_item_id = 1;
int32 low_stock_threshold = 2;
int32 reorder_point = 3;
int32 max_stock_level = 4;
}