# 🛒 فروشگاه، موجودی و محصولات > **منابع ادغام‌شده:** `discount-shop-business.md`, `DISCOUNT-STORE-STATUS.md`, `package-purchase-system.md`, `INVENTORY-IMPROVEMENTS.md`, `INVENTORY-REFACTORING-STATUS.md`, `PRODUCT-BUNDLE-FEATURE.md`, `SHOP-UNIFICATION.md` > **آخرین بروزرسانی:** اسفند ۱۴۰۴ --- ## ۱. دو فروشگاه FourSat ``` ┌─────────────────────────────────────────────────────────┐ │ FourSat Stores │ ├───────────────────────┬─────────────────────────────────┤ │ Regular Store │ Discount Store │ │ (/store) │ (/discount-store) │ ├───────────────────────┼─────────────────────────────────┤ │ • همه کاربران │ • فقط اعضای باشگاه │ │ • پرداخت 100% نقدی │ • پرداخت ترکیبی (تخفیف+نقد) │ │ • قیمت عادی │ • تخفیف ۳۰% از DiscountBalance │ │ • بدون محدودیت │ • وابسته به موجودی تخفیفی │ ├───────────────────────┴─────────────────────────────────┤ │ Shared: Products, Categories, │ │ Inventory, ProductImages (1:1 square) │ └─────────────────────────────────────────────────────────┘ ``` --- ## ۲. Lazy Loading محصولات ### ۲.۱ API ```csharp // ProductService.cs public record ProductListResult(List Products, int TotalCount); public async Task GetProductsPagedAsync( int skip, int take, Guid? categoryId = null, string? search = null) { var request = new GetProductsRequest { Pagination = new PaginationState { Skip = skip, Take = take }, CategoryId = categoryId?.ToString() ?? "", SearchTerm = search ?? "" }; // gRPC call... } ``` ### ۲.۲ پیاده‌سازی UI (هر دو فروشگاه) ``` بارگذاری اولیه: 12 محصول │ ▼ اسکرول → نمایش دکمه "نمایش محصولات بیشتر" │ ▼ کلیک → LoadMore() → skip += 12 │ ▼ محصولات جدید اضافه به لیست (append) │ ▼ تکرار تا Products.Count >= TotalCount │ ▼ مخفی‌شدن دکمه ``` --- ## ۳. مدیریت موجودی (Inventory) ### ۳.۱ بهبودهای اخیر | بهبود | توضیح | وضعیت | |-------|--------|--------| | Auto-Create | ایجاد خودکار رکورد موجودی هنگام ساخت محصول | ✅ | | Hangfire Worker | `InventorySyncJob` — بررسی دوره‌ای و ایجاد رکوردهای گمشده | ✅ | | Autocomplete | جستجوی محصول در صفحه موجودی BackOffice با autocomplete | ✅ | | Lazy Load | بارگذاری تنبل محصولات در هر دو فروشگاه | ✅ | ### ۳.۲ Entity ها ```csharp public class Inventory { public Guid Id { get; set; } public Guid ProductId { get; set; } // FK → Product public int Quantity { get; set; } // موجودی فعلی public int ReservedQuantity { get; set; } // رزرو‌شده public int MinimumStock { get; set; } // حداقل موجودی (هشدار) public bool TrackInventory { get; set; } // آیا موجودی رصد شود؟ } ``` ### ۳.۳ فلوی سفارش و موجودی ``` سفارش جدید │ ▼ بررسی Quantity - ReservedQuantity >= OrderQuantity? │ ├─→ بله: ReservedQuantity += OrderQuantity │ پرداخت موفق → Quantity -= OrderQuantity, Reserved -= OrderQuantity │ پرداخت ناموفق → Reserved -= OrderQuantity (آزادسازی) │ └─→ خیر: نمایش "موجودی کافی نیست" ``` --- ## ۴. تصاویر محصول (۱:۱ مربعی) ``` AppImage Component (Shared): • ObjectFit = Cover • AspectRatio = 1:1 (مربع) • Fallback = آیکون پیش‌فرض MudBlazor • LazyLoading = true اعمال در: ✅ Regular Store — ProductCard ✅ Discount Store — ProductCard ✅ BackOffice — Product List ✅ Product Detail Pages ``` --- ## ۵. باندل محصولات (Product Bundle) > ⚠️ **وضعیت: طراحی کامل — پیاده‌سازی نشده** ### ۵.۱ مدل داده ```csharp public class ProductBundle { public Guid Id { get; set; } public string Name { get; set; } public string Description { get; set; } public decimal OriginalPrice { get; set; } // مجموع قیمت تکی public decimal BundlePrice { get; set; } // قیمت باندل public decimal DiscountPercentage { get; set; } public bool IsActive { get; set; } public List Items { get; set; } } public class BundleItem { public Guid ProductId { get; set; } public int Quantity { get; set; } } ``` ### ۵.۲ فلو ``` ادمین → ساخت باندل → انتخاب محصولات + تعیین قیمت │ ▼ نمایش در فروشگاه با تگ "باندل" │ ▼ خرید → تمام محصولات باندل یکجا به سبد │ ▼ پرداخت → کسر موجودی هر محصول جداگانه ``` --- ## ۶. یکپارچه‌سازی فروشگاه‌ها (Shop Unification) ### ۶.۱ اجزای مشترک | کامپوننت | کاربرد | وضعیت | |----------|--------|--------| | `ProductCard` | کارت محصول (۱:۱) | ✅ مشترک | | `AppImage` | نمایش تصویر | ✅ مشترک | | `CategoryFilter` | فیلتر دسته‌بندی | ✅ مشترک | | `SearchBar` | جستجوی محصول | ✅ مشترک | | `LoadMoreButton` | Lazy loading | ✅ مشترک | | `CartSummary` | خلاصه سبد | ⬜ جداگانه | ### ۶.۲ مسیرهای Navigation ``` فروشگاه عادی: /store → لیست محصولات /store/product/{id} → جزئیات محصول /store/cart → سبد خرید /store/checkout → پرداخت فروشگاه تخفیفی: /discount-store → لیست محصولات /discount-store/product/{id} → جزئیات /discount-store/cart → سبد (ترکیبی) /discount-store/checkout → پرداخت ترکیبی ``` --- ## ۷. دسته‌بندی‌ها (Categories) ``` درختی / سلسله‌مراتبی │ ├── سلامت و زیبایی │ ├── مکمل‌ها │ ├── مراقبت پوست │ └── مراقبت مو ├── تغذیه │ ├── ارگانیک │ └── رژیمی └── ورزشی مدل: Category (Id, Name, ParentId?, ImageUrl, IsActive, SortOrder) ``` --- ## ۸. خلاصه وضعیت | ماژول | وضعیت | درصد | |-------|--------|------| | فروشگاه عادی | ✅ کامل | 100% | | فروشگاه تخفیفی | ✅ کامل | 100% | | Lazy Loading | ✅ کامل | 100% | | موجودی خودکار | ✅ کامل | 100% | | تصاویر مربعی | ✅ کامل | 100% | | باندل محصولات | ⬜ طراحی | 30% | | مقایسه محصول | ⬜ ایده | 0% |