Implement Inventory Management Service with CRUD operations for warehouses and inventory items, stock operations, and bulk processing capabilities.
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 1m48s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 1m48s
This commit is contained in:
@@ -61,6 +61,11 @@ public interface IApplicationDbContext
|
||||
DbSet<State> States { get; }
|
||||
DbSet<City> Cities { get; }
|
||||
|
||||
// ============= Inventory Management =============
|
||||
DbSet<Warehouse> Warehouses { get; }
|
||||
DbSet<InventoryItem> InventoryItems { get; }
|
||||
DbSet<StockMovement> StockMovements { get; }
|
||||
|
||||
/// <summary>
|
||||
/// دسترسی به DatabaseFacade برای اجرای raw SQL و Stored Procedures
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
using CMSMicroservice.Domain.Entities;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.Common.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// سرویس مدیریت موجودی - لایه بالاتر برای عملیات business
|
||||
/// این سرویس مسئول همگامسازی موجودی بین InventoryItem و Product.RemainingCount است
|
||||
/// </summary>
|
||||
public interface IInventoryService
|
||||
{
|
||||
#region Initialization
|
||||
|
||||
/// <summary>
|
||||
/// ایجاد رکورد موجودی برای محصول جدید
|
||||
/// این متد باید در CreateProductCommandHandler و CreateDiscountProductCommandHandler فراخوانی شود
|
||||
/// </summary>
|
||||
/// <param name="productId">شناسه محصول (Product.Id یا DiscountProduct.Id)</param>
|
||||
/// <param name="productType">نوع محصول (RegularProduct یا DiscountProduct)</param>
|
||||
/// <param name="initialQuantity">موجودی اولیه</param>
|
||||
/// <param name="warehouseId">شناسه انبار (پیشفرض: انبار اصلی)</param>
|
||||
/// <param name="lowStockThreshold">آستانه هشدار کمموجودی</param>
|
||||
/// <param name="ct">CancellationToken</param>
|
||||
/// <returns>شناسه InventoryItem ایجاد شده</returns>
|
||||
Task<long> InitializeInventoryAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
int initialQuantity,
|
||||
long? warehouseId = null,
|
||||
int lowStockThreshold = 10,
|
||||
CancellationToken ct = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Query Operations
|
||||
|
||||
/// <summary>
|
||||
/// دریافت موجودی یک محصول
|
||||
/// </summary>
|
||||
Task<InventoryItem?> GetInventoryAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
long? warehouseId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت موجودی قابل فروش (Quantity - ReservedQuantity)
|
||||
/// </summary>
|
||||
Task<int> GetAvailableQuantityAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
long? warehouseId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// بررسی اینکه آیا موجودی کافی برای فروش وجود دارد
|
||||
/// </summary>
|
||||
Task<bool> CheckAvailabilityAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
int requiredQuantity,
|
||||
long? warehouseId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت لیست محصولات کمموجود
|
||||
/// </summary>
|
||||
Task<List<InventoryItem>> GetLowStockItemsAsync(
|
||||
ProductType? productType = null,
|
||||
long? warehouseId = null,
|
||||
int count = 50,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت تاریخچه حرکات موجودی
|
||||
/// </summary>
|
||||
Task<List<StockMovement>> GetStockMovementsAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
DateTime? fromDate = null,
|
||||
DateTime? toDate = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Order Flow Operations
|
||||
|
||||
/// <summary>
|
||||
/// رزرو موجودی برای سفارش pending
|
||||
/// این متد در PlaceOrderCommandHandler فراخوانی میشود
|
||||
/// فقط ReservedQuantity را افزایش میدهد، Quantity تغییر نمیکند
|
||||
/// </summary>
|
||||
/// <param name="productId">شناسه محصول</param>
|
||||
/// <param name="productType">نوع محصول</param>
|
||||
/// <param name="quantity">تعداد رزرو</param>
|
||||
/// <param name="orderId">شناسه سفارش (Order.Id یا DiscountOrder.Id)</param>
|
||||
/// <param name="ct">CancellationToken</param>
|
||||
/// <returns>true اگر رزرو موفق بود</returns>
|
||||
Task<bool> ReserveStockAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
int quantity,
|
||||
long? orderId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// آزادسازی رزرو (لغو سفارش یا timeout)
|
||||
/// این متد در CancelOrderCommandHandler فراخوانی میشود
|
||||
/// </summary>
|
||||
Task<bool> ReleaseReservationAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
int quantity,
|
||||
long? orderId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// تایید فروش - کسر واقعی موجودی
|
||||
/// این متد در CompleteOrderPaymentCommandHandler فراخوانی میشود
|
||||
/// ReservedQuantity کاهش مییابد، Quantity کاهش مییابد، Product.RemainingCount sync میشود
|
||||
/// </summary>
|
||||
Task<bool> ConfirmSaleAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
int quantity,
|
||||
long? orderId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Stock Management Operations
|
||||
|
||||
/// <summary>
|
||||
/// ورود کالا به انبار (Restock)
|
||||
/// </summary>
|
||||
/// <param name="productId">شناسه محصول</param>
|
||||
/// <param name="productType">نوع محصول</param>
|
||||
/// <param name="quantity">تعداد ورودی</param>
|
||||
/// <param name="referenceNumber">شماره مرجع (مثل شماره فاکتور خرید)</param>
|
||||
/// <param name="note">یادداشت</param>
|
||||
/// <param name="performedByUserId">شناسه کاربر انجامدهنده</param>
|
||||
/// <param name="ct">CancellationToken</param>
|
||||
Task<bool> AddStockAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
int quantity,
|
||||
string? referenceNumber = null,
|
||||
string? note = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// تعدیل موجودی (تنظیم به مقدار جدید)
|
||||
/// </summary>
|
||||
Task<bool> AdjustStockAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
int newQuantity,
|
||||
string? note = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// ثبت برگشت کالا از مشتری
|
||||
/// </summary>
|
||||
Task<bool> ProcessReturnAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
int quantity,
|
||||
long? orderId = null,
|
||||
string? note = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// ثبت ضایعات/مفقودی
|
||||
/// </summary>
|
||||
Task<bool> RecordLossAsync(
|
||||
long productId,
|
||||
ProductType productType,
|
||||
int quantity,
|
||||
StockMovementType lossType, // Damaged or Lost
|
||||
string? note = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bulk Operations
|
||||
|
||||
/// <summary>
|
||||
/// رزرو موجودی برای چند آیتم (یک سفارش با چند محصول)
|
||||
/// </summary>
|
||||
Task<bool> BulkReserveStockAsync(
|
||||
IEnumerable<(long ProductId, ProductType ProductType, int Quantity)> items,
|
||||
long? orderId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// آزادسازی رزرو برای چند آیتم
|
||||
/// </summary>
|
||||
Task<bool> BulkReleaseReservationAsync(
|
||||
IEnumerable<(long ProductId, ProductType ProductType, int Quantity)> items,
|
||||
long? orderId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// تایید فروش برای چند آیتم
|
||||
/// </summary>
|
||||
Task<bool> BulkConfirmSaleAsync(
|
||||
IEnumerable<(long ProductId, ProductType ProductType, int Quantity)> items,
|
||||
long? orderId = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
#endregion
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
using CMSMicroservice.Domain.Entities;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.Common.Interfaces.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Repository interface برای مدیریت موجودی محصولات
|
||||
/// </summary>
|
||||
public interface IInventoryItemRepository
|
||||
{
|
||||
#region Read Operations
|
||||
|
||||
/// <summary>
|
||||
/// دریافت آیتم موجودی بر اساس شناسه
|
||||
/// </summary>
|
||||
Task<InventoryItem?> GetByIdAsync(long id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت آیتم موجودی بر اساس محصول معمولی
|
||||
/// </summary>
|
||||
Task<InventoryItem?> GetByProductIdAsync(long productId, long warehouseId = 1, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت آیتم موجودی بر اساس محصول تخفیفی
|
||||
/// </summary>
|
||||
Task<InventoryItem?> GetByDiscountProductIdAsync(long discountProductId, long warehouseId = 1, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت تمام آیتمهای موجودی یک انبار
|
||||
/// </summary>
|
||||
Task<List<InventoryItem>> GetByWarehouseIdAsync(long warehouseId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت محصولات کمموجود
|
||||
/// </summary>
|
||||
Task<List<InventoryItem>> GetLowStockItemsAsync(ProductType? productType = null, long warehouseId = 1, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت محصولات با موجودی صفر
|
||||
/// </summary>
|
||||
Task<List<InventoryItem>> GetOutOfStockItemsAsync(ProductType? productType = null, long warehouseId = 1, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// جستجوی آیتمهای موجودی با فیلتر
|
||||
/// </summary>
|
||||
Task<List<InventoryItem>> SearchAsync(
|
||||
string? searchTerm = null,
|
||||
ProductType? productType = null,
|
||||
long? warehouseId = null,
|
||||
int? minQuantity = null,
|
||||
int? maxQuantity = null,
|
||||
int skip = 0,
|
||||
int take = 50,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// شمارش کل آیتمهای موجودی با فیلتر
|
||||
/// </summary>
|
||||
Task<int> CountAsync(
|
||||
string? searchTerm = null,
|
||||
ProductType? productType = null,
|
||||
long? warehouseId = null,
|
||||
int? minQuantity = null,
|
||||
int? maxQuantity = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Write Operations
|
||||
|
||||
/// <summary>
|
||||
/// افزودن آیتم موجودی جدید
|
||||
/// </summary>
|
||||
Task<InventoryItem> AddAsync(InventoryItem inventoryItem, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// بروزرسانی آیتم موجودی
|
||||
/// </summary>
|
||||
Task UpdateAsync(InventoryItem inventoryItem, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// حذف آیتم موجودی
|
||||
/// </summary>
|
||||
Task DeleteAsync(long id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// بروزرسانی موجودی (با ثبت حرکت)
|
||||
/// </summary>
|
||||
Task<bool> UpdateQuantityAsync(
|
||||
long inventoryItemId,
|
||||
int quantityChange,
|
||||
StockMovementType movementType,
|
||||
string? note = null,
|
||||
string? referenceNumber = null,
|
||||
long? orderId = null,
|
||||
long? discountOrderId = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// رزرو موجودی
|
||||
/// </summary>
|
||||
Task<bool> ReserveQuantityAsync(
|
||||
long inventoryItemId,
|
||||
int quantity,
|
||||
string? note = null,
|
||||
string? referenceNumber = null,
|
||||
long? orderId = null,
|
||||
long? discountOrderId = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// آزاد کردن موجودی رزرو شده
|
||||
/// </summary>
|
||||
Task<bool> ReleaseReservedQuantityAsync(
|
||||
long inventoryItemId,
|
||||
int quantity,
|
||||
string? note = null,
|
||||
string? referenceNumber = null,
|
||||
long? orderId = null,
|
||||
long? discountOrderId = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bulk Operations
|
||||
|
||||
/// <summary>
|
||||
/// بروزرسانی انبوه موجودی چندین محصول
|
||||
/// </summary>
|
||||
Task<bool> BulkUpdateQuantityAsync(
|
||||
List<(long InventoryItemId, int QuantityChange, string? Note)> updates,
|
||||
StockMovementType movementType,
|
||||
string? referenceNumber = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// رزرو انبوه موجودی چندین محصول
|
||||
/// </summary>
|
||||
Task<bool> BulkReserveQuantityAsync(
|
||||
List<(long InventoryItemId, int Quantity, string? Note)> reservations,
|
||||
string? referenceNumber = null,
|
||||
long? orderId = null,
|
||||
long? discountOrderId = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
#endregion
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
using CMSMicroservice.Domain.Entities;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.Common.Interfaces.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Repository interface برای مدیریت حرکات موجودی
|
||||
/// </summary>
|
||||
public interface IStockMovementRepository
|
||||
{
|
||||
#region Read Operations
|
||||
|
||||
/// <summary>
|
||||
/// دریافت حرکت موجودی بر اساس شناسه
|
||||
/// </summary>
|
||||
Task<StockMovement?> GetByIdAsync(long id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت تاریخچه حرکات یک آیتم موجودی
|
||||
/// </summary>
|
||||
Task<List<StockMovement>> GetByInventoryItemIdAsync(
|
||||
long inventoryItemId,
|
||||
StockMovementType? movementType = null,
|
||||
DateTime? fromDate = null,
|
||||
DateTime? toDate = null,
|
||||
int skip = 0,
|
||||
int take = 100,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت حرکات مربوط به یک سفارش
|
||||
/// </summary>
|
||||
Task<List<StockMovement>> GetByOrderIdAsync(long orderId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت حرکات مربوط به یک سفارش تخفیفی
|
||||
/// </summary>
|
||||
Task<List<StockMovement>> GetByDiscountOrderIdAsync(long discountOrderId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت حرکات بر اساس شماره مرجع
|
||||
/// </summary>
|
||||
Task<List<StockMovement>> GetByReferenceNumberAsync(string referenceNumber, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت حرکات بر اساس نوع حرکت
|
||||
/// </summary>
|
||||
Task<List<StockMovement>> GetByMovementTypeAsync(
|
||||
StockMovementType movementType,
|
||||
DateTime? fromDate = null,
|
||||
DateTime? toDate = null,
|
||||
int skip = 0,
|
||||
int take = 100,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت آخرین حرکات موجودی
|
||||
/// </summary>
|
||||
Task<List<StockMovement>> GetRecentMovementsAsync(
|
||||
int count = 50,
|
||||
StockMovementType? movementType = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// جستجوی حرکات موجودی با فیلتر پیشرفته
|
||||
/// </summary>
|
||||
Task<List<StockMovement>> SearchAsync(
|
||||
long? inventoryItemId = null,
|
||||
StockMovementType? movementType = null,
|
||||
DateTime? fromDate = null,
|
||||
DateTime? toDate = null,
|
||||
string? referenceNumber = null,
|
||||
long? orderId = null,
|
||||
long? discountOrderId = null,
|
||||
long? performedByUserId = null,
|
||||
int skip = 0,
|
||||
int take = 100,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// شمارش حرکات موجودی با فیلتر
|
||||
/// </summary>
|
||||
Task<int> CountAsync(
|
||||
long? inventoryItemId = null,
|
||||
StockMovementType? movementType = null,
|
||||
DateTime? fromDate = null,
|
||||
DateTime? toDate = null,
|
||||
string? referenceNumber = null,
|
||||
long? orderId = null,
|
||||
long? discountOrderId = null,
|
||||
long? performedByUserId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Write Operations
|
||||
|
||||
/// <summary>
|
||||
/// افزودن حرکت موجودی جدید
|
||||
/// </summary>
|
||||
Task<StockMovement> AddAsync(StockMovement stockMovement, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// حذف حرکت موجودی (نرمافزاری)
|
||||
/// </summary>
|
||||
Task DeleteAsync(long id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// افزودن انبوه حرکات موجودی
|
||||
/// </summary>
|
||||
Task<List<StockMovement>> BulkAddAsync(List<StockMovement> stockMovements, CancellationToken cancellationToken = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Analytics & Reports
|
||||
|
||||
/// <summary>
|
||||
/// گزارش خلاصه حرکات در بازه زمانی
|
||||
/// </summary>
|
||||
Task<Dictionary<StockMovementType, int>> GetMovementSummaryAsync(
|
||||
DateTime fromDate,
|
||||
DateTime toDate,
|
||||
long? inventoryItemId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// گزارش حجم ورود و خروج روزانه
|
||||
/// </summary>
|
||||
Task<List<(DateTime Date, int InboundQuantity, int OutboundQuantity)>> GetDailyMovementVolumeAsync(
|
||||
DateTime fromDate,
|
||||
DateTime toDate,
|
||||
long? inventoryItemId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// گزارش بیشترین حرکات محصولات
|
||||
/// </summary>
|
||||
Task<List<(long InventoryItemId, string ProductName, int MovementCount, int TotalQuantityChange)>> GetTopMovingProductsAsync(
|
||||
DateTime fromDate,
|
||||
DateTime toDate,
|
||||
int count = 10,
|
||||
StockMovementType? movementType = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
#endregion
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
using CMSMicroservice.Domain.Entities;
|
||||
|
||||
namespace CMSMicroservice.Application.Common.Interfaces.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Repository interface برای مدیریت انبارها
|
||||
/// </summary>
|
||||
public interface IWarehouseRepository
|
||||
{
|
||||
#region Read Operations
|
||||
|
||||
/// <summary>
|
||||
/// دریافت انبار بر اساس شناسه
|
||||
/// </summary>
|
||||
Task<Warehouse?> GetByIdAsync(long id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت انبار بر اساس کد
|
||||
/// </summary>
|
||||
Task<Warehouse?> GetByCodeAsync(string code, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت انبار پیشفرض
|
||||
/// </summary>
|
||||
Task<Warehouse?> GetDefaultWarehouseAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت تمام انبارهای فعال
|
||||
/// </summary>
|
||||
Task<List<Warehouse>> GetActiveWarehousesAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// دریافت تمام انبارها
|
||||
/// </summary>
|
||||
Task<List<Warehouse>> GetAllAsync(bool includeInactive = false, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// جستجوی انبارها
|
||||
/// </summary>
|
||||
Task<List<Warehouse>> SearchAsync(
|
||||
string? searchTerm = null,
|
||||
bool? isActive = null,
|
||||
int skip = 0,
|
||||
int take = 50,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// شمارش انبارها
|
||||
/// </summary>
|
||||
Task<int> CountAsync(
|
||||
string? searchTerm = null,
|
||||
bool? isActive = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// بررسی وجود انبار با کد مشخص
|
||||
/// </summary>
|
||||
Task<bool> ExistsByCodeAsync(string code, long? excludeId = null, CancellationToken cancellationToken = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Write Operations
|
||||
|
||||
/// <summary>
|
||||
/// افزودن انبار جدید
|
||||
/// </summary>
|
||||
Task<Warehouse> AddAsync(Warehouse warehouse, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// بروزرسانی انبار
|
||||
/// </summary>
|
||||
Task UpdateAsync(Warehouse warehouse, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// حذف انبار (نرمافزاری)
|
||||
/// </summary>
|
||||
Task DeleteAsync(long id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// فعال/غیرفعال کردن انبار
|
||||
/// </summary>
|
||||
Task SetActiveStatusAsync(long id, bool isActive, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// تنظیم انبار پیشفرض
|
||||
/// </summary>
|
||||
Task SetAsDefaultAsync(long id, CancellationToken cancellationToken = default);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Analytics
|
||||
|
||||
/// <summary>
|
||||
/// گزارش آمار کلی انبار
|
||||
/// </summary>
|
||||
Task<(int TotalProducts, int LowStockProducts, int OutOfStockProducts, decimal TotalValue)> GetWarehouseStatisticsAsync(
|
||||
long warehouseId,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// گزارش محصولات پرفروش انبار
|
||||
/// </summary>
|
||||
Task<List<(long ProductId, string ProductName, int TotalSold, int CurrentStock)>> GetTopSellingProductsAsync(
|
||||
long warehouseId,
|
||||
DateTime fromDate,
|
||||
DateTime toDate,
|
||||
int count = 10,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user