Files
docs/business/BUSINESS-03-ECOMMERCE-STORES.md
masoodafar-web c78850f86e docs: update BUSINESS-02, BUSINESS-03, TECH-03
BUSINESS-02:
- فرمول هایبرید: حذف MIN، اضافه validation کیف‌پول اعتباری
- فلوی خرید: اضافه مرحله بررسی موجودی + UserWalletChangeLog
- نام‌گذاری جدید کیف‌پول‌ها: اصلی، اعتباری، پاداش تیمی
- جدول وضعیت: اضافه WalletChangeLog + Validation

BUSINESS-03:
- بخش ۹ جدید: ExpirePendingOrdersService (۱۵ دقیقه)
- دیاگرام Mermaid فلوی انقضا

TECH-03:
- فیکس URL پروداکشن (kbs1→kbs2) + هشدار
- ۴ کامیت جدید در بخش ۹.۲
- بخش ۹.۳ فیکس URL پروداکشن
- بخش ۹.۴ نام‌گذاری کیف‌پول‌ها
2026-02-24 00:29:03 +03:30

270 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🛒 فروشگاه، موجودی و محصولات
> **منابع ادغام‌شده:** `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`
> **آخرین بروزرسانی:** اسفند ۱۴۰۴ (بروزرسانی: ExpirePendingOrders ۱۵ دقیقه + فروشگاه اعتباری نام‌گذاری)
---
## ۱. دو فروشگاه FourSat
```mermaid
flowchart LR
subgraph RS["Regular Store — /store"]
R1["همه کاربران"]
R2["پرداخت از Balance کیف‌پول"]
R3["قیمت عادی"]
R4["VAT = 10%"]
end
subgraph DS["Discount Store — /discount-store"]
D1["فقط اعضای باشگاه"]
D2["پرداخت ترکیبی تخفیف+نقد"]
D3["تخفیف بر اساس MaxDiscountPercent"]
D4["VAT = 10%"]
end
subgraph SHARED["مشترک"]
S1["Products"]
S2["Categories"]
S3["Inventory"]
S4["ProductImages 1:1"]
end
RS --> SHARED
DS --> SHARED
```
---
## ۲. Lazy Loading محصولات
### ۲.۱ API
```csharp
// ProductService.cs
public record ProductListResult(List<ProductDto> Products, int TotalCount);
public async Task<ProductListResult> 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 (هر دو فروشگاه)
```mermaid
flowchart TD
A["بارگذاری اولیه: 12 محصول"] --> B["اسکرول → نمایش دکمه\nنمایش محصولات بیشتر"]
B --> C["کلیک → LoadMore\nskip += 12"]
C --> D["محصولات جدید append به لیست"]
D --> E{"Products.Count >= TotalCount?"}
E -->|خیر| B
E -->|بله| F["مخفی‌شدن دکمه"]
```
---
## ۳. مدیریت موجودی (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; } // آیا موجودی رصد شود؟
}
// فیلد کلیدی در Product:
public int MaxDiscountPercent { get; set; } // 0 تا 100 — درصد تخفیف در فروشگاه اعتباری
```
### ۳.۳ فلوی سفارش و موجودی
```mermaid
flowchart TD
A["سفارش جدید"] --> B{"Quantity - Reserved >= OrderQty?"}
B -->|بله| C["Reserved += OrderQty"]
C --> D{"پرداخت موفق؟"}
D -->|موفق| E["✅ Quantity -= OrderQty\nReserved -= OrderQty"]
D -->|ناموفق| F["❌ Reserved -= OrderQty\nآزادسازی"]
B -->|خیر| G["نمایش: موجودی کافی نیست"]
```
---
## ۴. تصاویر محصول (۱:۱ مربعی)
```
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<BundleItem> Items { get; set; }
}
public class BundleItem {
public Guid ProductId { get; set; }
public int Quantity { get; set; }
}
```
### ۵.۲ فلو
```mermaid
flowchart TD
A["ادمین → ساخت باندل\nانتخاب محصولات + تعیین قیمت"] --> B["نمایش در فروشگاه\nبا تگ باندل"]
B --> C["خرید → تمام محصولات\nیکجا به سبد"]
C --> D["پرداخت → کسر موجودی\nهر محصول جداگانه"]
```
---
## ۶. یکپارچه‌سازی فروشگاه‌ها (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)
```mermaid
graph TD
ROOT["دسته‌بندی‌ها"] --> A["سلامت و زیبایی"]
ROOT --> B["تغذیه"]
ROOT --> C["ورزشی"]
A --> A1["مکمل‌ها"]
A --> A2["مراقبت پوست"]
A --> A3["مراقبت مو"]
B --> B1["ارگانیک"]
B --> B2["رژیمی"]
```
> مدل: `Category (Id, Name, ParentId?, ImageUrl, IsActive, SortOrder)`
---
## ۸. خلاصه وضعیت
| ماژول | وضعیت | درصد |
|-------|--------|------|
| فروشگاه عادی | ✅ کامل | 100% |
| فروشگاه اعتباری | ✅ کامل | 100% |
| Lazy Loading | ✅ کامل | 100% |
| موجودی خودکار | ✅ کامل | 100% |
| تصاویر مربعی | ✅ کامل | 100% |
| انقضای سفارشات Pending | ✅ کامل | 100% |
| باندل محصولات | ⬜ طراحی | 30% |
| مقایسه محصول | ⬜ ایده | 0% |
---
## ۹. انقضای خودکار سفارشات Pending (ExpirePendingOrdersService)
> سرویس پس‌زمینه‌ای که سفارشات فروشگاه اعتباری را بعد از ۱۵ دقیقه منقضی می‌کند.
### ۹.۱ پارامترها
| پارامتر | مقدار | توضیح |
|---------|-------|-------|
| `ExpirationTime` | **۱۵ دقیقه** | مدت زمان مجاز برای پرداخت |
| `CheckInterval` | ۵ دقیقه | فاصله بررسی |
### ۹.۲ عملکرد
```mermaid
flowchart TD
A["هر ۵ دقیقه\nExpirePendingOrdersService"] --> B["جستجوی DiscountOrders\nPaymentStatus=Pending\nCreated < (now - 15 min)"]
B --> C{"سفارشی یافت شد?"}
C -->|خیر| A
C -->|بله| D["آزادسازی رزرو موجودی\nReleaseReservationAsync"]
D --> E["PaymentStatus → Reject\nDeliveryStatus → Cancelled"]
E --> F["Transaction.PaymentStatus → Reject"]
F --> G["Log: Expired order #X"]
G --> A
```
### ۹.۳ فایل
```
CMS/src/CMSMicroservice.Infrastructure/BackgroundServices/ExpirePendingOrdersService.cs
```
رجیستر شده در `ConfigureServices.cs`:
```csharp
services.AddHostedService<ExpirePendingOrdersService>();
```