2 Commits

Author SHA1 Message Date
masoodafar-web 1e3ba03c5c Merge branch 'kub-stage' into production
Build and Deploy to Production / build-and-deploy (push) Successful in 8m34s
2026-05-01 00:56:21 +03:30
masoodafar-web eeb837f32e feat: enhance inventory release logic in ExpirePendingOrdersService and InventoryService
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m27s
2026-05-01 00:56:00 +03:30
2 changed files with 49 additions and 3 deletions
@@ -79,10 +79,47 @@ public class ExpirePendingOrdersService : BackgroundService
// آزادسازی رزرو موجودی // آزادسازی رزرو موجودی
foreach (var detail in order.OrderDetails) foreach (var detail in order.OrderDetails)
{ {
var inventoryItem = await inventoryService.GetInventoryAsync(
detail.ProductId,
ProductType.DiscountProduct,
null,
cancellationToken);
if (inventoryItem == null)
{
_logger.LogWarning(
"Skipping inventory release for expired order #{OrderId}, ProductId={ProductId} because InventoryItem was not found",
order.Id,
detail.ProductId);
continue;
}
if (inventoryItem.ReservedQuantity <= 0)
{
_logger.LogInformation(
"Skipping inventory release for expired order #{OrderId}, ProductId={ProductId} because no reserved quantity remains",
order.Id,
detail.ProductId);
continue;
}
var releaseQuantity = Math.Min(detail.Count, inventoryItem.ReservedQuantity);
if (releaseQuantity < detail.Count)
{
_logger.LogWarning(
"Partial reservation release for expired order #{OrderId}, ProductId={ProductId}: requested={Requested}, reserved={Reserved}, releasing={Released}",
order.Id,
detail.ProductId,
detail.Count,
inventoryItem.ReservedQuantity,
releaseQuantity);
}
await inventoryService.ReleaseReservationAsync( await inventoryService.ReleaseReservationAsync(
detail.ProductId, detail.ProductId,
ProductType.DiscountProduct, ProductType.DiscountProduct,
detail.Count, releaseQuantity,
order.Id, order.Id,
cancellationToken); cancellationToken);
} }
@@ -249,14 +249,23 @@ public class InventoryService : IInventoryService
var quantityBefore = item.ReservedQuantity; var quantityBefore = item.ReservedQuantity;
item.ReservedQuantity = Math.Max(0, item.ReservedQuantity - quantity); item.ReservedQuantity = Math.Max(0, item.ReservedQuantity - quantity);
var releasedQuantity = quantityBefore - item.ReservedQuantity;
await _context.SaveChangesAsync(ct); await _context.SaveChangesAsync(ct);
if (releasedQuantity == 0)
{
_logger.LogInformation(
"No reserved units to release for {ProductType} Id={ProductId}, OrderId={OrderId}",
productType, productId, orderId);
return true;
}
// ثبت StockMovement // ثبت StockMovement
await LogMovementAsync( await LogMovementAsync(
item.Id, item.Id,
StockMovementType.Released, StockMovementType.Released,
quantity, -releasedQuantity,
quantityBefore, quantityBefore,
item.ReservedQuantity, item.ReservedQuantity,
orderId, orderId,
@@ -268,7 +277,7 @@ public class InventoryService : IInventoryService
_logger.LogInformation( _logger.LogInformation(
"Released {Quantity} reserved units for {ProductType} Id={ProductId}, OrderId={OrderId}", "Released {Quantity} reserved units for {ProductType} Id={ProductId}, OrderId={OrderId}",
quantity, productType, productId, orderId); releasedQuantity, productType, productId, orderId);
return true; return true;
} }