# بهبود سیستم موجودی (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` ```csharp // تزریق 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:** ```csharp // ConfigureServices.cs services.AddHostedService(); ``` ### ۳.۳ ویژگی‌ها - **یکبار اجرا:** بعد از اتمام، سرویس متوقف می‌شود - **موجودی اولیه:** از `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` | ✏️ ویرایش |