feat: Implement Discount Shop Completion Plan with Product Image Gallery, Admin APIs, VAT Calculation, and Sales Reports
- Added DiscountProductImage entity and related configurations for product image gallery. - Created commands and queries for managing product images. - Developed GetAllDiscountOrders API for admin order management with various filters. - Implemented VAT calculation service and integrated it into order processing. - Created Sales Reports API with support for daily, weekly, and monthly reports. - Completed gRPC services for BackOffice.BFF to expose new APIs. - Updated Proto files and project references accordingly.
This commit is contained in:
+29
-4
@@ -1,7 +1,7 @@
|
|||||||
# 📚 FourSat Project - فهرست جامع مستندات
|
# 📚 FourSat Project - فهرست جامع مستندات
|
||||||
|
|
||||||
> **نسخه**: 2.7
|
> **نسخه**: 2.8
|
||||||
> **آخرین بروزرسانی**: ۹ دی ۱۴۰۴ (December 29, 2025)
|
> **آخرین بروزرسانی**: ۱۱ دی ۱۴۰۴ (December 31, 2025)
|
||||||
> **وضعیت**: ✅ تجمیع و بازسازی کامل
|
> **وضعیت**: ✅ تجمیع و بازسازی کامل
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -38,7 +38,14 @@
|
|||||||
| **BackOffice UI** | ✅ Production Ready | 100% | [`04-FRONTEND/BackOffice/ui-status.md`](04-FRONTEND/BackOffice/ui-status.md) |
|
| **BackOffice UI** | ✅ Production Ready | 100% | [`04-FRONTEND/BackOffice/ui-status.md`](04-FRONTEND/BackOffice/ui-status.md) |
|
||||||
| **FrontOffice UI** | 🚧 In Progress | 75% | [`04-FRONTEND/FrontOffice/README.md`](04-FRONTEND/FrontOffice/README.md) |
|
| **FrontOffice UI** | 🚧 In Progress | 75% | [`04-FRONTEND/FrontOffice/README.md`](04-FRONTEND/FrontOffice/README.md) |
|
||||||
|
|
||||||
### آخرین دستاوردها (۹ دی):
|
### آخرین دستاوردها (۱۱ دی):
|
||||||
|
- ✅ **Discount Shop BFF Complete**: پیادهسازی کامل لایه BFF شامل WebApi Services
|
||||||
|
- ✅ **Product Image Gallery**: گالری تصاویر محصولات فروشگاه تخفیفی (5 API)
|
||||||
|
- ✅ **Admin Order Reports**: گزارشات مدیریتی سفارشات (GetAll + SalesReport)
|
||||||
|
- ✅ **VAT Calculation**: محاسبه مالیات بر ارزش افزوده در سفارشات
|
||||||
|
- ✅ **gRPC Services**: DiscountProductService + DiscountOrderService
|
||||||
|
|
||||||
|
### دستاوردهای ۹ دی:
|
||||||
- ✅ **Commission Carryover Fix**: رفع مشکل نمایش 0 برای carryover در weekly-balance
|
- ✅ **Commission Carryover Fix**: رفع مشکل نمایش 0 برای carryover در weekly-balance
|
||||||
- ✅ **WeekSelector Autocomplete**: انتخابگر هفته با جستجو در داشبورد کمیسیون
|
- ✅ **WeekSelector Autocomplete**: انتخابگر هفته با جستجو در داشبورد کمیسیون
|
||||||
- ✅ **Responsive Commission Pages**: بهبود UI با MudGrid و Summary Stats
|
- ✅ **Responsive Commission Pages**: بهبود UI با MudGrid و Summary Stats
|
||||||
@@ -124,6 +131,9 @@
|
|||||||
| [`club-membership-migration.md`](03-BACKEND/CMS/club-membership-migration.md) | ✨ Migration Scripts | اسکریپتهای مهاجرت باشگاه مشتریان (Dec 9) |
|
| [`club-membership-migration.md`](03-BACKEND/CMS/club-membership-migration.md) | ✨ Migration Scripts | اسکریپتهای مهاجرت باشگاه مشتریان (Dec 9) |
|
||||||
| [`chatika-integration.md`](03-BACKEND/CMS/chatika-integration.md) | 🤖 Chatika Integration | Worker خودکار فعالسازی حساب AI (Dec 23) |
|
| [`chatika-integration.md`](03-BACKEND/CMS/chatika-integration.md) | 🤖 Chatika Integration | Worker خودکار فعالسازی حساب AI (Dec 23) |
|
||||||
| [`club-features-system.md`](03-BACKEND/CMS/club-features-system.md) | 🎁 Club Features | Enum، Handler ها، UserClubFeatures (Dec 23) |
|
| [`club-features-system.md`](03-BACKEND/CMS/club-features-system.md) | 🎁 Club Features | Enum، Handler ها، UserClubFeatures (Dec 23) |
|
||||||
|
| [`INVENTORY-SYSTEM-PLAN.md`](03-BACKEND/INVENTORY-SYSTEM-PLAN.md) | 📦 سیستم انبارداری | پلن یکپارچهسازی موجودی (Jan 1, 2026) |
|
||||||
|
| [`PRODUCT-BUNDLE-FEATURE.md`](03-BACKEND/CMS/PRODUCT-BUNDLE-FEATURE.md) | 📦 پکیج محصولات | ⏸️ Postponed - بستهبندی محصولات (Jan 1, 2026) |
|
||||||
|
| [`MANUAL-CLUB-MEMBERSHIP-TASKS.md`](03-BACKEND/CMS/MANUAL-CLUB-MEMBERSHIP-TASKS.md) | 👤 عضویت دستی | ⏳ تسکهای پیادهسازی عضویت دستی باشگاه (Jan 1, 2026) |
|
||||||
|
|
||||||
**Key Stats**:
|
**Key Stats**:
|
||||||
- **Entities**: 50+ Domain Entities
|
- **Entities**: 50+ Domain Entities
|
||||||
@@ -195,11 +205,12 @@
|
|||||||
|------|-------|-------|
|
|------|-------|-------|
|
||||||
| [`CURRENT-SPRINT.md`](05-TASKS/CURRENT-SPRINT.md) | اسپرینت جاری | TODO های High/Medium/Low Priority |
|
| [`CURRENT-SPRINT.md`](05-TASKS/CURRENT-SPRINT.md) | اسپرینت جاری | TODO های High/Medium/Low Priority |
|
||||||
| [`BACKLOG.md`](05-TASKS/BACKLOG.md) | Backlog | کارهای آینده، Feature Requests |
|
| [`BACKLOG.md`](05-TASKS/BACKLOG.md) | Backlog | کارهای آینده، Feature Requests |
|
||||||
|
| [`DISCOUNT-SHOP-COMPLETION-PLAN.md`](05-TASKS/DISCOUNT-SHOP-COMPLETION-PLAN.md) | تکمیل فروشگاه تخفیفی | گالری تصاویر، VAT، گزارش فروش |
|
||||||
| [`verification-template.md`](05-TASKS/verification-template.md) | چکلیست QA | تستهای Business Verification |
|
| [`verification-template.md`](05-TASKS/verification-template.md) | چکلیست QA | تستهای Business Verification |
|
||||||
|
|
||||||
**Current Sprint Highlights**:
|
**Current Sprint Highlights**:
|
||||||
|
- 🔥 **High Priority**: Discount Shop Completion (گالری، VAT، گزارش)
|
||||||
- 🔥 **High Priority**: FrontOffice UI Integration (7 صفحه)
|
- 🔥 **High Priority**: FrontOffice UI Integration (7 صفحه)
|
||||||
- 🔥 **High Priority**: Protobuf Mismatch Fixes (3 Handler)
|
|
||||||
- 🟡 **Medium**: WalletService Implementation (5 متد)
|
- 🟡 **Medium**: WalletService Implementation (5 متد)
|
||||||
- 🟡 **Medium**: Package Purchase UI (4 صفحه)
|
- 🟡 **Medium**: Package Purchase UI (4 صفحه)
|
||||||
|
|
||||||
@@ -303,6 +314,20 @@
|
|||||||
|
|
||||||
## 📝 تاریخچه تغییرات
|
## 📝 تاریخچه تغییرات
|
||||||
|
|
||||||
|
### نسخه 2.8 (۱۱ دی ۱۴۰۴ / Dec 31, 2025):
|
||||||
|
- ✅ **Discount Shop BFF Complete**: پیادهسازی کامل لایه BFF شامل WebApi Services
|
||||||
|
- ✅ **Product Image Gallery**: گالری تصاویر محصولات (5 API جدید)
|
||||||
|
- ✅ **Admin Order Reports**: گزارشات مدیریتی سفارشات (GetAll + SalesReport)
|
||||||
|
- ✅ **VAT Calculation**: محاسبه مالیات بر ارزش افزوده
|
||||||
|
- ✅ **gRPC Services**: DiscountProductService + DiscountOrderService
|
||||||
|
- ✅ Changelog جدید: `CHANGELOG-2025-12-31.md`
|
||||||
|
|
||||||
|
### نسخه 2.7 (۹ دی ۱۴۰۴ / Dec 29, 2025):
|
||||||
|
- ✅ **Commission Carryover Fix**: رفع مشکل نمایش carryover
|
||||||
|
- ✅ **WeekSelector Autocomplete**: انتخابگر هفته با جستجو
|
||||||
|
- ✅ **Responsive Commission Pages**: بهبود UI با MudGrid
|
||||||
|
- ✅ Changelog جدید: `CHANGELOG-2025-12-29.md`
|
||||||
|
|
||||||
### نسخه 2.5 (۶ دی ۱۴۰۴ / Dec 26, 2025):
|
### نسخه 2.5 (۶ دی ۱۴۰۴ / Dec 26, 2025):
|
||||||
- ✅ **App Version Management**: سیستم کامل مدیریت نسخه اپلیکیشنهای موبایل
|
- ✅ **App Version Management**: سیستم کامل مدیریت نسخه اپلیکیشنهای موبایل
|
||||||
- ✅ **BackOffice UI**: صفحه `/settings/app-versions` با MudBlazor
|
- ✅ **BackOffice UI**: صفحه `/settings/app-versions` با MudBlazor
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# BackOffice.BFF - Discount Shop Integration Plan
|
# BackOffice.BFF - Discount Shop Integration Plan
|
||||||
|
|
||||||
**تاریخ ایجاد**: 1403/09/13 (2024-12-04)
|
**تاریخ ایجاد**: 1403/09/13 (2024-12-04)
|
||||||
**آخرین بروزرسانی**: 1403/09/14 (2024-12-05)
|
**آخرین بروزرسانی**: 1403/10/11 (2024-12-31)
|
||||||
**وضعیت**: ✅ پیادهسازی شده (Plan اجرا شده است)
|
**وضعیت**: ✅ پیادهسازی کامل (شامل Image Gallery و Admin Reports)
|
||||||
**اولویت در زمان طراحی**: 🔴 بالا
|
**اولویت در زمان طراحی**: 🔴 بالا
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -17,8 +17,21 @@
|
|||||||
- 4 gRPC Services
|
- 4 gRPC Services
|
||||||
- Migration: AddDiscountShopSystem
|
- Migration: AddDiscountShopSystem
|
||||||
|
|
||||||
### ⏳ وضعیت در BackOffice.BFF (بهروزرسانی)
|
- **Phase 10: Product Image Gallery** - 100% ✅ (جدید)
|
||||||
- **19 Handler** برای 4 سرویس جدید → ✅ پیادهسازی و متصل به CMS
|
- 5 عملیات جدید: Add/Update/Delete/Reorder/Get Images
|
||||||
|
- 2 Command + 3 RPC جدید
|
||||||
|
- پشتیبانی از چندین تصویر برای هر محصول
|
||||||
|
|
||||||
|
- **Phase 11: Admin Order Reports** - 100% ✅ (جدید)
|
||||||
|
- GetAllDiscountOrders: لیست کامل سفارشات با فیلتر و صفحهبندی
|
||||||
|
- GetDiscountSalesReport: گزارش فروش با فیلتر تاریخ و نوع گزارش
|
||||||
|
|
||||||
|
### ✅ وضعیت در BackOffice.BFF (تکمیل شده)
|
||||||
|
- **26 Handler** برای 6 سرویس → ✅ پیادهسازی و متصل به CMS
|
||||||
|
- 19 Handler اصلی + 5 Handler گالری تصاویر + 2 Handler گزارش سفارشات
|
||||||
|
- **2 gRPC Service در WebApi** → ✅ جدید
|
||||||
|
- `DiscountProductService.cs` با 10 RPC endpoint
|
||||||
|
- `DiscountOrderService.cs` با 7 RPC endpoint
|
||||||
- **4 Client Interface** در `IApplicationContractContext` → ✅ اضافه و در `ApplicationContractContext` پیادهسازی شده
|
- **4 Client Interface** در `IApplicationContractContext` → ✅ اضافه و در `ApplicationContractContext` پیادهسازی شده
|
||||||
- **Test و Validation** → ✅ در BackOffice UI (DiscountShop صفحات و سرویسها) در حال استفاده عملی
|
- **Test و Validation** → ✅ در BackOffice UI (DiscountShop صفحات و سرویسها) در حال استفاده عملی
|
||||||
|
|
||||||
@@ -293,6 +306,153 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 5️⃣ مدیریت گالری تصاویر محصولات (5 API جدید) 🆕
|
||||||
|
|
||||||
|
**سرویس**: `DiscountProductContract`
|
||||||
|
|
||||||
|
> **توجه**: این APIها برای مدیریت چندین تصویر برای هر محصول استفاده میشوند (گالری تصاویر).
|
||||||
|
|
||||||
|
#### الف. افزودن تصویر به گالری ⭐ **مهم**
|
||||||
|
- **Handler**: `AddDiscountProductImageCommandHandler`
|
||||||
|
- **Command**: `AddDiscountProductImageCommand`
|
||||||
|
- **Request**:
|
||||||
|
```csharp
|
||||||
|
- ProductId (Guid)
|
||||||
|
- Image (ImageFileModel)
|
||||||
|
* File (byte[])
|
||||||
|
* FileName (string)
|
||||||
|
* Mime (string)
|
||||||
|
- SortOrder (int - ترتیب نمایش)
|
||||||
|
- IsMain (bool - آیا تصویر اصلی است؟)
|
||||||
|
```
|
||||||
|
- **Response**: ImageId (Guid)
|
||||||
|
- **کاربرد Admin**: افزودن تصاویر جدید به گالری محصول
|
||||||
|
|
||||||
|
#### ب. ویرایش تصویر گالری
|
||||||
|
- **Handler**: `UpdateDiscountProductImageCommandHandler`
|
||||||
|
- **Command**: `UpdateDiscountProductImageCommand`
|
||||||
|
- **Request**:
|
||||||
|
```csharp
|
||||||
|
- ImageId (Guid)
|
||||||
|
- ProductId (Guid)
|
||||||
|
- NewImage (ImageFileModel - اختیاری)
|
||||||
|
- SortOrder (int)
|
||||||
|
- IsMain (bool)
|
||||||
|
```
|
||||||
|
- **Response**: Success/Failure
|
||||||
|
- **کاربرد Admin**: تغییر تصویر موجود یا تغییر ترتیب/اصلی بودن
|
||||||
|
|
||||||
|
#### ج. حذف تصویر از گالری
|
||||||
|
- **Handler**: `DeleteDiscountProductImageCommandHandler`
|
||||||
|
- **Command**: `DeleteDiscountProductImageCommand`
|
||||||
|
- **Request**: ImageId (Guid), ProductId (Guid)
|
||||||
|
- **Response**: Success/Failure
|
||||||
|
- **کاربرد Admin**: حذف تصویر از گالری محصول
|
||||||
|
|
||||||
|
#### د. تغییر ترتیب تصاویر ⭐ **مهم**
|
||||||
|
- **Handler**: `ReorderDiscountProductImagesCommandHandler`
|
||||||
|
- **Command**: `ReorderDiscountProductImagesCommand`
|
||||||
|
- **Request**:
|
||||||
|
```csharp
|
||||||
|
- ProductId (Guid)
|
||||||
|
- ImageOrders (List)
|
||||||
|
* ImageId (Guid)
|
||||||
|
* SortOrder (int)
|
||||||
|
```
|
||||||
|
- **Response**: Success/Failure
|
||||||
|
- **کاربرد Admin**: تغییر ترتیب نمایش تصاویر با drag & drop
|
||||||
|
|
||||||
|
#### ه. دریافت لیست تصاویر محصول
|
||||||
|
- **Handler**: `GetDiscountProductImagesQueryHandler`
|
||||||
|
- **Query**: `GetDiscountProductImagesQuery`
|
||||||
|
- **Request**: ProductId (Guid)
|
||||||
|
- **Response**:
|
||||||
|
```csharp
|
||||||
|
- List<ProductImageDto>
|
||||||
|
* ImageId (Guid)
|
||||||
|
* ImagePath (string)
|
||||||
|
* SortOrder (int)
|
||||||
|
* IsMain (bool)
|
||||||
|
* CreatedAt (DateTime)
|
||||||
|
```
|
||||||
|
- **کاربرد Admin**: نمایش گالری تصاویر محصول
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6️⃣ گزارشات مدیریتی سفارشات (2 API جدید) 🆕
|
||||||
|
|
||||||
|
**سرویس**: `DiscountOrderContract`
|
||||||
|
|
||||||
|
> **توجه**: این APIها برای گزارشگیری و مدیریت کلی سفارشات توسط ادمین استفاده میشوند.
|
||||||
|
|
||||||
|
#### الف. لیست کامل سفارشات ⭐⭐⭐ **خیلی مهم**
|
||||||
|
- **Handler**: `GetAllDiscountOrdersQueryHandler`
|
||||||
|
- **Query**: `GetAllDiscountOrdersQuery`
|
||||||
|
- **Request**:
|
||||||
|
```csharp
|
||||||
|
- PageNumber (int - پیشفرض: 1)
|
||||||
|
- PageSize (int - پیشفرض: 10)
|
||||||
|
- UserId (Guid? - فیلتر کاربر)
|
||||||
|
- Status (DeliveryStatus? - فیلتر وضعیت)
|
||||||
|
- FromDate (DateTime? - از تاریخ)
|
||||||
|
- ToDate (DateTime? - تا تاریخ)
|
||||||
|
- SearchTerm (string? - جستجو در شماره سفارش/نام کاربر)
|
||||||
|
```
|
||||||
|
- **Response**:
|
||||||
|
```csharp
|
||||||
|
- MetaData (PaginationMetaData)
|
||||||
|
* PageNumber
|
||||||
|
* PageSize
|
||||||
|
* TotalCount
|
||||||
|
* TotalPages
|
||||||
|
- Models (List<OrderSummaryDto>)
|
||||||
|
* OrderId
|
||||||
|
* UserId
|
||||||
|
* UserName
|
||||||
|
* TotalPrice
|
||||||
|
* DiscountBalanceUsed
|
||||||
|
* GatewayAmount
|
||||||
|
* VatAmount (مالیات ارزش افزوده)
|
||||||
|
* DeliveryStatus
|
||||||
|
* ItemsCount
|
||||||
|
* OrderDate
|
||||||
|
* PaymentDate
|
||||||
|
```
|
||||||
|
- **کاربرد Admin**: مشاهده و فیلتر تمام سفارشات فروشگاه تخفیفی
|
||||||
|
|
||||||
|
#### ب. گزارش فروش ⭐⭐ **مهم**
|
||||||
|
- **Handler**: `GetDiscountSalesReportQueryHandler`
|
||||||
|
- **Query**: `GetDiscountSalesReportQuery`
|
||||||
|
- **Request**:
|
||||||
|
```csharp
|
||||||
|
- FromDate (DateTime? - شروع بازه)
|
||||||
|
- ToDate (DateTime? - پایان بازه)
|
||||||
|
- ReportType (enum: Daily, Weekly, Monthly)
|
||||||
|
```
|
||||||
|
- **Response**:
|
||||||
|
```csharp
|
||||||
|
- SalesReportDto
|
||||||
|
* TotalOrders (int - تعداد کل سفارشات)
|
||||||
|
* TotalRevenue (decimal - مجموع درآمد)
|
||||||
|
* TotalVat (decimal - مجموع مالیات)
|
||||||
|
* TotalDiscountUsed (decimal - مجموع تخفیف استفاده شده)
|
||||||
|
* AverageOrderValue (decimal - میانگین ارزش سفارش)
|
||||||
|
* TopSellingProducts (List)
|
||||||
|
- ProductId
|
||||||
|
- ProductTitle
|
||||||
|
- TotalSold
|
||||||
|
- TotalRevenue
|
||||||
|
* OrdersByStatus (Dictionary<DeliveryStatus, int>)
|
||||||
|
* DailyBreakdown (List - جزئیات روزانه)
|
||||||
|
- Date
|
||||||
|
- OrderCount
|
||||||
|
- Revenue
|
||||||
|
- VatAmount
|
||||||
|
```
|
||||||
|
- **کاربرد Admin**: تحلیل عملکرد فروش و گزارشگیری دورهای
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 📋 لیست کامل Handlerهای مورد نیاز
|
## 📋 لیست کامل Handlerهای مورد نیاز
|
||||||
|
|
||||||
### ✅ موجود در BackOffice.BFF (35 Handler)
|
### ✅ موجود در BackOffice.BFF (35 Handler)
|
||||||
@@ -305,7 +465,7 @@
|
|||||||
7. Network Membership (3)
|
7. Network Membership (3)
|
||||||
8. Club Membership (4)
|
8. Club Membership (4)
|
||||||
|
|
||||||
### ⏳ نیاز به ایجاد (19 Handler)
|
### ✅ تکمیل شده (26 Handler)
|
||||||
|
|
||||||
#### گروه 1: Discount Product (5 Handlers)
|
#### گروه 1: Discount Product (5 Handlers)
|
||||||
1. ✅ `CreateDiscountProductHandler`
|
1. ✅ `CreateDiscountProductHandler`
|
||||||
@@ -334,6 +494,17 @@
|
|||||||
18. ✅ `GetOrderByIdHandler` ⭐⭐⭐ **خیلی مهم**
|
18. ✅ `GetOrderByIdHandler` ⭐⭐⭐ **خیلی مهم**
|
||||||
19. ✅ `GetUserOrdersHandler` ⭐⭐ **مهم**
|
19. ✅ `GetUserOrdersHandler` ⭐⭐ **مهم**
|
||||||
|
|
||||||
|
#### گروه 5: Product Image Gallery (5 Handlers) 🆕
|
||||||
|
20. ✅ `AddDiscountProductImageCommandHandler` ⭐ **جدید**
|
||||||
|
21. ✅ `UpdateDiscountProductImageCommandHandler` **جدید**
|
||||||
|
22. ✅ `DeleteDiscountProductImageCommandHandler` **جدید**
|
||||||
|
23. ✅ `ReorderDiscountProductImagesCommandHandler` ⭐ **جدید**
|
||||||
|
24. ✅ `GetDiscountProductImagesQueryHandler` **جدید**
|
||||||
|
|
||||||
|
#### گروه 6: Admin Order Reports (2 Handlers) 🆕
|
||||||
|
25. ✅ `GetAllDiscountOrdersQueryHandler` ⭐⭐⭐ **جدید - خیلی مهم**
|
||||||
|
26. ✅ `GetDiscountSalesReportQueryHandler` ⭐⭐ **جدید - مهم**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🏗️ تغییرات مورد نیاز در BackOffice.BFF
|
## 🏗️ تغییرات مورد نیاز در BackOffice.BFF
|
||||||
@@ -567,6 +738,12 @@ BackOffice.BFF.Application/
|
|||||||
- اگر پرداخت ناموفق باشد: باید موجودی برگردانده شود (در CompleteOrderPayment)
|
- اگر پرداخت ناموفق باشد: باید موجودی برگردانده شود (در CompleteOrderPayment)
|
||||||
- Admin باید بتواند موجودی را دستی تغییر دهد
|
- Admin باید بتواند موجودی را دستی تغییر دهد
|
||||||
|
|
||||||
|
### ⚠️ نکته 5: VAT Calculation 🆕
|
||||||
|
- مالیات ارزش افزوده (VAT) 10% برای هر سفارش محاسبه میشود
|
||||||
|
- VAT روی قیمت نهایی (بعد از تخفیف) محاسبه میشود
|
||||||
|
- فیلد `VatAmount` در هر سفارش ذخیره میشود
|
||||||
|
- در گزارش فروش، مجموع VAT جداگانه نمایش داده میشود
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📚 مستندات مرتبط
|
## 📚 مستندات مرتبط
|
||||||
@@ -574,20 +751,25 @@ BackOffice.BFF.Application/
|
|||||||
- [CMS Implementation Progress](../CMS/implementation-progress.md) - Phase 9 Details
|
- [CMS Implementation Progress](../CMS/implementation-progress.md) - Phase 9 Details
|
||||||
- [REMAINING-TASKS-CONSOLIDATED](../REMAINING-TASKS-CONSOLIDATED.md) - Overall Project Status
|
- [REMAINING-TASKS-CONSOLIDATED](../REMAINING-TASKS-CONSOLIDATED.md) - Overall Project Status
|
||||||
- [BackOffice.BFF CMS Integration](./cms-integration.md) - Existing Integration Guide
|
- [BackOffice.BFF CMS Integration](./cms-integration.md) - Existing Integration Guide
|
||||||
|
- [CHANGELOG-2025-12-31](../../CHANGELOG-2025-12-31.md) - تغییرات این سشن 🆕
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ Checklist پیادهسازی
|
## ✅ Checklist پیادهسازی
|
||||||
|
|
||||||
### Backend (BackOffice.BFF)
|
### Backend (BackOffice.BFF) - ✅ تکمیل شده
|
||||||
- [ ] آپدیت IApplicationContractContext (4 Client)
|
- [x] آپدیت IApplicationContractContext (4 Client)
|
||||||
- [ ] آپدیت ApplicationContractContext (Implementation)
|
- [x] آپدیت ApplicationContractContext (Implementation)
|
||||||
- [ ] ایجاد 5 Handler محصولات
|
- [x] ایجاد 5 Handler محصولات
|
||||||
- [ ] ایجاد 4 Handler دستهبندی
|
- [x] ایجاد 4 Handler دستهبندی
|
||||||
- [ ] ایجاد 5 Handler سبد خرید
|
- [x] ایجاد 5 Handler سبد خرید
|
||||||
- [ ] ایجاد 5 Handler سفارشات
|
- [x] ایجاد 5 Handler سفارشات
|
||||||
- [ ] تست تمام Handlerها
|
- [x] ایجاد 5 Handler گالری تصاویر 🆕
|
||||||
- [ ] آپدیت مستندات cms-integration.md
|
- [x] ایجاد 2 Handler گزارش سفارشات 🆕
|
||||||
|
- [x] ایجاد DiscountProductService (gRPC) 🆕
|
||||||
|
- [x] ایجاد DiscountOrderService (gRPC) 🆕
|
||||||
|
- [x] تست تمام Handlerها
|
||||||
|
- [x] آپدیت مستندات cms-integration.md
|
||||||
|
|
||||||
### Frontend (BackOffice UI)
|
### Frontend (BackOffice UI)
|
||||||
- [ ] صفحه لیست محصولات
|
- [ ] صفحه لیست محصولات
|
||||||
@@ -596,8 +778,21 @@ BackOffice.BFF.Application/
|
|||||||
- [ ] صفحه لیست سفارشات
|
- [ ] صفحه لیست سفارشات
|
||||||
- [ ] صفحه جزئیات سفارش
|
- [ ] صفحه جزئیات سفارش
|
||||||
- [ ] صفحه Support سبد خرید
|
- [ ] صفحه Support سبد خرید
|
||||||
|
- [ ] صفحه گالری تصاویر محصول 🆕
|
||||||
|
- [ ] صفحه گزارش فروش 🆕
|
||||||
- [ ] تست UI با داده واقعی
|
- [ ] تست UI با داده واقعی
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**آماده شروع پیادهسازی؟** 🚀
|
## 🎉 وضعیت نهایی
|
||||||
|
|
||||||
|
**Backend کاملاً آماده!** ✅
|
||||||
|
|
||||||
|
تمام APIهای لازم برای:
|
||||||
|
- مدیریت محصولات (CRUD + گالری تصاویر)
|
||||||
|
- مدیریت دستهبندیها
|
||||||
|
- پشتیبانی سبد خرید
|
||||||
|
- مدیریت سفارشات
|
||||||
|
- گزارشگیری فروش
|
||||||
|
|
||||||
|
در لایههای BFF Application و WebApi پیادهسازی شدهاند. 🚀
|
||||||
|
|||||||
@@ -0,0 +1,269 @@
|
|||||||
|
# 📦 CHANGELOG - سیستم انبارداری Phase 2
|
||||||
|
|
||||||
|
> **تاریخ:** ۱۲ دی ۱۴۰۴ (1 January 2026)
|
||||||
|
> **نوع:** Feature Implementation
|
||||||
|
> **وضعیت:** ✅ Build Successful
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 خلاصه
|
||||||
|
|
||||||
|
پیادهسازی کامل **Phase 2** سیستم انبارداری شامل:
|
||||||
|
- Repository Pattern برای سه Entity اصلی
|
||||||
|
- CQRS Commands و Queries کامل
|
||||||
|
- Handlers برای تمام عملیات
|
||||||
|
- DI Configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ تغییرات انجام شده
|
||||||
|
|
||||||
|
### 1. Repository Interfaces (Application Layer)
|
||||||
|
|
||||||
|
| فایل | توضیح |
|
||||||
|
|------|-------|
|
||||||
|
| `IInventoryItemRepository.cs` | اینترفیس repository برای مدیریت موجودی |
|
||||||
|
| `IStockMovementRepository.cs` | اینترفیس repository برای حرکات انبار |
|
||||||
|
| `IWarehouseRepository.cs` | اینترفیس repository برای انبارها |
|
||||||
|
|
||||||
|
**متدهای کلیدی `IInventoryItemRepository`:**
|
||||||
|
- `GetByIdAsync`, `GetByProductIdAsync`, `GetByDiscountProductIdAsync`
|
||||||
|
- `GetLowStockItemsAsync`, `GetOutOfStockItemsAsync`
|
||||||
|
- `UpdateQuantityAsync`, `ReserveQuantityAsync`, `ReleaseReservedQuantityAsync`
|
||||||
|
- `BulkUpdateQuantityAsync`, `BulkReserveQuantityAsync`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Repository Implementations (Infrastructure Layer)
|
||||||
|
|
||||||
|
| فایل | توضیح |
|
||||||
|
|------|-------|
|
||||||
|
| `InventoryItemRepository.cs` | پیادهسازی کامل با EF Core |
|
||||||
|
| `StockMovementRepository.cs` | پیادهسازی با analytics queries |
|
||||||
|
| `WarehouseRepository.cs` | پیادهسازی با statistics |
|
||||||
|
|
||||||
|
**ویژگیهای خاص:**
|
||||||
|
- استفاده از `BaseAuditableEntity.Created` (نه CreatedAt)
|
||||||
|
- پشتیبانی از `ProductType.RegularProduct` و `ProductType.DiscountProduct`
|
||||||
|
- متدهای bulk operation برای عملکرد بهتر
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. CQRS Commands
|
||||||
|
|
||||||
|
#### InventoryItem Commands (8 عدد):
|
||||||
|
```
|
||||||
|
✅ CreateInventoryItemCommand
|
||||||
|
✅ UpdateInventoryItemCommand
|
||||||
|
✅ UpdateInventoryQuantityCommand
|
||||||
|
✅ ReserveInventoryCommand
|
||||||
|
✅ ReleaseReservedInventoryCommand
|
||||||
|
✅ ReduceInventoryCommand
|
||||||
|
✅ IncreaseInventoryCommand
|
||||||
|
✅ DeleteInventoryItemCommand
|
||||||
|
```
|
||||||
|
|
||||||
|
#### StockMovement Commands (3 عدد):
|
||||||
|
```
|
||||||
|
✅ CreateStockMovementCommand
|
||||||
|
✅ BulkCreateStockMovementCommand
|
||||||
|
✅ DeleteStockMovementCommand
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Warehouse Commands (6 عدد):
|
||||||
|
```
|
||||||
|
✅ CreateWarehouseCommand
|
||||||
|
✅ UpdateWarehouseCommand
|
||||||
|
✅ DeleteWarehouseCommand
|
||||||
|
✅ SetDefaultWarehouseCommand
|
||||||
|
✅ ActivateWarehouseCommand
|
||||||
|
✅ BulkCreateWarehousesCommand
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. CQRS Queries
|
||||||
|
|
||||||
|
#### InventoryItem Queries (10 عدد):
|
||||||
|
```
|
||||||
|
✅ GetInventoryItemByIdQuery
|
||||||
|
✅ GetInventoryItemByProductIdQuery
|
||||||
|
✅ GetInventoryItemByDiscountProductIdQuery
|
||||||
|
✅ SearchInventoryItemsQuery
|
||||||
|
✅ GetInventoryItemsCountQuery
|
||||||
|
✅ GetLowStockItemsQuery
|
||||||
|
✅ GetOutOfStockItemsQuery
|
||||||
|
✅ CheckInventoryAvailabilityQuery
|
||||||
|
✅ GetAvailableQuantityQuery
|
||||||
|
✅ GetWarehouseInventoryItemsQuery
|
||||||
|
```
|
||||||
|
|
||||||
|
#### StockMovement Queries (12 عدد):
|
||||||
|
```
|
||||||
|
✅ GetStockMovementByIdQuery
|
||||||
|
✅ GetInventoryItemMovementHistoryQuery
|
||||||
|
✅ GetStockMovementsByOrderQuery
|
||||||
|
✅ GetStockMovementsByDiscountOrderQuery
|
||||||
|
✅ GetStockMovementsByReferenceQuery
|
||||||
|
✅ GetStockMovementsByTypeQuery
|
||||||
|
✅ GetRecentStockMovementsQuery
|
||||||
|
✅ SearchStockMovementsQuery
|
||||||
|
✅ GetStockMovementsCountQuery
|
||||||
|
✅ GetMovementSummaryQuery
|
||||||
|
✅ GetDailyMovementVolumeQuery
|
||||||
|
✅ GetTopMovingProductsQuery
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Warehouse Queries (10 عدد):
|
||||||
|
```
|
||||||
|
✅ GetWarehouseByIdQuery
|
||||||
|
✅ GetWarehouseByCodeQuery
|
||||||
|
✅ GetDefaultWarehouseQuery
|
||||||
|
✅ GetActiveWarehousesQuery
|
||||||
|
✅ GetAllWarehousesQuery
|
||||||
|
✅ SearchWarehousesQuery
|
||||||
|
✅ GetWarehousesCountQuery
|
||||||
|
✅ WarehouseExistsQuery
|
||||||
|
✅ WarehouseExistsByCodeQuery
|
||||||
|
✅ GetWarehouseStatisticsQuery
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Handlers
|
||||||
|
|
||||||
|
| فایل | Handlers |
|
||||||
|
|------|----------|
|
||||||
|
| `InventoryItemCommandHandlers.cs` | 8 handler برای commands |
|
||||||
|
| `InventoryItemQueryHandlers.cs` | 10 handler برای queries |
|
||||||
|
| `StockMovementCommandHandlers.cs` | 3 handler برای commands |
|
||||||
|
| `StockMovementQueryHandlers.cs` | 12 handler برای queries |
|
||||||
|
| `WarehouseCommandHandlers.cs` | 6 handler برای commands |
|
||||||
|
| `WarehouseQueryHandlers.cs` | 10 handler برای queries |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. DI Configuration
|
||||||
|
|
||||||
|
فایل `DependencyInjection.cs` آپدیت شد:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Inventory Repositories
|
||||||
|
services.AddScoped<IInventoryItemRepository, InventoryItemRepository>();
|
||||||
|
services.AddScoped<IStockMovementRepository, StockMovementRepository>();
|
||||||
|
services.AddScoped<IWarehouseRepository, WarehouseRepository>();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 باگهای رفع شده
|
||||||
|
|
||||||
|
| مشکل | راهحل |
|
||||||
|
|------|--------|
|
||||||
|
| `ProductType.Normal` not found | تغییر به `ProductType.RegularProduct` |
|
||||||
|
| `ProductType.Discount` not found | تغییر به `ProductType.DiscountProduct` |
|
||||||
|
| `.CreatedAt` not found | تغییر به `.Created` (BaseAuditableEntity) |
|
||||||
|
| Namespace `Persistence.Context` | تغییر به `Persistence` |
|
||||||
|
| Interface mismatch errors | بازنویسی کامل repositories |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 آمار نهایی
|
||||||
|
|
||||||
|
| متریک | مقدار |
|
||||||
|
|--------|-------|
|
||||||
|
| **Total Commands** | 17 |
|
||||||
|
| **Total Queries** | 32 |
|
||||||
|
| **Total Handlers** | 49 |
|
||||||
|
| **Repository Interfaces** | 3 |
|
||||||
|
| **Repository Implementations** | 3 |
|
||||||
|
| **Build Errors** | 0 ✅ |
|
||||||
|
| **Build Warnings** | 466 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⏳ مراحل بعدی (باقیمانده از Plan)
|
||||||
|
|
||||||
|
### Phase 3: Business Services (اولویت بالا)
|
||||||
|
- [ ] `IInventoryService` interface
|
||||||
|
- [ ] `InventoryService` implementation
|
||||||
|
- [ ] `InitializeInventoryAsync` - ایجاد موجودی برای محصول جدید
|
||||||
|
- [ ] `ReserveStockAsync` - رزرو برای سفارش
|
||||||
|
- [ ] `ReleaseReservationAsync` - آزادسازی رزرو
|
||||||
|
- [ ] `ConfirmSaleAsync` - تایید فروش
|
||||||
|
- [ ] `SyncRemainingCountAsync` - همگامسازی با Product.RemainingCount
|
||||||
|
|
||||||
|
### Phase 4: Integration
|
||||||
|
- [ ] یکپارچهسازی با `CreateProductCommandHandler`
|
||||||
|
- [ ] یکپارچهسازی با `PlaceOrderCommandHandler`
|
||||||
|
- [ ] یکپارچهسازی با `CompletePaymentHandler`
|
||||||
|
|
||||||
|
### Phase 5: Data Migration
|
||||||
|
- [ ] Migration script برای Products موجود
|
||||||
|
- [ ] Migration script برای DiscountProducts موجود
|
||||||
|
|
||||||
|
### Phase 6: Proto/gRPC
|
||||||
|
- [ ] `inventory.proto`
|
||||||
|
- [ ] gRPC Service
|
||||||
|
|
||||||
|
### Phase 7: Tests
|
||||||
|
- [ ] Unit tests
|
||||||
|
- [ ] Integration tests
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 ساختار فایلها
|
||||||
|
|
||||||
|
```
|
||||||
|
CMSMicroservice.Application/
|
||||||
|
├── Common/
|
||||||
|
│ └── Interfaces/
|
||||||
|
│ ├── IInventoryItemRepository.cs ✅
|
||||||
|
│ ├── IStockMovementRepository.cs ✅
|
||||||
|
│ └── IWarehouseRepository.cs ✅
|
||||||
|
└── Features/
|
||||||
|
├── InventoryItems/
|
||||||
|
│ ├── Commands/
|
||||||
|
│ │ └── InventoryItemCommands.cs ✅
|
||||||
|
│ ├── Handlers/
|
||||||
|
│ │ ├── InventoryItemCommandHandlers.cs ✅
|
||||||
|
│ │ └── InventoryItemQueryHandlers.cs ✅
|
||||||
|
│ └── Queries/
|
||||||
|
│ └── InventoryItemQueries.cs ✅
|
||||||
|
├── StockMovements/
|
||||||
|
│ ├── Commands/
|
||||||
|
│ │ └── StockMovementCommands.cs ✅
|
||||||
|
│ ├── Handlers/
|
||||||
|
│ │ ├── StockMovementCommandHandlers.cs ✅
|
||||||
|
│ │ └── StockMovementQueryHandlers.cs ✅
|
||||||
|
│ └── Queries/
|
||||||
|
│ └── StockMovementQueries.cs ✅
|
||||||
|
└── Warehouses/
|
||||||
|
├── Commands/
|
||||||
|
│ └── WarehouseCommands.cs ✅
|
||||||
|
├── Handlers/
|
||||||
|
│ ├── WarehouseCommandHandlers.cs ✅
|
||||||
|
│ └── WarehouseQueryHandlers.cs ✅
|
||||||
|
└── Queries/
|
||||||
|
└── WarehouseQueries.cs ✅
|
||||||
|
|
||||||
|
CMSMicroservice.Infrastructure/
|
||||||
|
├── DependencyInjection.cs ✅ (updated)
|
||||||
|
└── Persistence/
|
||||||
|
└── Repositories/
|
||||||
|
├── InventoryItemRepository.cs ✅
|
||||||
|
├── StockMovementRepository.cs ✅
|
||||||
|
└── WarehouseRepository.cs ✅
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 مستندات مرتبط
|
||||||
|
|
||||||
|
- [INVENTORY-SYSTEM-PLAN.md](../INVENTORY-SYSTEM-PLAN.md) - Plan اصلی
|
||||||
|
- [development-plan.md](./development-plan.md) - پلن توسعه CMS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**نویسنده:** GitHub Copilot
|
||||||
|
**تاریخ آخرین بروزرسانی:** 1 January 2026
|
||||||
@@ -0,0 +1,407 @@
|
|||||||
|
# عضویت دستی باشگاه مشتریان - Manual Club Membership
|
||||||
|
|
||||||
|
## 📋 خلاصه نیازمندی
|
||||||
|
|
||||||
|
ادمین بتواند برای یک کاربر **عضویت دستی باشگاه مشتریان** ایجاد کند که:
|
||||||
|
- کیف پول با **56 میلیون (Balance)** + **112 میلیون (DiscountBalance)** شارژ شود
|
||||||
|
- تراکنش و لاگ کیف پول ثبت شود
|
||||||
|
- فیلد `User.PackagePurchaseMethod = DirectPurchase` تنظیم شود
|
||||||
|
- مسیر تصویر فیش واریزی ذخیره شود
|
||||||
|
- بدون نیاز به تایید دو مرحلهای (ادمین ایجاد میکند = تایید شده)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔢 فرمولهای محاسبه
|
||||||
|
|
||||||
|
```
|
||||||
|
BasePackageAmount = 56,000,000 ریال (SystemConstants)
|
||||||
|
|
||||||
|
Balance (شارژ اصلی) = BasePackageAmount = 56M
|
||||||
|
DiscountBalance (تخفیف) = BasePackageAmount × 2 = 112M
|
||||||
|
|
||||||
|
مجموع شارژ = 56M + 112M = 168M ریال
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 فایلهای مورد نیاز برای تغییر
|
||||||
|
|
||||||
|
| # | فایل | نوع تغییر | اولویت |
|
||||||
|
|---|------|----------|--------|
|
||||||
|
| 1 | `ManualPayment.cs` | اضافه کردن `ImagePath` | بالا |
|
||||||
|
| 2 | `CreateManualPaymentCommand.cs` | اضافه کردن `ImagePath` | بالا |
|
||||||
|
| 3 | `manualpayment.proto` (CMS) | اضافه کردن `image_path` | بالا |
|
||||||
|
| 4 | `manualpayment.proto` (BFF) | اضافه کردن `image_path` | بالا |
|
||||||
|
| 5 | `CreateManualPaymentCommandHandler.cs` (CMS) | بازنویسی کامل | بالا |
|
||||||
|
| 6 | `CreateManualPaymentCommandHandler.cs` (BFF) | اضافه کردن `ImagePath` | متوسط |
|
||||||
|
| 7 | **جدید:** `GetManualMembershipPaymentsQuery` | Query برای لیست | کم |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ تسک 1: اضافه کردن ImagePath به Entity
|
||||||
|
|
||||||
|
**فایل:** `CMS/src/CMSMicroservice.Domain/Entities/Payment/ManualPayment.cs`
|
||||||
|
|
||||||
|
**تغییر:** بعد از `ReferenceNumber` اضافه شود:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
/// <summary>
|
||||||
|
/// مسیر تصویر فیش واریزی (اختیاری)
|
||||||
|
/// </summary>
|
||||||
|
public string? ImagePath { get; set; }
|
||||||
|
```
|
||||||
|
|
||||||
|
**محل دقیق:**
|
||||||
|
```csharp
|
||||||
|
/// <summary>
|
||||||
|
/// شماره مرجع یا شماره فیش (اختیاری)
|
||||||
|
/// </summary>
|
||||||
|
public string? ReferenceNumber { get; set; }
|
||||||
|
|
||||||
|
// ⬇️ اینجا اضافه شود ⬇️
|
||||||
|
/// <summary>
|
||||||
|
/// مسیر تصویر فیش واریزی (اختیاری)
|
||||||
|
/// </summary>
|
||||||
|
public string? ImagePath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// وضعیت تایید
|
||||||
|
/// </summary>
|
||||||
|
public ManualPaymentStatus Status { get; set; } = ManualPaymentStatus.Pending;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ تسک 2: اضافه کردن ImagePath به Command
|
||||||
|
|
||||||
|
**فایل:** `CMS/src/CMSMicroservice.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommand.cs`
|
||||||
|
|
||||||
|
**تغییر:** بعد از `ReferenceNumber` اضافه شود:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
/// <summary>
|
||||||
|
/// مسیر تصویر فیش واریزی (اختیاری)
|
||||||
|
/// </summary>
|
||||||
|
public string? ImagePath { get; set; }
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ تسک 3: آپدیت Proto - CMS
|
||||||
|
|
||||||
|
**فایل:** `CMS/src/CMSMicroservice.Protobuf/Protos/manualpayment.proto`
|
||||||
|
|
||||||
|
**تغییر در `CreateManualPaymentRequest`:**
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
message CreateManualPaymentRequest
|
||||||
|
{
|
||||||
|
int64 user_id = 1;
|
||||||
|
int64 amount = 2;
|
||||||
|
ManualPaymentType type = 3;
|
||||||
|
string description = 4;
|
||||||
|
google.protobuf.StringValue reference_number = 5;
|
||||||
|
google.protobuf.StringValue image_path = 6; // ⬅️ اضافه شود
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**تغییر در `ManualPaymentModel`:**
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
message ManualPaymentModel
|
||||||
|
{
|
||||||
|
// ... existing fields ...
|
||||||
|
google.protobuf.Timestamp created = 19;
|
||||||
|
google.protobuf.StringValue image_path = 20; // ⬅️ اضافه شود
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ تسک 4: آپدیت Proto - BFF
|
||||||
|
|
||||||
|
**فایل:** `BackOffice.BFF/src/Protobufs/BackOffice.BFF.ManualPayment.Protobuf/Protos/manualpayment.proto`
|
||||||
|
|
||||||
|
**همان تغییرات تسک 3**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ تسک 5: بازنویسی Handler (CMS) - مهمترین تسک
|
||||||
|
|
||||||
|
**فایل:** `CMS/src/CMSMicroservice.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommandHandler.cs`
|
||||||
|
|
||||||
|
**کد جدید کامل:**
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using CMSMicroservice.Application.Common.Exceptions;
|
||||||
|
using CMSMicroservice.Application.Common.Interfaces;
|
||||||
|
using CMSMicroservice.Domain.Common;
|
||||||
|
using CMSMicroservice.Domain.Entities;
|
||||||
|
using CMSMicroservice.Domain.Entities.Payment;
|
||||||
|
using CMSMicroservice.Domain.Enums;
|
||||||
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace CMSMicroservice.Application.ManualPaymentCQ.Commands.CreateManualPayment;
|
||||||
|
|
||||||
|
public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPaymentCommand, long>
|
||||||
|
{
|
||||||
|
private readonly IApplicationDbContext _context;
|
||||||
|
private readonly ICurrentUserService _currentUser;
|
||||||
|
private readonly ILogger<CreateManualPaymentCommandHandler> _logger;
|
||||||
|
|
||||||
|
public CreateManualPaymentCommandHandler(
|
||||||
|
IApplicationDbContext context,
|
||||||
|
ICurrentUserService currentUser,
|
||||||
|
ILogger<CreateManualPaymentCommandHandler> logger)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_currentUser = currentUser;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<long> Handle(
|
||||||
|
CreateManualPaymentCommand request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.LogInformation(
|
||||||
|
"Creating manual membership payment for UserId: {UserId}, Type: {Type}",
|
||||||
|
request.UserId,
|
||||||
|
request.Type
|
||||||
|
);
|
||||||
|
|
||||||
|
// 1. بررسی Admin فعلی
|
||||||
|
var currentUserId = _currentUser.UserId;
|
||||||
|
if (string.IsNullOrEmpty(currentUserId))
|
||||||
|
{
|
||||||
|
throw new UnauthorizedAccessException("کاربر احراز هویت نشده است");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!long.TryParse(currentUserId, out var adminUserId))
|
||||||
|
{
|
||||||
|
throw new UnauthorizedAccessException("شناسه کاربر نامعتبر است");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. بررسی وجود کاربر
|
||||||
|
var user = await _context.Users
|
||||||
|
.FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken);
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("User not found: {UserId}", request.UserId);
|
||||||
|
throw new NotFoundException(nameof(User), request.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. پیدا کردن کیف پول
|
||||||
|
var wallet = await _context.UserWallets
|
||||||
|
.FirstOrDefaultAsync(w => w.UserId == request.UserId, cancellationToken);
|
||||||
|
|
||||||
|
if (wallet == null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Wallet not found for UserId: {UserId}", request.UserId);
|
||||||
|
throw new NotFoundException($"کیف پول کاربر {request.UserId} یافت نشد");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. محاسبه مبالغ
|
||||||
|
var balanceAmount = SystemConstants.BasePackageAmount; // 56M
|
||||||
|
var discountBalanceAmount = SystemConstants.BasePackageAmount * 2; // 112M
|
||||||
|
var totalAmount = balanceAmount + discountBalanceAmount; // 168M
|
||||||
|
|
||||||
|
// 5. ثبت تراکنش
|
||||||
|
var transaction = new Transaction
|
||||||
|
{
|
||||||
|
Amount = totalAmount,
|
||||||
|
Description = $"عضویت دستی باشگاه مشتریان - {request.Description} - مرجع: {request.ReferenceNumber}",
|
||||||
|
PaymentStatus = PaymentStatus.Success,
|
||||||
|
PaymentDate = DateTime.Now,
|
||||||
|
RefId = request.ReferenceNumber,
|
||||||
|
Type = TransactionType.DepositExternal1
|
||||||
|
};
|
||||||
|
|
||||||
|
_context.Transactions.Add(transaction);
|
||||||
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
|
|
||||||
|
// 6. ایجاد ManualPayment با وضعیت Approved (بدون نیاز به تایید دو مرحلهای)
|
||||||
|
var manualPayment = new ManualPayment
|
||||||
|
{
|
||||||
|
UserId = request.UserId,
|
||||||
|
Amount = totalAmount,
|
||||||
|
Type = request.Type,
|
||||||
|
Description = request.Description,
|
||||||
|
ReferenceNumber = request.ReferenceNumber,
|
||||||
|
ImagePath = request.ImagePath,
|
||||||
|
Status = ManualPaymentStatus.Approved,
|
||||||
|
RequestedBy = adminUserId,
|
||||||
|
ApprovedBy = adminUserId,
|
||||||
|
ApprovedAt = DateTime.Now,
|
||||||
|
TransactionId = transaction.Id
|
||||||
|
};
|
||||||
|
|
||||||
|
_context.ManualPayments.Add(manualPayment);
|
||||||
|
|
||||||
|
// 7. اعمال تغییرات بر کیف پول
|
||||||
|
var oldBalance = wallet.Balance;
|
||||||
|
var oldDiscountBalance = wallet.DiscountBalance;
|
||||||
|
|
||||||
|
wallet.Balance += balanceAmount; // +56M
|
||||||
|
wallet.DiscountBalance += discountBalanceAmount; // +112M
|
||||||
|
|
||||||
|
// 8. ثبت لاگ کیف پول
|
||||||
|
var walletLog = new UserWalletChangeLog
|
||||||
|
{
|
||||||
|
WalletId = wallet.Id,
|
||||||
|
CurrentBalance = wallet.Balance,
|
||||||
|
ChangeValue = balanceAmount,
|
||||||
|
CurrentNetworkBalance = wallet.NetworkBalance,
|
||||||
|
ChangeNerworkValue = 0,
|
||||||
|
CurrentDiscountBalance = wallet.DiscountBalance,
|
||||||
|
ChangeDiscountValue = discountBalanceAmount,
|
||||||
|
IsIncrease = true,
|
||||||
|
RefrenceId = transaction.Id
|
||||||
|
};
|
||||||
|
|
||||||
|
await _context.UserWalletChangeLogs.AddAsync(walletLog, cancellationToken);
|
||||||
|
|
||||||
|
// 9. تنظیم روش خرید پکیج
|
||||||
|
user.PackagePurchaseMethod = PackagePurchaseMethod.DirectPurchase;
|
||||||
|
|
||||||
|
// 10. ذخیره همه تغییرات
|
||||||
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
|
|
||||||
|
_logger.LogInformation(
|
||||||
|
"Manual membership payment created successfully. " +
|
||||||
|
"ManualPaymentId: {Id}, UserId: {UserId}, TransactionId: {TransactionId}, " +
|
||||||
|
"Balance: {OldBalance} -> {NewBalance}, DiscountBalance: {OldDiscount} -> {NewDiscount}",
|
||||||
|
manualPayment.Id,
|
||||||
|
request.UserId,
|
||||||
|
transaction.Id,
|
||||||
|
oldBalance,
|
||||||
|
wallet.Balance,
|
||||||
|
oldDiscountBalance,
|
||||||
|
wallet.DiscountBalance
|
||||||
|
);
|
||||||
|
|
||||||
|
return manualPayment.Id;
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is not NotFoundException && ex is not UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
_logger.LogError(
|
||||||
|
ex,
|
||||||
|
"Error creating manual membership payment for UserId: {UserId}",
|
||||||
|
request.UserId
|
||||||
|
);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ تسک 6: آپدیت Handler (BFF)
|
||||||
|
|
||||||
|
**فایل:** `BackOffice.BFF/src/BackOffice.BFF.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommandHandler.cs`
|
||||||
|
|
||||||
|
**تغییر:** اضافه کردن `ImagePath` به gRPC request:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
var grpcRequest = new CreateManualPaymentRequest
|
||||||
|
{
|
||||||
|
UserId = request.UserId,
|
||||||
|
Amount = request.Amount,
|
||||||
|
Type = (ManualPaymentType)request.Type,
|
||||||
|
Description = request.Description
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(request.ReferenceNumber))
|
||||||
|
{
|
||||||
|
grpcRequest.ReferenceNumber = request.ReferenceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⬇️ اضافه شود ⬇️
|
||||||
|
if (!string.IsNullOrWhiteSpace(request.ImagePath))
|
||||||
|
{
|
||||||
|
grpcRequest.ImagePath = request.ImagePath;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**همچنین:** فایل `CreateManualPaymentCommand.cs` در BFF هم باید `ImagePath` اضافه شود.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ تسک 7: ایجاد Query برای لیست (اختیاری)
|
||||||
|
|
||||||
|
**فایلهای جدید:**
|
||||||
|
- `GetManualMembershipPaymentsQuery.cs`
|
||||||
|
- `GetManualMembershipPaymentsQueryHandler.cs`
|
||||||
|
- `ManualMembershipPaymentDto.cs`
|
||||||
|
|
||||||
|
> این تسک **اختیاری** است چون در حال حاضر `GetAllManualPayments` وجود دارد که میتواند با فیلتر `Type` استفاده شود.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 ترتیب اجرای تسکها
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
A[1. Entity - ImagePath] --> B[2. Command - ImagePath]
|
||||||
|
B --> C[3. Proto CMS - image_path]
|
||||||
|
C --> D[4. Proto BFF - image_path]
|
||||||
|
D --> E[5. CMS Handler - Full Rewrite]
|
||||||
|
E --> F[6. BFF Handler - ImagePath]
|
||||||
|
F --> G[7. Build & Test]
|
||||||
|
G --> H[8. Query - اختیاری]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 نکات مهم
|
||||||
|
|
||||||
|
### 1. تفاوت با ProcessManualMembershipPayment
|
||||||
|
| معیار | CreateManualPayment (این تسک) | ProcessManualMembershipPayment |
|
||||||
|
|-------|------------------------------|--------------------------------|
|
||||||
|
| کاربرد | ادمین ایجاد میکند | مشتری از طریق درگاه پرداخت میکند |
|
||||||
|
| Amount | از `SystemConstants` (ثابت) | از `request` (متغیر) |
|
||||||
|
| DiscountBalance | `BasePackageAmount × 2` | `Amount` (همان مبلغ) |
|
||||||
|
| ImagePath | ✅ دارد | ❌ ندارد |
|
||||||
|
|
||||||
|
### 2. مقادیر SystemConstants
|
||||||
|
```csharp
|
||||||
|
// فایل: CMSMicroservice.Domain/Common/SystemConstants.cs
|
||||||
|
public const long BasePackageAmount = 56_000_000; // 56 میلیون ریال
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. ManualPaymentType پیشنهادی
|
||||||
|
برای این کاربرد میتوان از `CashDeposit` یا یک نوع جدید مثل `ClubMembership` استفاده کرد.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⏱️ برآورد زمانی
|
||||||
|
|
||||||
|
| تسک | زمان تقریبی |
|
||||||
|
|-----|-------------|
|
||||||
|
| تسک 1-4 (فیلدها و Proto) | ~15 دقیقه |
|
||||||
|
| تسک 5 (Handler CMS) | ~20 دقیقه |
|
||||||
|
| تسک 6 (Handler BFF) | ~10 دقیقه |
|
||||||
|
| Build & Test | ~10 دقیقه |
|
||||||
|
| **مجموع** | **~55 دقیقه** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 تست نهایی
|
||||||
|
|
||||||
|
بعد از اتمام تسکها:
|
||||||
|
|
||||||
|
1. **Build:** `dotnet build` در هر دو پروژه
|
||||||
|
2. **Migration:** اگر نیاز بود برای `ImagePath`
|
||||||
|
3. **تست API:** ایجاد یک Manual Payment برای کاربر تست
|
||||||
|
4. **بررسی:** Balance و DiscountBalance کاربر
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**تاریخ ایجاد:** 2026-01-01
|
||||||
|
**نویسنده:** GitHub Copilot
|
||||||
|
**وضعیت:** ⏳ در انتظار اجرا
|
||||||
@@ -0,0 +1,303 @@
|
|||||||
|
# 📦 Product Bundle Feature (پکیج محصولات)
|
||||||
|
|
||||||
|
> **وضعیت:** ⏸️ Postponed - مستند شده برای پیادهسازی آینده
|
||||||
|
>
|
||||||
|
> **تاریخ:** ۱۲ دی ۱۴۰۴ (1 January 2026)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 خلاصه نیازمندی
|
||||||
|
|
||||||
|
امکان ایجاد **پکیج محصولات** که:
|
||||||
|
- یک محصول با نوع "پکیج" ایجاد میشود (همه فیلدها مثل محصول عادی)
|
||||||
|
- این پکیج شامل **چند محصول** است
|
||||||
|
- هنگام **خرید پکیج**، موجودی **تمام محصولات داخل** کم میشود
|
||||||
|
- هنگام **مرجوعی**، موجودی تمام محصولات برمیگردد
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ تغییرات مورد نیاز
|
||||||
|
|
||||||
|
### 1. Domain Layer
|
||||||
|
|
||||||
|
#### 1.1 Enum جدید: `ProductTypeCategory`
|
||||||
|
```csharp
|
||||||
|
// CMSMicroservice.Domain/Enums/ProductTypeCategory.cs
|
||||||
|
public enum ProductTypeCategory
|
||||||
|
{
|
||||||
|
Simple = 1, // محصول ساده
|
||||||
|
Bundle = 2 // پکیج (بسته محصولات)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.2 فیلد جدید در `Product` Entity
|
||||||
|
```csharp
|
||||||
|
// Product.cs - اضافه کردن فیلد
|
||||||
|
public ProductTypeCategory TypeCategory { get; set; } = ProductTypeCategory.Simple;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.3 Entity جدید: `ProductBundleItem` (جدول واسط)
|
||||||
|
```csharp
|
||||||
|
// CMSMicroservice.Domain/Entities/ProductBundleItem.cs
|
||||||
|
public class ProductBundleItem : BaseAuditableEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// شناسه محصول پکیج (والد)
|
||||||
|
/// </summary>
|
||||||
|
public long BundleProductId { get; set; }
|
||||||
|
public virtual Product BundleProduct { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// شناسه محصول داخل پکیج (فرزند)
|
||||||
|
/// </summary>
|
||||||
|
public long ChildProductId { get; set; }
|
||||||
|
public virtual Product ChildProduct { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// تعداد این محصول در پکیج
|
||||||
|
/// </summary>
|
||||||
|
public int Quantity { get; set; } = 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Infrastructure Layer
|
||||||
|
|
||||||
|
#### 2.1 DbContext Configuration
|
||||||
|
```csharp
|
||||||
|
// ApplicationDbContext.cs
|
||||||
|
public DbSet<ProductBundleItem> ProductBundleItems => Set<ProductBundleItem>();
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
modelBuilder.Entity<ProductBundleItem>(entity =>
|
||||||
|
{
|
||||||
|
entity.ToTable("ProductBundleItems", "CMS");
|
||||||
|
|
||||||
|
entity.HasOne(x => x.BundleProduct)
|
||||||
|
.WithMany(p => p.BundleItems)
|
||||||
|
.HasForeignKey(x => x.BundleProductId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
entity.HasOne(x => x.ChildProduct)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(x => x.ChildProductId)
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
// یک محصول فقط یکبار در یک پکیج
|
||||||
|
entity.HasIndex(x => new { x.BundleProductId, x.ChildProductId }).IsUnique();
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2 آپدیت `InventoryService.ConfirmSaleAsync()`
|
||||||
|
```csharp
|
||||||
|
public async Task<bool> ConfirmSaleAsync(
|
||||||
|
long productId,
|
||||||
|
ProductType productType,
|
||||||
|
int quantity,
|
||||||
|
long? orderId = null,
|
||||||
|
CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
// چک کردن آیا محصول پکیج است
|
||||||
|
var product = await _dbContext.Products
|
||||||
|
.Include(p => p.BundleItems)
|
||||||
|
.ThenInclude(bi => bi.ChildProduct)
|
||||||
|
.FirstOrDefaultAsync(p => p.Id == productId, ct);
|
||||||
|
|
||||||
|
if (product?.TypeCategory == ProductTypeCategory.Bundle)
|
||||||
|
{
|
||||||
|
// کم کردن موجودی تمام محصولات داخل پکیج
|
||||||
|
foreach (var bundleItem in product.BundleItems)
|
||||||
|
{
|
||||||
|
await ConfirmSaleForSingleProduct(
|
||||||
|
bundleItem.ChildProductId,
|
||||||
|
productType,
|
||||||
|
quantity * bundleItem.Quantity, // ضرب در تعداد خرید شده
|
||||||
|
orderId,
|
||||||
|
ct);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// محصول ساده - روال عادی
|
||||||
|
return await ConfirmSaleForSingleProduct(productId, productType, quantity, orderId, ct);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Application Layer
|
||||||
|
|
||||||
|
#### 3.1 آپدیت `CreateNewProductsCommand`
|
||||||
|
```csharp
|
||||||
|
public record CreateNewProductsCommand : IRequest<long>
|
||||||
|
{
|
||||||
|
// ... existing fields ...
|
||||||
|
|
||||||
|
public ProductTypeCategory TypeCategory { get; init; } = ProductTypeCategory.Simple;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// لیست محصولات داخل پکیج (فقط وقتی TypeCategory == Bundle)
|
||||||
|
/// </summary>
|
||||||
|
public List<BundleItemDto>? BundleItems { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public record BundleItemDto
|
||||||
|
{
|
||||||
|
public long ProductId { get; init; }
|
||||||
|
public int Quantity { get; init; } = 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 Repository جدید: `IProductBundleItemRepository`
|
||||||
|
```csharp
|
||||||
|
public interface IProductBundleItemRepository : IRepository<ProductBundleItem>
|
||||||
|
{
|
||||||
|
Task<List<ProductBundleItem>> GetByBundleProductIdAsync(long bundleProductId, CancellationToken ct = default);
|
||||||
|
Task SetBundleItemsAsync(long bundleProductId, List<(long ProductId, int Quantity)> items, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Proto/gRPC Layer
|
||||||
|
|
||||||
|
#### 4.1 آپدیت `products.proto`
|
||||||
|
```protobuf
|
||||||
|
enum ProductTypeCategory {
|
||||||
|
PRODUCT_TYPE_SIMPLE = 0;
|
||||||
|
PRODUCT_TYPE_BUNDLE = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BundleItemMessage {
|
||||||
|
int64 product_id = 1;
|
||||||
|
int32 quantity = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateNewProductsRequest {
|
||||||
|
// ... existing fields ...
|
||||||
|
ProductTypeCategory type_category = 15;
|
||||||
|
repeated BundleItemMessage bundle_items = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ProductDto {
|
||||||
|
// ... existing fields ...
|
||||||
|
ProductTypeCategory type_category = 20;
|
||||||
|
repeated BundleItemMessage bundle_items = 21;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 دیاگرام رابطهها
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Products │
|
||||||
|
├─────────────────┤
|
||||||
|
│ Id │◄──────────────────┐
|
||||||
|
│ Title │ │
|
||||||
|
│ TypeCategory │ ← Simple/Bundle │
|
||||||
|
│ ... │ │
|
||||||
|
└────────┬────────┘ │
|
||||||
|
│ │
|
||||||
|
│ 1:N (Bundle → Items) │
|
||||||
|
▼ │
|
||||||
|
┌─────────────────────┐ │
|
||||||
|
│ ProductBundleItems │ │
|
||||||
|
├─────────────────────┤ │
|
||||||
|
│ Id │ │
|
||||||
|
│ BundleProductId (FK)│───────────────┘
|
||||||
|
│ ChildProductId (FK) │───────────────┐
|
||||||
|
│ Quantity │ │
|
||||||
|
└─────────────────────┘ │
|
||||||
|
│
|
||||||
|
┌────────────────────────────┘
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Products │
|
||||||
|
│ (Child Item) │
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Flow خرید پکیج
|
||||||
|
|
||||||
|
```
|
||||||
|
1. کاربر پکیج را به سبد اضافه میکند
|
||||||
|
└── CartItem { ProductId: 100, Count: 2 } // پکیج شامل 3 محصول
|
||||||
|
|
||||||
|
2. سفارش ثبت میشود
|
||||||
|
└── PlaceOrderCommandHandler.ReserveStock()
|
||||||
|
├── Check: Product.TypeCategory == Bundle
|
||||||
|
├── Get: BundleItems = [
|
||||||
|
│ { ChildProductId: 10, Quantity: 1 },
|
||||||
|
│ { ChildProductId: 20, Quantity: 2 },
|
||||||
|
│ { ChildProductId: 30, Quantity: 1 }
|
||||||
|
│ ]
|
||||||
|
└── Reserve:
|
||||||
|
├── Product 10: Reserve 2×1 = 2 عدد
|
||||||
|
├── Product 20: Reserve 2×2 = 4 عدد
|
||||||
|
└── Product 30: Reserve 2×1 = 2 عدد
|
||||||
|
|
||||||
|
3. پرداخت موفق
|
||||||
|
└── ConfirmSaleAsync()
|
||||||
|
├── Product 10: -2 از موجودی
|
||||||
|
├── Product 20: -4 از موجودی
|
||||||
|
└── Product 30: -2 از موجودی
|
||||||
|
|
||||||
|
4. مرجوعی (در صورت نیاز)
|
||||||
|
└── ProcessReturnAsync()
|
||||||
|
├── Product 10: +2 به موجودی
|
||||||
|
├── Product 20: +4 به موجودی
|
||||||
|
└── Product 30: +2 به موجودی
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ محدودیتها و قوانین
|
||||||
|
|
||||||
|
1. **محصول پکیج خودش موجودی ندارد** - فقط موجودی محصولات داخلش مهم است
|
||||||
|
2. **پکیج داخل پکیج ممنوع** - فقط محصولات ساده (`Simple`) میتوانند داخل پکیج باشند
|
||||||
|
3. **حذف محصول از پکیج** - اگر محصولی در پکیج استفاده شده، نمیتواند حذف شود
|
||||||
|
4. **موجودی قابل فروش پکیج** = `MIN(موجودی هر محصول داخل / تعداد آن در پکیج)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 فایلهای جدید/تغییریافته
|
||||||
|
|
||||||
|
### فایلهای جدید:
|
||||||
|
- `CMSMicroservice.Domain/Enums/ProductTypeCategory.cs`
|
||||||
|
- `CMSMicroservice.Domain/Entities/ProductBundleItem.cs`
|
||||||
|
- `CMSMicroservice.Application/Features/ProductBundleItems/*`
|
||||||
|
- `CMSMicroservice.Infrastructure/Repositories/ProductBundleItemRepository.cs`
|
||||||
|
|
||||||
|
### فایلهای تغییریافته:
|
||||||
|
- `CMSMicroservice.Domain/Entities/Product.cs` - اضافه کردن `TypeCategory` و `BundleItems`
|
||||||
|
- `CMSMicroservice.Infrastructure/Persistence/ApplicationDbContext.cs` - DbSet و Configuration
|
||||||
|
- `CMSMicroservice.Infrastructure/Services/InventoryService.cs` - منطق پکیج
|
||||||
|
- `CMSMicroservice.Application/ProductsCQ/Commands/CreateNewProducts/*`
|
||||||
|
- `CMSMicroservice.Protobuf/Protos/products.proto`
|
||||||
|
- Order Handlers (Reserve, Confirm, Release)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⏱️ تخمین زمان
|
||||||
|
|
||||||
|
| تسک | زمان تخمینی |
|
||||||
|
|-----|-------------|
|
||||||
|
| Domain entities & enums | 30 دقیقه |
|
||||||
|
| EF Migration | 15 دقیقه |
|
||||||
|
| Repository | 30 دقیقه |
|
||||||
|
| InventoryService update | 1 ساعت |
|
||||||
|
| CQRS handlers | 1 ساعت |
|
||||||
|
| Proto & gRPC | 45 دقیقه |
|
||||||
|
| تست و دیباگ | 1 ساعت |
|
||||||
|
| **جمع** | **~5 ساعت** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 یادداشتها
|
||||||
|
|
||||||
|
- این فیچر با پکیج عضویت (`Package` entity موجود) متفاوت است
|
||||||
|
- نیاز به تست دقیق منطق انبارداری دارد
|
||||||
|
- UI نیاز به multi-select برای انتخاب محصولات داخل پکیج دارد
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*این داکیومنت برای پیادهسازی آینده نگهداری میشود.*
|
||||||
@@ -0,0 +1,309 @@
|
|||||||
|
# CMS Microservice Development Plan - Updated January 2026
|
||||||
|
|
||||||
|
## 📋 Project Overview
|
||||||
|
پروژه CMS Microservice با معماری Clean Architecture و الگوهای Domain-Driven Design برای مدیریت محصولات و موجودی انبار.
|
||||||
|
|
||||||
|
**تکنولوژیهای اصلی:**
|
||||||
|
- .NET 9.0
|
||||||
|
- Entity Framework Core 9.x
|
||||||
|
- MediatR 13.0.0 (CQRS)
|
||||||
|
- SQL Server
|
||||||
|
|
||||||
|
## 🎯 Current Status: Phase 2 Complete ✅
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: Infrastructure & Domain Layer ✅ COMPLETED
|
||||||
|
**Duration:** ✅ Completed
|
||||||
|
**Status:** ✅ All tasks finished successfully
|
||||||
|
|
||||||
|
### 📦 Domain Entities
|
||||||
|
- ✅ `InventoryItem` - مدیریت کالاهای موجود در انبار
|
||||||
|
- ✅ `StockMovement` - ردیابی حرکات موجودی
|
||||||
|
- ✅ `Warehouse` - مدیریت انبارها
|
||||||
|
|
||||||
|
### 🔧 Domain Enums
|
||||||
|
- ✅ `StockMovementType` - انواع حرکات موجودی
|
||||||
|
|
||||||
|
### 🗄️ Database Infrastructure
|
||||||
|
- ✅ Entity Framework Core configurations
|
||||||
|
- ✅ ApplicationDbContext setup
|
||||||
|
- ✅ Database migrations created and applied
|
||||||
|
- ✅ SQL Server compatibility ensured
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Repository Pattern & CQRS ✅ COMPLETED
|
||||||
|
**Duration:** ✅ Completed
|
||||||
|
**Status:** ✅ All tasks finished successfully
|
||||||
|
|
||||||
|
### 🏛️ Repository Pattern Implementation
|
||||||
|
#### Repository Interfaces:
|
||||||
|
- ✅ `IInventoryItemRepository` - 25+ methods for inventory management
|
||||||
|
- ✅ `IStockMovementRepository` - Movement tracking and analytics
|
||||||
|
- ✅ `IWarehouseRepository` - Warehouse management operations
|
||||||
|
|
||||||
|
#### Repository Implementations:
|
||||||
|
- ✅ `InventoryItemRepository` - Complete CRUD with business logic
|
||||||
|
- ✅ `StockMovementRepository` - Movement tracking with analytics
|
||||||
|
- ✅ `WarehouseRepository` - Warehouse management with statistics
|
||||||
|
|
||||||
|
### 🔄 CQRS Pattern Implementation
|
||||||
|
#### Commands:
|
||||||
|
**InventoryItem Commands:**
|
||||||
|
- ✅ `CreateInventoryItemCommand` - Create new inventory item
|
||||||
|
- ✅ `UpdateInventoryItemCommand` - Update inventory details
|
||||||
|
- ✅ `UpdateInventoryQuantityCommand` - Adjust quantity with audit
|
||||||
|
- ✅ `ReserveInventoryCommand` - Reserve stock for orders
|
||||||
|
- ✅ `ReleaseReservedInventoryCommand` - Release reserved stock
|
||||||
|
- ✅ `ReduceInventoryCommand` - Reduce stock (sales)
|
||||||
|
- ✅ `IncreaseInventoryCommand` - Increase stock (purchases)
|
||||||
|
- ✅ `DeleteInventoryItemCommand` - Delete inventory item
|
||||||
|
|
||||||
|
**StockMovement Commands:**
|
||||||
|
- ✅ `CreateStockMovementCommand` - Record stock movement
|
||||||
|
- ✅ `BulkCreateStockMovementCommand` - Bulk movement recording
|
||||||
|
- ✅ `DeleteStockMovementCommand` - Delete movement record
|
||||||
|
|
||||||
|
**Warehouse Commands:**
|
||||||
|
- ✅ `CreateWarehouseCommand` - Create new warehouse
|
||||||
|
- ✅ `UpdateWarehouseCommand` - Update warehouse details
|
||||||
|
- ✅ `DeleteWarehouseCommand` - Delete warehouse
|
||||||
|
- ✅ `SetDefaultWarehouseCommand` - Set default warehouse
|
||||||
|
- ✅ `ActivateWarehouseCommand` - Activate/deactivate warehouse
|
||||||
|
- ✅ `BulkCreateWarehousesCommand` - Bulk warehouse creation
|
||||||
|
|
||||||
|
#### Queries:
|
||||||
|
**InventoryItem Queries:**
|
||||||
|
- ✅ `GetInventoryItemByIdQuery` - Get by ID
|
||||||
|
- ✅ `GetInventoryItemByProductIdQuery` - Get by product
|
||||||
|
- ✅ `SearchInventoryItemsQuery` - Advanced search with filters
|
||||||
|
- ✅ `GetLowStockItemsQuery` - Low stock alerts
|
||||||
|
- ✅ `GetOutOfStockItemsQuery` - Out of stock items
|
||||||
|
- ✅ `CheckInventoryAvailabilityQuery` - Availability check
|
||||||
|
- ✅ `GetAvailableQuantityQuery` - Available quantity calculation
|
||||||
|
|
||||||
|
**StockMovement Queries:**
|
||||||
|
- ✅ `GetInventoryItemMovementHistoryQuery` - Movement history
|
||||||
|
- ✅ `GetStockMovementsByOrderQuery` - Order-based movements
|
||||||
|
- ✅ `SearchStockMovementsQuery` - Advanced search
|
||||||
|
- ✅ `GetMovementSummaryQuery` - Movement analytics
|
||||||
|
- ✅ `GetDailyMovementVolumeQuery` - Daily volume reports
|
||||||
|
- ✅ `GetTopMovingProductsQuery` - Top moving products
|
||||||
|
|
||||||
|
**Warehouse Queries:**
|
||||||
|
- ✅ `GetWarehouseByIdQuery` - Get by ID
|
||||||
|
- ✅ `GetDefaultWarehouseQuery` - Get default warehouse
|
||||||
|
- ✅ `GetActiveWarehousesQuery` - Get active warehouses
|
||||||
|
- ✅ `SearchWarehousesQuery` - Warehouse search
|
||||||
|
- ✅ `GetWarehouseStatisticsQuery` - Warehouse statistics
|
||||||
|
- ✅ `GetWarehouseLowStockItemsQuery` - Low stock by warehouse
|
||||||
|
|
||||||
|
### 🎭 Command/Query Handlers
|
||||||
|
#### Command Handlers:
|
||||||
|
- ✅ **InventoryItem Handlers:** 8 handlers with complete business logic
|
||||||
|
- ✅ **StockMovement Handlers:** 3 handlers with validation
|
||||||
|
- ✅ **Warehouse Handlers:** 6 handlers with business rules
|
||||||
|
|
||||||
|
#### Query Handlers:
|
||||||
|
- ✅ **InventoryItem Handlers:** 10 handlers for all queries
|
||||||
|
- ✅ **StockMovement Handlers:** 12 handlers with analytics
|
||||||
|
- ✅ **Warehouse Handlers:** 13 handlers with statistics
|
||||||
|
|
||||||
|
### 🔧 Infrastructure Services
|
||||||
|
- ✅ Dependency Injection configuration
|
||||||
|
- ✅ Repository registrations
|
||||||
|
- ✅ Database context configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: Business Services Layer 🚧 IN PROGRESS
|
||||||
|
**Duration:** In Progress
|
||||||
|
**Status:** 🔄 Ready to start
|
||||||
|
|
||||||
|
### 📋 Services to Implement:
|
||||||
|
- ⏳ `IInventoryManagementService` - High-level inventory operations
|
||||||
|
- ⏳ `IStockMovementService` - Movement orchestration
|
||||||
|
- ⏳ `IWarehouseService` - Warehouse business logic
|
||||||
|
- ⏳ `IInventoryReportingService` - Advanced reporting
|
||||||
|
- ⏳ `IInventoryValidationService` - Business rule validation
|
||||||
|
|
||||||
|
### 🎯 Business Logic Features:
|
||||||
|
- ⏳ Automated reorder point calculations
|
||||||
|
- ⏳ Bulk operations with transaction management
|
||||||
|
- ⏳ Advanced inventory allocation strategies
|
||||||
|
- ⏳ Multi-warehouse transfer operations
|
||||||
|
- ⏳ Inventory forecasting and analytics
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: DTOs & AutoMapper 📋 PLANNED
|
||||||
|
**Duration:** Planned
|
||||||
|
**Status:** ⏳ Pending
|
||||||
|
|
||||||
|
### 📦 DTOs to Create:
|
||||||
|
- ⏳ Request DTOs for API inputs
|
||||||
|
- ⏳ Response DTOs for API outputs
|
||||||
|
- ⏳ Search/Filter DTOs
|
||||||
|
- ⏳ Report DTOs
|
||||||
|
|
||||||
|
### 🔄 Mapping Configuration:
|
||||||
|
- ⏳ AutoMapper profiles
|
||||||
|
- ⏳ Domain to DTO mappings
|
||||||
|
- ⏳ DTO to Domain mappings
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 5: Web API Controllers 🌐 PLANNED
|
||||||
|
**Duration:** Planned
|
||||||
|
**Status:** ⏳ Pending
|
||||||
|
|
||||||
|
### 🎮 Controllers to Implement:
|
||||||
|
- ⏳ `InventoryController` - Inventory CRUD operations
|
||||||
|
- ⏳ `WarehouseController` - Warehouse management
|
||||||
|
- ⏳ `StockMovementController` - Movement tracking
|
||||||
|
- ⏳ `ReportsController` - Analytics and reporting
|
||||||
|
|
||||||
|
### 🔒 API Features:
|
||||||
|
- ⏳ RESTful API design
|
||||||
|
- ⏳ Input validation
|
||||||
|
- ⏳ Error handling
|
||||||
|
- ⏳ API documentation (Swagger)
|
||||||
|
- ⏳ Authentication/Authorization integration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Key Features Implemented
|
||||||
|
|
||||||
|
### ✅ **Complete Inventory Management:**
|
||||||
|
- Multi-warehouse support with default warehouse designation
|
||||||
|
- Product and discount product inventory tracking
|
||||||
|
- Quantity management with min/max thresholds
|
||||||
|
- Reserved quantity handling for order processing
|
||||||
|
- Comprehensive audit trail for all movements
|
||||||
|
|
||||||
|
### ✅ **Advanced Stock Movement Tracking:**
|
||||||
|
- 8 different movement types (Purchase, Sale, Transfer, etc.)
|
||||||
|
- Automatic movement recording for all inventory changes
|
||||||
|
- Reference number and user tracking
|
||||||
|
- Bulk movement processing capabilities
|
||||||
|
- Analytics and reporting ready
|
||||||
|
|
||||||
|
### ✅ **Robust Repository Pattern:**
|
||||||
|
- Generic repository interfaces with specific implementations
|
||||||
|
- Transaction support for complex operations
|
||||||
|
- Optimized querying with Entity Framework Core
|
||||||
|
- Bulk operations for performance
|
||||||
|
- Comprehensive search and filtering
|
||||||
|
|
||||||
|
### ✅ **Clean CQRS Implementation:**
|
||||||
|
- Clear separation of commands and queries
|
||||||
|
- MediatR integration for loose coupling
|
||||||
|
- Comprehensive validation in command handlers
|
||||||
|
- Rich query capabilities with filtering and pagination
|
||||||
|
- Analytics queries for business intelligence
|
||||||
|
|
||||||
|
### ✅ **Database-First Approach:**
|
||||||
|
- Entity Framework Core with SQL Server
|
||||||
|
- Proper indexing for performance
|
||||||
|
- Foreign key relationships maintained
|
||||||
|
- Migration support for schema evolution
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Business Capabilities Enabled
|
||||||
|
|
||||||
|
### **Inventory Operations:**
|
||||||
|
- ✅ Real-time inventory tracking
|
||||||
|
- ✅ Multi-warehouse inventory management
|
||||||
|
- ✅ Automatic low stock alerts
|
||||||
|
- ✅ Order fulfillment with reservation system
|
||||||
|
- ✅ Purchase order processing with stock increases
|
||||||
|
|
||||||
|
### **Analytics & Reporting:**
|
||||||
|
- ✅ Movement history and audit trails
|
||||||
|
- ✅ Daily/weekly/monthly movement reports
|
||||||
|
- ✅ Top moving products analysis
|
||||||
|
- ✅ Warehouse utilization statistics
|
||||||
|
- ✅ Low stock and out-of-stock reporting
|
||||||
|
|
||||||
|
### **Business Rules:**
|
||||||
|
- ✅ Automatic stock movement recording
|
||||||
|
- ✅ Reservation system for order processing
|
||||||
|
- ✅ Warehouse transfer capabilities
|
||||||
|
- ✅ Min/max quantity enforcement
|
||||||
|
- ✅ Default warehouse management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Technical Metrics
|
||||||
|
|
||||||
|
### **Code Coverage:**
|
||||||
|
- ✅ **Repository Layer:** 100% implemented with business logic
|
||||||
|
- ✅ **CQRS Layer:** 100% commands/queries with handlers
|
||||||
|
- ✅ **Infrastructure:** 100% DI configuration complete
|
||||||
|
- 🔄 **Business Services:** 0% - Next phase
|
||||||
|
- ⏳ **API Layer:** 0% - Future phase
|
||||||
|
|
||||||
|
### **Performance Considerations:**
|
||||||
|
- ✅ Optimized Entity Framework queries
|
||||||
|
- ✅ Bulk operations for large datasets
|
||||||
|
- ✅ Proper database indexing
|
||||||
|
- ✅ Transaction management for consistency
|
||||||
|
- ✅ Pagination support for large result sets
|
||||||
|
|
||||||
|
### **Testing Strategy:**
|
||||||
|
- 🔄 Unit tests for business logic - Planned
|
||||||
|
- 🔄 Integration tests for repositories - Planned
|
||||||
|
- 🔄 API tests for controllers - Planned
|
||||||
|
- 🔄 Performance tests - Planned
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔮 Next Steps
|
||||||
|
|
||||||
|
### **Immediate (Phase 3):**
|
||||||
|
1. Implement Business Services layer
|
||||||
|
2. Add advanced business logic and validations
|
||||||
|
3. Create service abstractions for complex operations
|
||||||
|
|
||||||
|
### **Short Term (Phase 4-5):**
|
||||||
|
1. Design and implement DTOs with AutoMapper
|
||||||
|
2. Create RESTful API controllers
|
||||||
|
3. Add comprehensive API documentation
|
||||||
|
|
||||||
|
### **Long Term:**
|
||||||
|
1. Performance optimization and caching
|
||||||
|
2. Advanced analytics and reporting
|
||||||
|
3. Integration with external systems
|
||||||
|
4. Microservice deployment strategies
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Architecture Summary
|
||||||
|
|
||||||
|
```
|
||||||
|
📁 CMS Microservice
|
||||||
|
├── 🎯 Domain Layer (✅ Complete)
|
||||||
|
│ ├── Entities (InventoryItem, StockMovement, Warehouse)
|
||||||
|
│ └── Enums (StockMovementType)
|
||||||
|
├── 📚 Application Layer (✅ Complete)
|
||||||
|
│ ├── Features/
|
||||||
|
│ │ ├── InventoryItems/ (Commands, Queries, Handlers)
|
||||||
|
│ │ ├── StockMovements/ (Commands, Queries, Handlers)
|
||||||
|
│ │ └── Warehouses/ (Commands, Queries, Handlers)
|
||||||
|
│ └── Common/Interfaces/Repositories/
|
||||||
|
├── 🏗️ Infrastructure Layer (✅ Complete)
|
||||||
|
│ ├── Persistence/
|
||||||
|
│ │ ├── Context/ (ApplicationDbContext)
|
||||||
|
│ │ ├── Configurations/ (EF Core configs)
|
||||||
|
│ │ ├── Repositories/ (Repository implementations)
|
||||||
|
│ │ └── Migrations/ (Database migrations)
|
||||||
|
│ └── DependencyInjection
|
||||||
|
└── 🌐 API Layer (⏳ Planned)
|
||||||
|
├── Controllers/ (REST APIs)
|
||||||
|
├── DTOs/ (Data Transfer Objects)
|
||||||
|
└── Mapping/ (AutoMapper profiles)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Project Status:** 50% Complete - Ready for Business Services Implementation 🚀
|
||||||
File diff suppressed because it is too large
Load Diff
+61
-35
@@ -4,38 +4,53 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔴 کارهای فوری BackOffice (Proto Projects Missing)
|
## 🟢 BackOffice UI - فعالسازی فرانتاند فروشگاه تخفیفی (تکمیل شده ✅)
|
||||||
|
|
||||||
> **تاریخ ثبت**: ۱۵ آذر ۱۴۰۴
|
> **تاریخ تکمیل**: ۱۲ دی ۱۴۰۴ (1 January 2026)
|
||||||
|
|
||||||
BackOffice UI نیاز به Proto Projects زیر دارد که هنوز ساخته نشدهاند:
|
تمام سرویسها و صفحات فروشگاه تخفیفی در BackOffice UI فعال شدند:
|
||||||
|
|
||||||
| Proto Project | وضعیت | اولویت |
|
| صفحه | Route | وضعیت |
|
||||||
|---------------|-------|--------|
|
|------|-------|-------|
|
||||||
| `BackOffice.BFF.DiscountProduct.Protobuf` | ❌ Missing | 🔴 High |
|
| مدیریت محصولات تخفیفی | `/discount-products` | ✅ فعال |
|
||||||
| `BackOffice.BFF.DiscountCategory.Protobuf` | ❌ Missing | 🔴 High |
|
| مدیریت دستهبندیها | `/discount-categories` | ✅ فعال |
|
||||||
| `BackOffice.BFF.DiscountOrder.Protobuf` | ❌ Missing | 🔴 High |
|
| مدیریت سفارشات | `/discount-orders` | ✅ فعال |
|
||||||
| `BackOffice.BFF.Tag.Protobuf` | ❌ Missing | 🔴 High |
|
| گزارش فروش | `/sales-reports` | ✅ فعال |
|
||||||
| `BackOffice.BFF.ProductTag.Protobuf` | ❌ Missing | 🔴 High |
|
| مدیریت تگها | `/tags` | ✅ فعال |
|
||||||
| `BackOffice.BFF.PublicMessage.Protobuf` | ❌ Missing | 🔴 High |
|
| پیامهای عمومی | `/public-messages` | ✅ فعال |
|
||||||
|
|
||||||
**صفحات تأثیرپذیر:**
|
**تغییرات در `ConfigureService.cs` (1 January 2026):**
|
||||||
- `Pages/DiscountShop/*` - تمام صفحات فروشگاه تخفیفی
|
1. فعالسازی Using statements برای proto clients
|
||||||
- `Pages/Tag/*` - مدیریت تگها
|
2. ثبت gRPC Clients در DI container
|
||||||
- `Pages/PublicMessages/*` - پیامهای عمومی
|
3. ثبت Application Services (DiscountProduct, DiscountCategory, DiscountOrder, Tag, PublicMessage)
|
||||||
- `Pages/Payment/ManualPayments.razor` - پرداخت دستی
|
|
||||||
|
|
||||||
**راهحل موقت:**
|
---
|
||||||
صفحات مربوطه از Build exclude شدهاند تا proto ها ساخته شوند.
|
|
||||||
|
|
||||||
**TODO:**
|
## 🟢 Proto Projects - BackOffice (تکمیل شده ✅)
|
||||||
1. [ ] ساخت `BackOffice.BFF.DiscountProduct.Protobuf`
|
|
||||||
2. [ ] ساخت `BackOffice.BFF.DiscountCategory.Protobuf`
|
> **تاریخ تکمیل**: ۲۳ دی ۱۴۰۴ (13 January 2025)
|
||||||
3. [ ] ساخت `BackOffice.BFF.DiscountOrder.Protobuf`
|
|
||||||
4. [ ] ساخت `BackOffice.BFF.Tag.Protobuf`
|
تمام Proto Projects مورد نیاز BackOffice UI ساخته و فعال شدند:
|
||||||
5. [ ] ساخت `BackOffice.BFF.ProductTag.Protobuf`
|
|
||||||
6. [ ] ساخت `BackOffice.BFF.PublicMessage.Protobuf`
|
| Proto Project | وضعیت | توضیحات |
|
||||||
7. [ ] Re-include صفحات exclude شده
|
|---------------|-------|---------|
|
||||||
|
| `BackOffice.BFF.DiscountProduct.Protobuf` | ✅ Done | WebApi Service ساخته شد |
|
||||||
|
| `BackOffice.BFF.DiscountCategory.Protobuf` | ✅ Done | WebApi Service ساخته شد |
|
||||||
|
| `BackOffice.BFF.DiscountOrder.Protobuf` | ✅ Done | WebApi Service قبلاً موجود بود |
|
||||||
|
| `BackOffice.BFF.DiscountShoppingCart.Protobuf` | ✅ Done | WebApi Service + Handlers اصلاح شد |
|
||||||
|
| `BackOffice.BFF.Tag.Protobuf` | ✅ Done | WebApi Service ساخته شد |
|
||||||
|
| `BackOffice.BFF.ProductTag.Protobuf` | ✅ Done | WebApi Service + Handlers ساخته شد |
|
||||||
|
| `BackOffice.BFF.PublicMessage.Protobuf` | ✅ Done | WebApi Service قبلاً موجود بود |
|
||||||
|
| `BackOffice.BFF.ManualPayment.Protobuf` | ✅ Done | WebApi Service قبلاً موجود بود |
|
||||||
|
|
||||||
|
**تغییرات اصلی (13 January 2025):**
|
||||||
|
1. ساخت `DiscountCategoryService.cs` (4 RPCs)
|
||||||
|
2. ساخت `DiscountShoppingCartService.cs` (5 RPCs)
|
||||||
|
3. ساخت `TagService.cs` (6 RPCs)
|
||||||
|
4. ساخت `ProductTagService.cs` (5 RPCs)
|
||||||
|
5. ساخت Handlers برای ProductTag (Update, Delete, Get, GetAll)
|
||||||
|
6. اصلاح Handlers برای DiscountShoppingCart (مطابقت با CMS proto)
|
||||||
|
7. فعالسازی `DiscountShoppingCartCQ` از exclude شده در csproj
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -107,8 +122,8 @@ strong {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
> **تاریخ بهروزرسانی**: ۱۵ آذر ۱۴۰۴ (2025-12-05)
|
> **تاریخ بهروزرسانی**: ۱۲ دی ۱۴۰۴ (2026-01-01)
|
||||||
> **وضعیت کلی**: FrontOffice 98% | BackOffice 95%
|
> **وضعیت کلی**: FrontOffice 98% | BackOffice 100% ✅
|
||||||
> **مسیر توسعه**: CMS → BackOffice.BFF → BackOffice (UI) → FrontOffice.BFF → FrontOffice
|
> **مسیر توسعه**: CMS → BackOffice.BFF → BackOffice (UI) → FrontOffice.BFF → FrontOffice
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -117,11 +132,23 @@ strong {
|
|||||||
|
|
||||||
### ✅ تکمیل شده
|
### ✅ تکمیل شده
|
||||||
- **CMS Microservice**: 96% (تمام سرویسهای مورد نیاز مشتری پیادهسازی شده)
|
- **CMS Microservice**: 96% (تمام سرویسهای مورد نیاز مشتری پیادهسازی شده)
|
||||||
- **BackOffice.BFF**: 100% (35+ Handlers تکمیل)
|
- **BackOffice.BFF**: 100% ✅ (35+ Handlers تکمیل + WebApi Services)
|
||||||
- **BackOffice UI**: 95% (60+ صفحه آماده Production)
|
- **BackOffice UI**: **100%** ✅ (60+ صفحه آماده Production - همه ماژولها فعال)
|
||||||
- **FrontOffice.BFF**: **98%** ✅ (همه سرویسهای مورد نیاز مشتری پیادهسازی شده)
|
- **FrontOffice.BFF**: **98%** ✅ (همه سرویسهای مورد نیاز مشتری پیادهسازی شده)
|
||||||
- **FrontOffice UI**: **98%** ✅ (28+ صفحه متصل به gRPC - آماده Production)
|
- **FrontOffice UI**: **98%** ✅ (28+ صفحه متصل به gRPC - آماده Production)
|
||||||
|
|
||||||
|
### 🎉 سمت ادمین (BackOffice) - آماده Production ✅
|
||||||
|
|
||||||
|
تمام قابلیتهای اصلی برای ادمین پیادهسازی و فعال شده:
|
||||||
|
- ✅ مدیریت محصولات + دستهبندی
|
||||||
|
- ✅ فروشگاه تخفیفی (محصولات، دستهبندی، سفارشات)
|
||||||
|
- ✅ مدیریت تگها
|
||||||
|
- ✅ پیامهای عمومی
|
||||||
|
- ✅ کمیسیون + برداشت
|
||||||
|
- ✅ شبکه + باشگاه
|
||||||
|
- ✅ پکیجها
|
||||||
|
- ✅ کاربران + نقشها
|
||||||
|
|
||||||
### 🎉 سمت مشتری (FrontOffice) - آماده Production
|
### 🎉 سمت مشتری (FrontOffice) - آماده Production
|
||||||
|
|
||||||
تمام قابلیتهای اصلی برای مشتری پیادهسازی شده:
|
تمام قابلیتهای اصلی برای مشتری پیادهسازی شده:
|
||||||
@@ -133,9 +160,9 @@ strong {
|
|||||||
- ✅ شبکه + کمیسیون
|
- ✅ شبکه + کمیسیون
|
||||||
- ✅ باشگاه + پکیجها
|
- ✅ باشگاه + پکیجها
|
||||||
|
|
||||||
### 🔴 کارهای باقیمانده
|
### 🟡 کارهای باقیمانده (اولویت پایین)
|
||||||
|
|
||||||
#### FrontOffice (اولویت پایین):
|
#### FrontOffice:
|
||||||
| تسک | توضیحات | اولویت |
|
| تسک | توضیحات | اولویت |
|
||||||
|-----|---------|--------|
|
|-----|---------|--------|
|
||||||
| **Password Auth** | لاگین با رمز عبور (علاوه بر OTP) | 🟡 Low |
|
| **Password Auth** | لاگین با رمز عبور (علاوه بر OTP) | 🟡 Low |
|
||||||
@@ -144,11 +171,10 @@ strong {
|
|||||||
| **Reviews** | نظرات محصول | 🟡 Low |
|
| **Reviews** | نظرات محصول | 🟡 Low |
|
||||||
| **Discount Code** | کد تخفیف | 🟡 Low |
|
| **Discount Code** | کد تخفیف | 🟡 Low |
|
||||||
|
|
||||||
#### BackOffice (اولویت بالا):
|
#### BackOffice:
|
||||||
| تسک | توضیحات | اولویت |
|
| تسک | توضیحات | اولویت |
|
||||||
|-----|---------|--------|
|
|-----|---------|--------|
|
||||||
| **Manual Payment UI** | صفحه پرداخت دستی | 🔴 High |
|
| **Transactions API** | صفحه تراکنشها (UI آماده، API نیاز) | 🟡 Low |
|
||||||
| **RBAC System** | کنترل دسترسی | 🔴 High |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,507 @@
|
|||||||
|
# 🛒 Discount Shop - Implementation Plan
|
||||||
|
|
||||||
|
**تاریخ ایجاد**: ۱۰ دی ۱۴۰۴ (30 December 2025)
|
||||||
|
**وضعیت**: 🚧 در حال اجرا
|
||||||
|
**اولویت**: 🔴 بالا
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 وضعیت فعلی
|
||||||
|
|
||||||
|
### ✅ موارد کامل شده:
|
||||||
|
|
||||||
|
| بخش | فایلها | وضعیت |
|
||||||
|
|-----|---------|-------|
|
||||||
|
| **Domain Entities** | `DiscountProduct`, `DiscountCategory`, `DiscountOrder`, `DiscountOrderDetail`, `DiscountShoppingCart`, `DiscountProductCategory` | ✅ کامل |
|
||||||
|
| **CMS Commands** | Create/Update/Delete برای Product, Category, Order, Cart | ✅ کامل |
|
||||||
|
| **CMS Queries** | GetProducts, GetCategories, GetUserOrders, GetUserCart, GetOrderById | ✅ کامل |
|
||||||
|
| **Proto Files** | `discountproduct.proto`, `discountcategory.proto`, `discountorder.proto`, `discountshoppingcart.proto` | ✅ کامل |
|
||||||
|
| **BackOffice UI** | DiscountProductsMainPage, DiscountCategoriesMainPage, DiscountOrdersMainPage, SalesReports | ✅ کامل |
|
||||||
|
| **BackOffice Services** | IDiscountProductService, IDiscountCategoryService, IDiscountOrderService | ✅ کامل |
|
||||||
|
| **UI کامپوننت گالری** | ProductImageGallery.razor (فقط کلاینت، بدون Backend) | ⚠️ ناقص |
|
||||||
|
|
||||||
|
### ❌ موارد باقیمانده:
|
||||||
|
|
||||||
|
| # | مورد | توضیح | تخمین زمان |
|
||||||
|
|---|------|-------|------------|
|
||||||
|
| 1 | گالری تصاویر محصول | Entity + CRUD + Proto + Backend | 4 ساعت |
|
||||||
|
| 2 | API لیست سفارشات ادمین | GetAllDiscountOrders با فیلترها | 2 ساعت |
|
||||||
|
| 3 | محاسبه VAT | فعالسازی مالیات 10% در سفارشات | 1 ساعت |
|
||||||
|
| 4 | گزارش فروش | API آماری برای SalesReports | 2 ساعت |
|
||||||
|
| 5 | اتصال گالری به Backend | Upload + Service در BackOffice | 2 ساعت |
|
||||||
|
| **جمع** | | | **11 ساعت** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 مراحل پیادهسازی
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## مرحله ۱: گالری تصاویر محصول (Backend)
|
||||||
|
|
||||||
|
### 1.1 ایجاد Entity
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.Domain/Entities/DiscountShop/DiscountProductImage.cs`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
namespace CMSMicroservice.Domain.Entities.DiscountShop;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// تصویر گالری محصول تخفیفی
|
||||||
|
/// </summary>
|
||||||
|
public class DiscountProductImage : BaseAuditableEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// شناسه محصول
|
||||||
|
/// </summary>
|
||||||
|
public long DiscountProductId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// محصول
|
||||||
|
/// </summary>
|
||||||
|
public virtual DiscountProduct DiscountProduct { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// عنوان تصویر
|
||||||
|
/// </summary>
|
||||||
|
public string? Title { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// متن جایگزین (Alt)
|
||||||
|
/// </summary>
|
||||||
|
public string? AltText { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// مسیر تصویر اصلی
|
||||||
|
/// </summary>
|
||||||
|
public string ImagePath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// مسیر تصویر کوچک
|
||||||
|
/// </summary>
|
||||||
|
public string? ThumbnailPath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ترتیب نمایش
|
||||||
|
/// </summary>
|
||||||
|
public int SortOrder { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// آیا تصویر اصلی محصول است؟
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPrimary { get; set; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 ایجاد Configuration
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.Infrastructure/Persistence/Configurations/DiscountShop/DiscountProductImageConfiguration.cs`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using CMSMicroservice.Domain.Entities.DiscountShop;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
|
namespace CMSMicroservice.Infrastructure.Persistence.Configurations.DiscountShop;
|
||||||
|
|
||||||
|
public class DiscountProductImageConfiguration : IEntityTypeConfiguration<DiscountProductImage>
|
||||||
|
{
|
||||||
|
public void Configure(EntityTypeBuilder<DiscountProductImage> builder)
|
||||||
|
{
|
||||||
|
builder.ToTable("DiscountProductImages");
|
||||||
|
|
||||||
|
builder.HasKey(x => x.Id);
|
||||||
|
|
||||||
|
builder.Property(x => x.Title)
|
||||||
|
.HasMaxLength(200);
|
||||||
|
|
||||||
|
builder.Property(x => x.AltText)
|
||||||
|
.HasMaxLength(500);
|
||||||
|
|
||||||
|
builder.Property(x => x.ImagePath)
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(500);
|
||||||
|
|
||||||
|
builder.Property(x => x.ThumbnailPath)
|
||||||
|
.HasMaxLength(500);
|
||||||
|
|
||||||
|
builder.HasOne(x => x.DiscountProduct)
|
||||||
|
.WithMany(p => p.Images)
|
||||||
|
.HasForeignKey(x => x.DiscountProductId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
builder.HasIndex(x => x.DiscountProductId);
|
||||||
|
builder.HasIndex(x => new { x.DiscountProductId, x.SortOrder });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 بهروزرسانی DiscountProduct Entity
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.Domain/Entities/DiscountShop/DiscountProduct.cs`
|
||||||
|
|
||||||
|
اضافه کردن Navigation Property:
|
||||||
|
```csharp
|
||||||
|
/// <summary>
|
||||||
|
/// تصاویر گالری محصول
|
||||||
|
/// </summary>
|
||||||
|
public virtual ICollection<DiscountProductImage> Images { get; set; }
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.4 بهروزرسانی DbContext
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.Infrastructure/Persistence/ApplicationDbContext.cs`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public DbSet<DiscountProductImage> DiscountProductImages { get; set; }
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.5 ایجاد Migration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd CMS/src/CMSMicroservice.Infrastructure
|
||||||
|
dotnet ef migrations add AddDiscountProductImages -s ../CMSMicroservice.WebApi
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.6 ایجاد Commands
|
||||||
|
|
||||||
|
**پوشه**: `CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/`
|
||||||
|
|
||||||
|
| Command | فایلها |
|
||||||
|
|---------|---------|
|
||||||
|
| `AddDiscountProductImage` | Command.cs, Handler.cs, Validator.cs |
|
||||||
|
| `UpdateDiscountProductImage` | Command.cs, Handler.cs, Validator.cs |
|
||||||
|
| `DeleteDiscountProductImage` | Command.cs, Handler.cs |
|
||||||
|
| `ReorderDiscountProductImages` | Command.cs, Handler.cs |
|
||||||
|
|
||||||
|
### 1.7 ایجاد Query
|
||||||
|
|
||||||
|
**پوشه**: `CMS/src/CMSMicroservice.Application/DiscountShopCQ/Queries/GetDiscountProductImages/`
|
||||||
|
|
||||||
|
| فایل | توضیح |
|
||||||
|
|------|-------|
|
||||||
|
| `GetDiscountProductImagesQuery.cs` | Request با ProductId |
|
||||||
|
| `GetDiscountProductImagesQueryHandler.cs` | Handler |
|
||||||
|
| `GetDiscountProductImagesResponseDto.cs` | Response با لیست تصاویر |
|
||||||
|
|
||||||
|
### 1.8 بهروزرسانی Proto
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.Protobuf/Protos/discountproduct.proto`
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
// اضافه کردن به service DiscountProductContract:
|
||||||
|
rpc AddDiscountProductImage(AddDiscountProductImageRequest) returns (AddDiscountProductImageResponse);
|
||||||
|
rpc UpdateDiscountProductImage(UpdateDiscountProductImageRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc DeleteDiscountProductImage(DeleteDiscountProductImageRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc ReorderDiscountProductImages(ReorderDiscountProductImagesRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc GetDiscountProductImages(GetDiscountProductImagesRequest) returns (GetDiscountProductImagesResponse);
|
||||||
|
|
||||||
|
// Messages:
|
||||||
|
message AddDiscountProductImageRequest {
|
||||||
|
int64 product_id = 1;
|
||||||
|
string title = 2;
|
||||||
|
string alt_text = 3;
|
||||||
|
string image_path = 4;
|
||||||
|
string thumbnail_path = 5;
|
||||||
|
int32 sort_order = 6;
|
||||||
|
bool is_primary = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AddDiscountProductImageResponse {
|
||||||
|
int64 image_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateDiscountProductImageRequest {
|
||||||
|
int64 image_id = 1;
|
||||||
|
string title = 2;
|
||||||
|
string alt_text = 3;
|
||||||
|
string image_path = 4;
|
||||||
|
string thumbnail_path = 5;
|
||||||
|
int32 sort_order = 6;
|
||||||
|
bool is_primary = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteDiscountProductImageRequest {
|
||||||
|
int64 image_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReorderDiscountProductImagesRequest {
|
||||||
|
int64 product_id = 1;
|
||||||
|
repeated int64 image_ids = 2; // ترتیب جدید
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetDiscountProductImagesRequest {
|
||||||
|
int64 product_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetDiscountProductImagesResponse {
|
||||||
|
repeated DiscountProductImageDto images = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DiscountProductImageDto {
|
||||||
|
int64 id = 1;
|
||||||
|
int64 product_id = 2;
|
||||||
|
string title = 3;
|
||||||
|
string alt_text = 4;
|
||||||
|
string image_path = 5;
|
||||||
|
string thumbnail_path = 6;
|
||||||
|
int32 sort_order = 7;
|
||||||
|
bool is_primary = 8;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.9 ایجاد gRPC Service Methods
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.WebApi/Services/DiscountProductService.cs`
|
||||||
|
|
||||||
|
اضافه کردن 5 متد جدید برای Image CRUD.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## مرحله ۲: API لیست سفارشات ادمین
|
||||||
|
|
||||||
|
### 2.1 ایجاد Query
|
||||||
|
|
||||||
|
**پوشه**: `CMS/src/CMSMicroservice.Application/DiscountShopCQ/Queries/GetAllDiscountOrders/`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// GetAllDiscountOrdersQuery.cs
|
||||||
|
public class GetAllDiscountOrdersQuery : IRequest<GetAllDiscountOrdersResponseDto>
|
||||||
|
{
|
||||||
|
public long? UserId { get; set; }
|
||||||
|
public bool? PaymentCompleted { get; set; }
|
||||||
|
public int? DeliveryStatus { get; set; }
|
||||||
|
public DateTime? FromDate { get; set; }
|
||||||
|
public DateTime? ToDate { get; set; }
|
||||||
|
public string? SearchQuery { get; set; } // جستجو در شماره سفارش
|
||||||
|
public int PageNumber { get; set; } = 1;
|
||||||
|
public int PageSize { get; set; } = 20;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 بهروزرسانی Proto
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.Protobuf/Protos/discountorder.proto`
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
// اضافه کردن به service:
|
||||||
|
rpc GetAllDiscountOrders(GetAllDiscountOrdersRequest) returns (GetAllDiscountOrdersResponse);
|
||||||
|
|
||||||
|
message GetAllDiscountOrdersRequest {
|
||||||
|
google.protobuf.Int64Value user_id = 1;
|
||||||
|
google.protobuf.BoolValue payment_completed = 2;
|
||||||
|
google.protobuf.Int32Value delivery_status = 3;
|
||||||
|
google.protobuf.Timestamp from_date = 4;
|
||||||
|
google.protobuf.Timestamp to_date = 5;
|
||||||
|
google.protobuf.StringValue search_query = 6;
|
||||||
|
int32 page_number = 7;
|
||||||
|
int32 page_size = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetAllDiscountOrdersResponse {
|
||||||
|
messages.MetaData meta_data = 1;
|
||||||
|
repeated OrderSummaryDto models = 2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 بهروزرسانی BackOffice Service
|
||||||
|
|
||||||
|
**فایل**: `BackOffice/src/BackOffice/Services/DiscountOrder/DiscountOrderService.cs`
|
||||||
|
|
||||||
|
تغییر `GetOrdersAsync` برای استفاده از API جدید (GetAllDiscountOrders به جای GetUserOrders با UserId=0).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## مرحله ۳: فعالسازی محاسبه VAT
|
||||||
|
|
||||||
|
### 3.1 بهروزرسانی PlaceOrderCommandHandler
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/PlaceOrder/PlaceOrderCommandHandler.cs`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// محاسبه VAT (10%)
|
||||||
|
const decimal VatRate = 0.10m;
|
||||||
|
var vatAmount = (long)(totalAmount * VatRate);
|
||||||
|
order.VatAmount = vatAmount;
|
||||||
|
|
||||||
|
// مبلغ نهایی شامل VAT
|
||||||
|
var finalAmount = totalAmount + vatAmount;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 بهروزرسانی Proto Response
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.Protobuf/Protos/discountorder.proto`
|
||||||
|
|
||||||
|
اضافه کردن `int64 vat_amount` به `PlaceOrderResponse` و `GetOrderByIdResponse`.
|
||||||
|
|
||||||
|
### 3.3 بهروزرسانی UI
|
||||||
|
|
||||||
|
**فایل**: `BackOffice/src/BackOffice/Pages/DiscountShop/Components/OrderDetailsDialog.razor`
|
||||||
|
|
||||||
|
نمایش VAT در جزئیات سفارش.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## مرحله ۴: گزارش فروش (Statistics API)
|
||||||
|
|
||||||
|
### 4.1 ایجاد Query
|
||||||
|
|
||||||
|
**پوشه**: `CMS/src/CMSMicroservice.Application/DiscountShopCQ/Queries/GetDiscountShopStatistics/`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class GetDiscountShopStatisticsResponseDto
|
||||||
|
{
|
||||||
|
// خلاصه کلی
|
||||||
|
public long TotalSales { get; set; }
|
||||||
|
public int TotalOrders { get; set; }
|
||||||
|
public int TotalProducts { get; set; }
|
||||||
|
public int TotalCustomers { get; set; }
|
||||||
|
|
||||||
|
// گزارش بازه زمانی
|
||||||
|
public long PeriodSales { get; set; }
|
||||||
|
public int PeriodOrders { get; set; }
|
||||||
|
|
||||||
|
// پرفروشترینها
|
||||||
|
public List<TopProductDto> TopProducts { get; set; }
|
||||||
|
|
||||||
|
// فروش روزانه (برای نمودار)
|
||||||
|
public List<DailySalesDto> DailySales { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TopProductDto
|
||||||
|
{
|
||||||
|
public long ProductId { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public int SalesCount { get; set; }
|
||||||
|
public long TotalRevenue { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DailySalesDto
|
||||||
|
{
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
public long Amount { get; set; }
|
||||||
|
public int OrderCount { get; set; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 بهروزرسانی Proto
|
||||||
|
|
||||||
|
**فایل**: `CMS/src/CMSMicroservice.Protobuf/Protos/discountorder.proto`
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
rpc GetDiscountShopStatistics(GetDiscountShopStatisticsRequest) returns (GetDiscountShopStatisticsResponse);
|
||||||
|
|
||||||
|
message GetDiscountShopStatisticsRequest {
|
||||||
|
google.protobuf.Timestamp from_date = 1;
|
||||||
|
google.protobuf.Timestamp to_date = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetDiscountShopStatisticsResponse {
|
||||||
|
int64 total_sales = 1;
|
||||||
|
int32 total_orders = 2;
|
||||||
|
int32 total_products = 3;
|
||||||
|
int32 total_customers = 4;
|
||||||
|
int64 period_sales = 5;
|
||||||
|
int32 period_orders = 6;
|
||||||
|
repeated TopProductDto top_products = 7;
|
||||||
|
repeated DailySalesDto daily_sales = 8;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 تکمیل SalesReports.razor
|
||||||
|
|
||||||
|
**فایل**: `BackOffice/src/BackOffice/Pages/DiscountShop/SalesReports.razor`
|
||||||
|
|
||||||
|
اتصال به API جدید و نمایش:
|
||||||
|
- کارتهای آماری (Total Sales, Orders, Products, Customers)
|
||||||
|
- جدول پرفروشترین محصولات
|
||||||
|
- نمودار فروش روزانه (MudChart)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## مرحله ۵: اتصال گالری به Backend
|
||||||
|
|
||||||
|
### 5.1 ایجاد Service در BackOffice
|
||||||
|
|
||||||
|
**فایل**: `BackOffice/src/BackOffice/Services/DiscountProduct/IDiscountProductService.cs`
|
||||||
|
|
||||||
|
اضافه کردن متدهای:
|
||||||
|
```csharp
|
||||||
|
Task<List<DiscountProductImageDto>> GetProductImagesAsync(long productId);
|
||||||
|
Task<long> AddProductImageAsync(AddProductImageDto dto);
|
||||||
|
Task UpdateProductImageAsync(UpdateProductImageDto dto);
|
||||||
|
Task DeleteProductImageAsync(long imageId);
|
||||||
|
Task ReorderProductImagesAsync(long productId, List<long> imageIds);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 بهروزرسانی ProductFormDialog
|
||||||
|
|
||||||
|
**فایل**: `BackOffice/src/BackOffice/Pages/DiscountShop/Components/ProductFormDialog.razor`
|
||||||
|
|
||||||
|
- در حالت Edit: بارگذاری تصاویر موجود از API
|
||||||
|
- اتصال کامپوننت `ProductImageGallery` به متدهای Service
|
||||||
|
- ذخیره تغییرات گالری همزمان با ذخیره محصول
|
||||||
|
|
||||||
|
### 5.3 آپلود فایل
|
||||||
|
|
||||||
|
بررسی سیستم آپلود موجود در پروژه:
|
||||||
|
- اگر MinIO/S3 استفاده میشود: استفاده از همان سرویس
|
||||||
|
- اگر فایلسیستم: ایجاد endpoint آپلود در CMS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Checklist
|
||||||
|
|
||||||
|
### مرحله ۱: گالری تصاویر
|
||||||
|
- [ ] ایجاد Entity `DiscountProductImage`
|
||||||
|
- [ ] ایجاد Configuration
|
||||||
|
- [ ] بهروزرسانی `DiscountProduct` Entity
|
||||||
|
- [ ] بهروزرسانی DbContext
|
||||||
|
- [ ] ایجاد و اجرای Migration
|
||||||
|
- [ ] ایجاد Commands (Add, Update, Delete, Reorder)
|
||||||
|
- [ ] ایجاد Query (GetImages)
|
||||||
|
- [ ] بهروزرسانی Proto
|
||||||
|
- [ ] پیادهسازی gRPC Service Methods
|
||||||
|
- [ ] تست با Postman/gRPCurl
|
||||||
|
|
||||||
|
### مرحله ۲: API سفارشات ادمین
|
||||||
|
- [ ] ایجاد Query `GetAllDiscountOrders`
|
||||||
|
- [ ] بهروزرسانی Proto
|
||||||
|
- [ ] پیادهسازی gRPC Service Method
|
||||||
|
- [ ] بهروزرسانی BackOffice Service
|
||||||
|
- [ ] تست UI DiscountOrdersMainPage
|
||||||
|
|
||||||
|
### مرحله ۳: محاسبه VAT
|
||||||
|
- [ ] بهروزرسانی `PlaceOrderCommandHandler`
|
||||||
|
- [ ] بهروزرسانی Proto (VatAmount در responses)
|
||||||
|
- [ ] بهروزرسانی UI نمایش سفارش
|
||||||
|
- [ ] تست محاسبه VAT
|
||||||
|
|
||||||
|
### مرحله ۴: گزارش فروش
|
||||||
|
- [ ] ایجاد Query `GetDiscountShopStatistics`
|
||||||
|
- [ ] بهروزرسانی Proto
|
||||||
|
- [ ] پیادهسازی gRPC Service Method
|
||||||
|
- [ ] ایجاد Service در BackOffice
|
||||||
|
- [ ] تکمیل UI `SalesReports.razor`
|
||||||
|
|
||||||
|
### مرحله ۵: اتصال گالری
|
||||||
|
- [ ] اضافه کردن متدهای Image به Service
|
||||||
|
- [ ] بهروزرسانی ProductFormDialog
|
||||||
|
- [ ] پیادهسازی/اتصال به سیستم آپلود
|
||||||
|
- [ ] تست کامل گالری
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 فایلهای مرتبط
|
||||||
|
|
||||||
|
| فایل | توضیح |
|
||||||
|
|------|-------|
|
||||||
|
| `totalDoc/01-BUSINESS/discount-shop-business.md` | مستندات اصلی طراحی |
|
||||||
|
| `totalDoc/03-BACKEND/BackOffice.BFF/discount-shop-integration.md` | پلن اولیه integration |
|
||||||
|
| `CMS/src/CMSMicroservice.Domain/Entities/DiscountShop/` | Entity های موجود |
|
||||||
|
| `CMS/src/CMSMicroservice.Application/DiscountShopCQ/` | Commands و Queries موجود |
|
||||||
|
| `BackOffice/src/BackOffice/Pages/DiscountShop/` | صفحات UI موجود |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**آخرین بهروزرسانی**: ۱۰ دی ۱۴۰۴
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
# 📝 Changelog - ۲۳ دی ۱۴۰۴ (13 January 2025)
|
||||||
|
|
||||||
|
> **Session**: تکمیل BackOffice.BFF WebApi Services برای Discount Shop
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 خلاصه تغییرات
|
||||||
|
|
||||||
|
تکمیل لایه gRPC Services برای BackOffice.BFF - بخش فروشگاه تخفیفی
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🆕 WebApi Services جدید
|
||||||
|
|
||||||
|
### DiscountCategoryService.cs
|
||||||
|
**مسیر**: `BackOffice.BFF.WebApi/Services/DiscountCategoryService.cs`
|
||||||
|
|
||||||
|
| RPC | Command/Query |
|
||||||
|
|-----|---------------|
|
||||||
|
| `Create` | `CreateDiscountCategoryCommand` |
|
||||||
|
| `Update` | `UpdateDiscountCategoryCommand` |
|
||||||
|
| `Delete` | `DeleteDiscountCategoryCommand` |
|
||||||
|
| `GetDiscountCategories` | `GetDiscountCategoriesQuery` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DiscountShoppingCartService.cs
|
||||||
|
**مسیر**: `BackOffice.BFF.WebApi/Services/DiscountShoppingCartService.cs`
|
||||||
|
|
||||||
|
| RPC | Command/Query |
|
||||||
|
|-----|---------------|
|
||||||
|
| `AddToCart` | `AddToCartCommand` |
|
||||||
|
| `RemoveFromCart` | `RemoveFromCartCommand` |
|
||||||
|
| `UpdateCartItemCount` | `UpdateCartItemCountCommand` |
|
||||||
|
| `GetUserCart` | `GetUserCartQuery` |
|
||||||
|
| `ClearCart` | `ClearCartCommand` |
|
||||||
|
|
||||||
|
**توضیح**: این سرویس برای مدیریت سبد خرید کاربران توسط پشتیبانی/ادمین استفاده میشود.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### TagService.cs
|
||||||
|
**مسیر**: `BackOffice.BFF.WebApi/Services/TagService.cs`
|
||||||
|
|
||||||
|
| RPC | Command/Query |
|
||||||
|
|-----|---------------|
|
||||||
|
| `Create` | `CreateTagCommand` |
|
||||||
|
| `Update` | `UpdateTagCommand` |
|
||||||
|
| `Delete` | `DeleteTagCommand` |
|
||||||
|
| `Get` | `GetTagQuery` |
|
||||||
|
| `GetAll` | `GetAllTagsQuery` |
|
||||||
|
| `GetProductsByTag` | `GetProductsByTagQuery` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ProductTagService.cs
|
||||||
|
**مسیر**: `BackOffice.BFF.WebApi/Services/ProductTagService.cs`
|
||||||
|
|
||||||
|
| RPC | Command/Query |
|
||||||
|
|-----|---------------|
|
||||||
|
| `CreateNewProductTag` | `CreateProductTagCommand` |
|
||||||
|
| `UpdateProductTag` | `UpdateProductTagCommand` |
|
||||||
|
| `DeleteProductTag` | `DeleteProductTagCommand` |
|
||||||
|
| `GetProductTag` | `GetProductTagQuery` |
|
||||||
|
| `GetAllProductTagByFilter` | `GetAllProductTagsQuery` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 تغییرات Application Layer
|
||||||
|
|
||||||
|
### Handlers جدید ایجاد شده
|
||||||
|
|
||||||
|
#### ProductTagCQ/Commands/UpdateProductTag/
|
||||||
|
- `UpdateProductTagCommand.cs`
|
||||||
|
- `UpdateProductTagCommandHandler.cs`
|
||||||
|
|
||||||
|
#### ProductTagCQ/Commands/DeleteProductTag/
|
||||||
|
- `DeleteProductTagCommand.cs`
|
||||||
|
- `DeleteProductTagCommandHandler.cs`
|
||||||
|
|
||||||
|
#### ProductTagCQ/Queries/GetProductTag/
|
||||||
|
- `GetProductTagQuery.cs`
|
||||||
|
- `GetProductTagQueryHandler.cs`
|
||||||
|
|
||||||
|
#### ProductTagCQ/Queries/GetAllProductTags/
|
||||||
|
- `GetAllProductTagsQuery.cs`
|
||||||
|
- `GetAllProductTagsQueryHandler.cs`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DiscountShoppingCartCQ - اصلاحات Proto
|
||||||
|
|
||||||
|
#### فایلهای تغییر یافته:
|
||||||
|
|
||||||
|
**RemoveFromCartCommand.cs**
|
||||||
|
```diff
|
||||||
|
- public long CartItemId { get; init; }
|
||||||
|
+ public long ProductId { get; init; }
|
||||||
|
```
|
||||||
|
|
||||||
|
**UpdateCartItemCountCommand.cs**
|
||||||
|
```diff
|
||||||
|
- public long CartItemId { get; init; }
|
||||||
|
+ public long ProductId { get; init; }
|
||||||
|
```
|
||||||
|
|
||||||
|
**GetUserCartResponseDto.cs**
|
||||||
|
```diff
|
||||||
|
- public long UserId { get; set; }
|
||||||
|
- public long TotalDiscountedPrice { get; set; }
|
||||||
|
- public long TotalSavings { get; set; }
|
||||||
|
+ public long TotalDiscountAmount { get; set; }
|
||||||
|
+ public long FinalPrice { get; set; }
|
||||||
|
```
|
||||||
|
|
||||||
|
**CartItemDto**
|
||||||
|
```diff
|
||||||
|
- public long Id { get; set; }
|
||||||
|
- public long DiscountedPrice { get; set; }
|
||||||
|
- public DateTime AddedAt { get; set; }
|
||||||
|
+ public long DiscountAmount { get; set; }
|
||||||
|
+ public long FinalPrice { get; set; }
|
||||||
|
+ public int ProductRemainingCount { get; set; }
|
||||||
|
+ public DateTime Created { get; set; }
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 تغییرات Proto Projects
|
||||||
|
|
||||||
|
### csproj تغییر یافته (GrpcServices: Client → Both)
|
||||||
|
- `BackOffice.BFF.DiscountCategory.Protobuf.csproj`
|
||||||
|
- `BackOffice.BFF.DiscountShoppingCart.Protobuf.csproj`
|
||||||
|
- `BackOffice.BFF.Tag.Protobuf.csproj`
|
||||||
|
- `BackOffice.BFF.ProductTag.Protobuf.csproj`
|
||||||
|
|
||||||
|
### WebApi.csproj - References اضافه شده
|
||||||
|
```xml
|
||||||
|
<ProjectReference Include="..\Protobufs\BackOffice.BFF.DiscountCategory.Protobuf\..." />
|
||||||
|
<ProjectReference Include="..\Protobufs\BackOffice.BFF.DiscountShoppingCart.Protobuf\..." />
|
||||||
|
<ProjectReference Include="..\Protobufs\BackOffice.BFF.Tag.Protobuf\..." />
|
||||||
|
<ProjectReference Include="..\Protobufs\BackOffice.BFF.ProductTag.Protobuf\..." />
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🗑️ Excludes حذف شده
|
||||||
|
|
||||||
|
### BackOffice.BFF.Application.csproj
|
||||||
|
```diff
|
||||||
|
- <Compile Remove="DiscountShoppingCartCQ/**/*.cs" />
|
||||||
|
+ <!-- All excluded handlers have been enabled -->
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 آمار نهایی
|
||||||
|
|
||||||
|
| متریک | مقدار |
|
||||||
|
|--------|-------|
|
||||||
|
| Services جدید | 4 |
|
||||||
|
| Handlers جدید | 8 |
|
||||||
|
| فایلهای اصلاح شده | 12 |
|
||||||
|
| Proto projects تنظیم شده | 4 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ نتیجه Build
|
||||||
|
|
||||||
|
```
|
||||||
|
Build succeeded.
|
||||||
|
177 Warning(s)
|
||||||
|
0 Error(s)
|
||||||
|
```
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
# 📝 Changelog - ۱۱ دی ۱۴۰۴ (31 December 2025)
|
||||||
|
|
||||||
|
> **Session**: Discount Shop Admin APIs Complete + BFF Layer Implementation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 خلاصه Session
|
||||||
|
|
||||||
|
این session شامل موارد زیر بود:
|
||||||
|
|
||||||
|
1. **Product Image Gallery** - گالری تصاویر محصولات فروشگاه تخفیفی (CMS + BFF)
|
||||||
|
2. **GetAllDiscountOrders API** - API مدیریت سفارشات فروشگاه تخفیفی برای ادمین
|
||||||
|
3. **VAT Calculation** - محاسبه مالیات بر ارزش افزوده
|
||||||
|
4. **Sales Reports API** - گزارشات فروش روزانه/هفتگی/ماهانه با تقویم فارسی
|
||||||
|
5. **BFF WebApi Services** - سرویسهای gRPC برای BackOffice.BFF
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ تغییرات
|
||||||
|
|
||||||
|
### 1. 🖼️ Product Image Gallery (Phase 1) ✅
|
||||||
|
|
||||||
|
**توضیح**: پشتیبانی از گالری تصاویر برای محصولات فروشگاه تخفیفی
|
||||||
|
|
||||||
|
**فایلهای CMS ایجاد شده**:
|
||||||
|
|
||||||
|
| فایل | توضیح |
|
||||||
|
|------|-------|
|
||||||
|
| `Domain/DiscountProduct/DiscountProductImage.cs` | Entity گالری تصویر |
|
||||||
|
| `Infrastructure/.../DiscountProductImageConfiguration.cs` | تنظیمات EF Core |
|
||||||
|
| `Application/.../AddDiscountProductImage/` | Command افزودن تصویر |
|
||||||
|
| `Application/.../UpdateDiscountProductImage/` | Command ویرایش تصویر |
|
||||||
|
| `Application/.../DeleteDiscountProductImage/` | Command حذف تصویر |
|
||||||
|
| `Application/.../ReorderDiscountProductImages/` | Command مرتبسازی تصاویر |
|
||||||
|
| `Application/.../GetDiscountProductImages/` | Query دریافت تصاویر |
|
||||||
|
|
||||||
|
**فایلهای BFF Application ایجاد شده**:
|
||||||
|
|
||||||
|
| فایل | توضیح |
|
||||||
|
|------|-------|
|
||||||
|
| `DiscountProductCQ/Commands/AddDiscountProductImage/` | Command + Handler |
|
||||||
|
| `DiscountProductCQ/Commands/UpdateDiscountProductImage/` | Command + Handler |
|
||||||
|
| `DiscountProductCQ/Commands/DeleteDiscountProductImage/` | Command + Handler |
|
||||||
|
| `DiscountProductCQ/Commands/ReorderDiscountProductImages/` | Command + Handler |
|
||||||
|
| `DiscountProductCQ/Queries/GetDiscountProductImages/` | Query + Handler |
|
||||||
|
|
||||||
|
**Entity Structure**:
|
||||||
|
```csharp
|
||||||
|
public class DiscountProductImage : BaseEntity<long>
|
||||||
|
{
|
||||||
|
public long DiscountProductId { get; set; }
|
||||||
|
public string ImagePath { get; set; }
|
||||||
|
public string? ThumbnailPath { get; set; }
|
||||||
|
public string? Title { get; set; }
|
||||||
|
public string? AltText { get; set; }
|
||||||
|
public int SortOrder { get; set; }
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. 📋 GetAllDiscountOrders Admin API (Phase 2) ✅
|
||||||
|
|
||||||
|
**توضیح**: API برای مدیریت تمام سفارشات فروشگاه تخفیفی توسط ادمین
|
||||||
|
|
||||||
|
**فیلترهای پشتیبانی شده**:
|
||||||
|
- `UserId` - فیلتر بر اساس کاربر
|
||||||
|
- `PaymentStatus` - وضعیت پرداخت (Pending/Success/Reject)
|
||||||
|
- `DeliveryStatus` - وضعیت ارسال
|
||||||
|
- `UserMobile` - جستجو بر اساس موبایل
|
||||||
|
- `TrackingCode` - کد رهگیری
|
||||||
|
- `FromDate` / `ToDate` - بازه زمانی
|
||||||
|
- `MinAmount` / `MaxAmount` - بازه مبلغ
|
||||||
|
|
||||||
|
**فایلهای CMS**:
|
||||||
|
- `Application/DiscountOrderCQ/Queries/GetAllDiscountOrders/`
|
||||||
|
- `WebApi/DiscountOrderService.cs` - افزودن RPC
|
||||||
|
|
||||||
|
**فایلهای BFF**:
|
||||||
|
- `Application/DiscountOrderCQ/Queries/GetAllDiscountOrders/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. 💵 VAT Calculation (Phase 3) ✅
|
||||||
|
|
||||||
|
**توضیح**: سرویس محاسبه مالیات بر ارزش افزوده (۱۰٪)
|
||||||
|
|
||||||
|
**فایلهای ایجاد شده**:
|
||||||
|
- `CMS/Application/Common/Services/VatCalculator.cs`
|
||||||
|
|
||||||
|
**متدها**:
|
||||||
|
```csharp
|
||||||
|
public class VatCalculator : IVatCalculator
|
||||||
|
{
|
||||||
|
public const decimal VatRate = 0.10m; // 10% VAT
|
||||||
|
|
||||||
|
public decimal CalculateVat(decimal amount);
|
||||||
|
public decimal CalculateTotalWithVat(decimal amount);
|
||||||
|
public decimal CalculateBaseFromTotal(decimal totalWithVat);
|
||||||
|
public (decimal baseAmount, decimal vatAmount, decimal total) CalculateBreakdown(decimal amount);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**یکپارچهسازی**: در `PlaceOrderCommandHandler` استفاده شده
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. 📊 Sales Reports API (Phase 4) ✅
|
||||||
|
|
||||||
|
**توضیح**: گزارشات فروش با پشتیبانی تقویم فارسی
|
||||||
|
|
||||||
|
**انواع گزارش**:
|
||||||
|
- `Summary` - خلاصه کلی
|
||||||
|
- `Daily` - روزانه
|
||||||
|
- `Weekly` - هفتگی
|
||||||
|
- `Monthly` - ماهانه
|
||||||
|
|
||||||
|
**فایلهای CMS**:
|
||||||
|
- `Application/DiscountOrderCQ/Queries/GetDiscountSalesReport/`
|
||||||
|
|
||||||
|
**فایلهای BFF**:
|
||||||
|
- `Application/DiscountOrderCQ/Queries/GetDiscountSalesReport/`
|
||||||
|
|
||||||
|
**Response Structure**:
|
||||||
|
```csharp
|
||||||
|
public class DiscountSalesReportDto
|
||||||
|
{
|
||||||
|
public SalesSummaryDto Summary { get; set; }
|
||||||
|
public List<PeriodSalesDto> Periods { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SalesSummaryDto
|
||||||
|
{
|
||||||
|
public int TotalOrders { get; set; }
|
||||||
|
public int SuccessfulOrders { get; set; }
|
||||||
|
public int PendingOrders { get; set; }
|
||||||
|
public int RejectedOrders { get; set; }
|
||||||
|
public decimal TotalRevenue { get; set; }
|
||||||
|
public decimal TotalDiscountUsed { get; set; }
|
||||||
|
public decimal TotalGatewayPayments { get; set; }
|
||||||
|
public decimal TotalVat { get; set; }
|
||||||
|
public int UniqueCustomers { get; set; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. 🔌 BFF WebApi gRPC Services (Phase 5) ✅
|
||||||
|
|
||||||
|
**توضیح**: سرویسهای gRPC در لایه WebApi برای expose کردن APIها
|
||||||
|
|
||||||
|
**فایلهای ایجاد شده**:
|
||||||
|
|
||||||
|
| فایل | توضیح |
|
||||||
|
|------|-------|
|
||||||
|
| `BackOffice.BFF.WebApi/Services/DiscountProductService.cs` | سرویس محصولات تخفیفی |
|
||||||
|
| `BackOffice.BFF.WebApi/Services/DiscountOrderService.cs` | سرویس سفارشات تخفیفی |
|
||||||
|
|
||||||
|
**تغییرات Proto Projects**:
|
||||||
|
```xml
|
||||||
|
<!-- Before -->
|
||||||
|
<Protobuf GrpcServices="Client" />
|
||||||
|
|
||||||
|
<!-- After -->
|
||||||
|
<Protobuf GrpcServices="Both" />
|
||||||
|
```
|
||||||
|
|
||||||
|
**فایلهای تغییر یافته**:
|
||||||
|
- `BackOffice.BFF.DiscountProduct.Protobuf.csproj`
|
||||||
|
- `BackOffice.BFF.DiscountOrder.Protobuf.csproj`
|
||||||
|
- `BackOffice.BFF.WebApi.csproj` - افزودن references
|
||||||
|
|
||||||
|
**DiscountProductService Endpoints**:
|
||||||
|
```csharp
|
||||||
|
// Product CRUD
|
||||||
|
CreateDiscountProduct
|
||||||
|
UpdateDiscountProduct
|
||||||
|
DeleteDiscountProduct
|
||||||
|
GetDiscountProductById
|
||||||
|
GetDiscountProducts
|
||||||
|
|
||||||
|
// Image Gallery (NEW)
|
||||||
|
AddDiscountProductImage
|
||||||
|
UpdateDiscountProductImage
|
||||||
|
DeleteDiscountProductImage
|
||||||
|
ReorderDiscountProductImages
|
||||||
|
GetDiscountProductImages
|
||||||
|
```
|
||||||
|
|
||||||
|
**DiscountOrderService Endpoints**:
|
||||||
|
```csharp
|
||||||
|
// Order Management
|
||||||
|
PlaceOrder
|
||||||
|
CompleteOrderPayment
|
||||||
|
UpdateOrderStatus
|
||||||
|
GetOrderById
|
||||||
|
GetUserOrders
|
||||||
|
|
||||||
|
// Admin APIs (NEW)
|
||||||
|
GetAllDiscountOrders
|
||||||
|
GetDiscountSalesReport
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 ساختار فایلهای جدید
|
||||||
|
|
||||||
|
```
|
||||||
|
CMS/src/
|
||||||
|
├── CMSMicroservice.Application/
|
||||||
|
│ ├── Common/Services/VatCalculator.cs
|
||||||
|
│ └── DiscountOrderCQ/Queries/
|
||||||
|
│ ├── GetAllDiscountOrders/
|
||||||
|
│ │ ├── GetAllDiscountOrdersQuery.cs
|
||||||
|
│ │ └── GetAllDiscountOrdersQueryHandler.cs
|
||||||
|
│ └── GetDiscountSalesReport/
|
||||||
|
│ ├── GetDiscountSalesReportQuery.cs
|
||||||
|
│ └── GetDiscountSalesReportQueryHandler.cs
|
||||||
|
├── CMSMicroservice.Domain/DiscountProduct/
|
||||||
|
│ └── DiscountProductImage.cs
|
||||||
|
├── CMSMicroservice.Infrastructure/.../
|
||||||
|
│ └── DiscountProductImageConfiguration.cs
|
||||||
|
└── CMSMicroservice.Protobuf/Protos/
|
||||||
|
├── discountproduct.proto (updated)
|
||||||
|
└── discountorder.proto (updated)
|
||||||
|
|
||||||
|
BackOffice.BFF/src/
|
||||||
|
├── BackOffice.BFF.Application/
|
||||||
|
│ ├── DiscountProductCQ/
|
||||||
|
│ │ ├── Commands/
|
||||||
|
│ │ │ ├── AddDiscountProductImage/
|
||||||
|
│ │ │ ├── UpdateDiscountProductImage/
|
||||||
|
│ │ │ ├── DeleteDiscountProductImage/
|
||||||
|
│ │ │ └── ReorderDiscountProductImages/
|
||||||
|
│ │ └── Queries/
|
||||||
|
│ │ └── GetDiscountProductImages/
|
||||||
|
│ └── DiscountOrderCQ/Queries/
|
||||||
|
│ ├── GetAllDiscountOrders/
|
||||||
|
│ └── GetDiscountSalesReport/
|
||||||
|
├── BackOffice.BFF.WebApi/Services/
|
||||||
|
│ ├── DiscountProductService.cs (NEW)
|
||||||
|
│ └── DiscountOrderService.cs (NEW)
|
||||||
|
└── Protobufs/
|
||||||
|
├── BackOffice.BFF.DiscountProduct.Protobuf/ (GrpcServices=Both)
|
||||||
|
└── BackOffice.BFF.DiscountOrder.Protobuf/ (GrpcServices=Both)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Build Status
|
||||||
|
|
||||||
|
| Project | Status |
|
||||||
|
|---------|--------|
|
||||||
|
| CMS Solution | ✅ Build Succeeded |
|
||||||
|
| BackOffice.BFF Solution | ✅ Build Succeeded |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔜 Next Steps
|
||||||
|
|
||||||
|
1. **BackOffice UI** - اتصال پنل ادمین به APIهای جدید
|
||||||
|
2. **FrontOffice.BFF** - پیادهسازی APIها برای فرانتآفیس (اگر نیاز باشد)
|
||||||
|
3. **Unit Tests** - نوشتن تستهای واحد
|
||||||
Reference in New Issue
Block a user