6.0 KiB
بهبود سیستم موجودی (Inventory System Improvements)
تاریخ: اسفند ۱۴۰۴ (February 2026)
وضعیت: ✅ پیادهسازی شده — مرج به production
پروژههای تغییر یافته: CMS, BackOffice
۱. خلاصه تغییرات
| تغییر | پروژه | وضعیت |
|---|---|---|
| ایجاد خودکار رکورد موجودی هنگام ساخت محصول عادی | CMS | ✅ |
| سرویس مهاجرت یکباراجرا برای محصولات بدون رکورد موجودی | CMS | ✅ |
| اتوکامپلیت محصولات تخفیفی | BackOffice | ✅ |
| UX هوشمند دیالوگ ورود کالا | BackOffice | ✅ |
۲. CMS — ایجاد خودکار رکورد موجودی
۲.۱ مشکل
وقتی محصول جدید عادی ساخته میشد، رکورد InventoryItem ایجاد نمیشد. این باعث میشد محصول در بخش موجودی نمایش داده نشود تا ادمین دستی آن را اضافه کند.
نکته:
CreateDiscountProductCommandHandlerاز قبلIInventoryService.InitializeInventoryAsyncرا فراخوانی میکرد — فقط handler محصول عادی این قابلیت را نداشت.
۲.۲ تغییر در CreateNewProductsCommandHandler
فایل: CMS/src/CMSMicroservice.Application/ProductsCQ/Commands/CreateNewProducts/CreateNewProductsCommandHandler.cs
// تزریق IInventoryService
private readonly IInventoryService _inventoryService;
// بعد از SaveChangesAsync:
try
{
await _inventoryService.InitializeInventoryAsync(entity.Id, ProductType.RegularProduct, 0);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to auto-initialize inventory for product {ProductId}", entity.Id);
}
- موجودی با
qty=0ایجاد میشود - خطای موجودی باعث شکست ایجاد محصول نمیشود (try/catch)
۳. CMS — InventoryInitializerService (مهاجرت یکباراجرا)
۳.۱ هدف
محصولات قدیمی (legacy) که قبل از اضافه شدن منطق خودکار ساخته شده بودند، رکورد InventoryItem ندارند. این سرویس هنگام استارت اپلیکیشن اجرا شده و برای آنها رکورد ایجاد میکند.
۳.۲ پیادهسازی
فایل: CMS/src/CMSMicroservice.Infrastructure/BackgroundServices/InventoryInitializerService.cs
BackgroundService (one-time execution on startup)
├── پیدا کردن Products بدون InventoryItem
├── پیدا کردن DiscountProducts بدون InventoryItem
├── ایجاد InventoryItem برای هر کدام (qty = RemainingCount)
└── ذخیره و توقف
ثبت در DI:
// ConfigureServices.cs
services.AddHostedService<InventoryInitializerService>();
۳.۳ ویژگیها
- یکبار اجرا: بعد از اتمام، سرویس متوقف میشود
- موجودی اولیه: از
RemainingCountمحصول (نه صفر) برای رکوردهای legacy - لاگگیری: تعداد محصولات بدون رکورد و نتیجه عملیات لاگ میشود
- مقاوم در برابر خطا: خطا باعث شکست اپلیکیشن نمیشود
۴. BackOffice — DiscountProductsAutoComplete
۴.۱ هدف
کامپوننت autocomplete برای جستجوی محصولات تخفیفی (مشابه ProductsAutoComplete موجود).
۴.۲ فایلها
| فایل | توضیح |
|---|---|
Pages/AutoComplete/DiscountProductsAutoComplete.razor |
UI کامپوننت |
Pages/AutoComplete/DiscountProductsAutoComplete.razor.cs |
Code-behind |
۴.۳ ویژگیها
- استفاده از
DiscountProductContract.DiscountProductContractClient(gRPC) - دِبانس ۷۰۰ms
- حداکثر ۹ نتیجه
- پارامتر خروجی
SelectedProductId(EventCallback) SearchQueryاز نوعstring(نهStringValue)
۵. BackOffice — UX هوشمند AddStockDialog
۵.۱ مشکل قبلی
دیالوگ «ورود کالا» یک فیلد عددی خام برای وارد کردن شناسه محصول داشت. ادمین باید شناسه را حفظ بوده یا از جایی کپی میکرد.
۵.۲ تغییر
فایل: BackOffice/src/BackOffice/Pages/Inventory/Components/AddStockDialog.razor
وقتی ProductIdParam == null (دکمه «ورود کالا» از نوار ابزار):
├── انتخاب نوع محصول (فروشگاه عادی / فروشگاه اعتباری)
├── if فروشگاه عادی → نمایش ProductsAutoComplete
├── if فروشگاه اعتباری → نمایش DiscountProductsAutoComplete
└── ولیدیشن: محصول باید انتخاب شده باشد
وقتی ProductIdParam != null (از صفحه محصول):
└── فقط فیلد تعداد نمایش داده میشود
۵.۳ UX هوشمند
- انتخاب «فروشگاه عادی» → فقط محصولات عادی در autocomplete
- انتخاب «فروشگاه اعتباری» → فقط محصولات تخفیفی در autocomplete
- جلوگیری از اشتباه ادمین
۶. خلاصه فایلهای تغییر یافته
CMS
| فایل | نوع تغییر |
|---|---|
ProductsCQ/Commands/CreateNewProducts/CreateNewProductsCommandHandler.cs |
✏️ ویرایش |
BackgroundServices/InventoryInitializerService.cs |
🆕 جدید |
Infrastructure/ConfigureServices.cs |
✏️ ویرایش (ثبت سرویس) |
BackOffice
| فایل | نوع تغییر |
|---|---|
Pages/AutoComplete/DiscountProductsAutoComplete.razor |
🆕 جدید |
Pages/AutoComplete/DiscountProductsAutoComplete.razor.cs |
🆕 جدید |
Pages/Inventory/Components/AddStockDialog.razor |
✏️ ویرایش |