Watch
1
0
Fork
You've already forked Seyyed_arc
0
forked from hesabix/arc
Seyyed_arc/docs/PROJECTS_REPORTS_INTEGRATION_SCENARIO.md
2026-04-14 19:34:55 +03:30

840 lines
27 KiB
Markdown
Executable file
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 📊 سناریوی یکپارچه‌سازی فیلتر پروژه در گزارشات
## 🎯 هدف
افزودن فیلتر پروژه به تمام گزارشات مالی و عملیاتی سیستم برای امکان تحلیل داده‌ها بر اساس پروژه
---
## 📋 فهرست گزارشات نیازمند به‌روزرسانی
### 1️⃣ **گزارشات مالی (اولویت بالا)** 🔴
#### الف) گزارش دفتر کل (General Ledger)
- **فایل**: `general_ledger_report_page.dart`
- **API**: `/api/v1/reports/general-ledger`
- **اهمیت**: ⭐⭐⭐⭐⭐
- **دلیل**: نمایش تراکنش‌های هر حساب با تفکیک پروژه
#### ب) گزارش روزنامه (Journal Ledger)
- **فایل**: `journal_ledger_report_page.dart`
- **API**: `/api/v1/reports/journal-ledger`
- **اهمیت**: ⭐⭐⭐⭐⭐
- **دلیل**: نمایش کلیه اسناد روزانه با فیلتر پروژه
#### ج) گزارش تراز آزمایشی (Trial Balance)
- **فایل**: `trial_balance_report_page.dart`
- **API**: `/api/v1/reports/trial-balance`
- **اهمیت**: ⭐⭐⭐⭐
- **دلیل**: تراز حساب‌ها با محدود کردن به پروژه خاص
#### د) گزارش سود و زیان (P&L)
- **فایل‌ها**:
- `pnl_period_report_page.dart` (دوره‌ای)
- `pnl_cumulative_report_page.dart` (تجمعی)
- **API**: `/api/v1/reports/pnl`
- **اهمیت**: ⭐⭐⭐⭐⭐
- **دلیل**: تحلیل سودآوری هر پروژه
#### ه) گزارش تراکنش‌های اشخاص
- **فایل**: `people_transactions_report_page.dart`
- **API**: `/api/v1/reports/people-transactions`
- **اهمیت**: ⭐⭐⭐⭐
- **دلیل**: مشاهده تراکنش‌های مشتری/تامین‌کننده در پروژه خاص
#### و) گزارش بدهکاران
- **فایل**: `debtors_report_page.dart`
- **API**: `/api/v1/reports/debtors`
- **اهمیت**: ⭐⭐⭐⭐
- **دلیل**: مانده بدهکاری مشتریان در پروژه خاص
#### ز) گزارش بستانکاران
- **فایل**: `creditors_report_page.dart`
- **API**: `/api/v1/reports/creditors`
- **اهمیت**: ⭐⭐⭐⭐
- **دلیل**: مانده بستانکاری تامین‌کنندگان در پروژه خاص
### 2️⃣ **گزارشات فروش و خرید (اولویت متوسط)** 🟡
#### الف) گزارش فروش روزانه
- **فایل**: `daily_sales_report_page.dart`
- **API**: `/api/v1/reports/daily-sales`
- **اهمیت**: ⭐⭐⭐⭐
- **دلیل**: تحلیل فروش روزانه هر پروژه
#### ب) گزارش خرید روزانه
- **فایل**: `daily_purchases_report_page.dart`
- **API**: `/api/v1/reports/daily-purchases`
- **اهمیت**: ⭐⭐⭐⭐
- **دلیل**: تحلیل خرید روزانه هر پروژه
#### ج) گزارش فروش ماهانه
- **فایل**: `monthly_sales_report_page.dart`
- **API**: `/api/v1/reports/monthly-sales`
- **اهمیت**: ⭐⭐⭐
- **دلیل**: روند فروش ماهانه به تفکیک پروژه
#### د) فروش بر اساس محصول
- **فایل**: `sales_by_product_report_page.dart`
- **API**: `/api/v1/reports/sales-by-product`
- **اهمیت**: ⭐⭐⭐
- **دلیل**: محصولات پرفروش در هر پروژه
#### ه) برترین مشتریان
- **فایل**: `top_customers_report_page.dart`
- **API**: `/api/v1/reports/top-customers`
- **اهمیت**: ⭐⭐⭐
- **دلیل**: مشتریان VIP هر پروژه
#### و) برترین تامین‌کنندگان
- **فایل**: `top_suppliers_report_page.dart`
- **API**: `/api/v1/reports/top-suppliers`
- **اهمیت**: ⭐⭐⭐
- **دلیل**: تامین‌کنندگان اصلی هر پروژه
### 3️⃣ **گزارشات انبار و موجودی (اولویت پایین)** 🟢
#### الف) گزارش کاردکس
- **فایل**: `inventory_kardex_report_page.dart`
- **API**: `/api/v1/reports/kardex`
- **اهمیت**: ⭐⭐⭐
- **دلیل**: ردیابی موجودی محصولات در پروژه
#### ب) گزارش موجودی انبار
- **فایل**: `inventory_stock_report_page.dart`
- **API**: `/api/v1/reports/inventory-stock`
- **اهمیت**: ⭐⭐
- **دلیل**: موجودی فعلی با تفکیک پروژه
#### ج) گزارش تحرکات محصول
- **فایل**: `product_movement_history_report_page.dart`
- **API**: `/api/v1/reports/product-movements`
- **اهمیت**: ⭐⭐⭐
- **دلیل**: تحرکات محصول در پروژه خاص
#### د) گزارش انتقالات بین انبار
- **فایل**: `inter_warehouse_transfers_report_page.dart`
- **API**: `/api/v1/reports/warehouse-transfers`
- **اهمیت**: ⭐⭐
- **دلیل**: انتقالات مربوط به پروژه
### 4️⃣ **گزارشات بانکی و صندوق (اولویت متوسط)** 🟡
#### الف) گزارش گردش حساب بانکی
- **فایل**: `bank_accounts_turnover_report_page.dart`
- **API**: `/api/v1/reports/bank-turnover`
- **اهمیت**: ⭐⭐⭐⭐
- **دلیل**: گردش بانکی مرتبط با پروژه
#### ب) گزارش صندوق و تنخواه
- **فایل**: `cash_petty_turnover_report_page.dart`
- **API**: `/api/v1/reports/cash-turnover`
- **اهمیت**: ⭐⭐⭐⭐
- **دلیل**: تراکنش‌های نقدی پروژه
### 5️⃣ **گزارشات اقساط و چک (اولویت پایین)** 🟢
#### الف) گزارش اقساط
- **فایل**: `installments_report_page.dart`
- **API**: `/api/v1/reports/installments`
- **اهمیت**: ⭐⭐⭐
- **دلیل**: اقساط دریافتی/پرداختی پروژه
#### ب) گزارش اسناد در انتظار
- **فایل**: `pending_documents_report_page.dart`
- **API**: `/api/v1/reports/pending-documents`
- **اهمیت**: ⭐⭐
- **دلیل**: اسناد تایید نشده پروژه
---
## 🏗️ معماری یکپارچه‌سازی
### Backend Architecture
```
hesabixAPI/
├── app/
│ └── services/
│ └── reports/
│ ├── general_ledger_service.py
│ ├── journal_ledger_service.py
│ ├── trial_balance_service.py
│ ├── pnl_service.py
│ ├── people_transactions_service.py
│ ├── sales_reports_service.py
│ ├── inventory_reports_service.py
│ └── ... (سایر سرویس‌های گزارش)
│
└── adapters/
└── api/
└── v1/
└── reports/
├── financial_reports.py
├── sales_reports.py
├── inventory_reports.py
└── ... (سایر endpoint های گزارش)
```
### Frontend Architecture
```
hesabixUI/lib/
├── pages/
│ └── business/
│ ├── general_ledger_report_page.dart
│ ├── pnl_period_report_page.dart
│ └── ... (سایر صفحات گزارش)
│
└── widgets/
└── reports/
└── report_filters_widget.dart (جدید)
```
---
## 📝 سناریوی پیاده‌سازی گام به گام
### مرحله 1️⃣: Backend - به‌روزرسانی Query Services
#### الف) اضافه کردن پارامتر project_id به توابع
**مثال: سرویس دفتر کل**
```python
# hesabixAPI/app/services/general_ledger_service.py
def get_general_ledger(
db: Session,
business_id: int,
account_id: Optional[int] = None,
from_date: Optional[date] = None,
to_date: Optional[date] = None,
fiscal_year_id: Optional[int] = None,
project_id: Optional[int] = None, # 🆕 اضافه شده
skip: int = 0,
limit: int = 100
) -> Dict[str, Any]:
"""
دریافت گزارش دفتر کل با فیلتر پروژه
"""
query = db.query(DocumentLine).join(Document)
# فیلتر کسب‌وکار
query = query.filter(Document.business_id == business_id)
# فیلتر حساب
if account_id:
query = query.filter(DocumentLine.account_id == account_id)
# فیلتر تاریخ
if from_date:
query = query.filter(Document.document_date >= from_date)
if to_date:
query = query.filter(Document.document_date <= to_date)
# فیلتر سال مالی
if fiscal_year_id:
query = query.filter(Document.fiscal_year_id == fiscal_year_id)
# 🆕 فیلتر پروژه
if project_id:
query = query.filter(Document.project_id == project_id)
# اجرای query و برگرداندن نتایج
# ...
```
**مثال: سرویس سود و زیان**
```python
# hesabixAPI/app/services/pnl_service.py
def calculate_pnl(
db: Session,
business_id: int,
from_date: date,
to_date: date,
project_id: Optional[int] = None, # 🆕 اضافه شده
cumulative: bool = False
) -> Dict[str, Any]:
"""
محاسبه سود و زیان با فیلتر پروژه
"""
# Query پایه برای درآمدها
revenue_query = db.query(
func.sum(DocumentLine.credit - DocumentLine.debit)
).join(Document).join(Account).filter(
Document.business_id == business_id,
Document.document_date.between(from_date, to_date),
Account.code.like('4%') # حساب‌های درآمد
)
# 🆕 فیلتر پروژه برای درآمد
if project_id:
revenue_query = revenue_query.filter(Document.project_id == project_id)
total_revenue = revenue_query.scalar() or 0
# Query پایه برای هزینه‌ها
expense_query = db.query(
func.sum(DocumentLine.debit - DocumentLine.credit)
).join(Document).join(Account).filter(
Document.business_id == business_id,
Document.document_date.between(from_date, to_date),
Account.code.like('5%') # حساب‌های هزینه
)
# 🆕 فیلتر پروژه برای هزینه
if project_id:
expense_query = expense_query.filter(Document.project_id == project_id)
total_expense = expense_query.scalar() or 0
# محاسبه سود خالص
net_profit = total_revenue - total_expense
return {
'revenue': float(total_revenue),
'expense': float(total_expense),
'net_profit': float(net_profit),
'profit_margin': (net_profit / total_revenue * 100) if total_revenue > 0 else 0,
'project_id': project_id,
'from_date': from_date.isoformat(),
'to_date': to_date.isoformat(),
}
```
#### ب) به‌روزرسانی API Endpoints
```python
# hesabixAPI/adapters/api/v1/reports/financial_reports.py
@router.get("/businesses/{business_id}/reports/general-ledger")
async def general_ledger_report(
business_id: int = Path(...),
account_id: Optional[int] = Query(None),
from_date: Optional[date] = Query(None),
to_date: Optional[date] = Query(None),
fiscal_year_id: Optional[int] = Query(None),
project_id: Optional[int] = Query(None), # 🆕 اضافه شده
skip: int = Query(0, ge=0),
limit: int = Query(100, ge=1, le=500),
db: Session = Depends(get_db),
ctx: AuthContext = Depends(get_current_user)
):
"""
گزارش دفتر کل با فیلتر پروژه
"""
result = get_general_ledger(
db=db,
business_id=business_id,
account_id=account_id,
from_date=from_date,
to_date=to_date,
fiscal_year_id=fiscal_year_id,
project_id=project_id, # 🆕 پاس دادن به سرویس
skip=skip,
limit=limit
)
return success_response(data=result, message="GENERAL_LEDGER_FETCHED")
```
### مرحله 2️⃣: Frontend - ایجاد Widget فیلتر مشترک
```dart
// lib/widgets/reports/report_filters_widget.dart
import 'package:flutter/material.dart';
import 'package:hesabix_ui/core/api_client.dart';
import 'package:hesabix_ui/core/calendar_controller.dart';
import 'package:hesabix_ui/widgets/project/project_selector_widget.dart';
import 'package:hesabix_ui/widgets/date_input_field.dart';
/// ویجت فیلترهای مشترک گزارشات
class ReportFiltersWidget extends StatelessWidget {
final int businessId;
final ApiClient apiClient;
final CalendarController calendarController;
// فیلترهای تاریخ
final DateTime? fromDate;
final DateTime? toDate;
final Function(DateTime?) onFromDateChanged;
final Function(DateTime?) onToDateChanged;
// فیلتر پروژه
final int? selectedProjectId;
final Function(int?) onProjectChanged;
// فیلترهای اختیاری
final int? selectedFiscalYearId;
final Function(int?)? onFiscalYearChanged;
final List<Map<String, dynamic>>? fiscalYears;
final bool showProjectFilter;
final bool showDateFilters;
final bool showFiscalYearFilter;
const ReportFiltersWidget({
Key? key,
required this.businessId,
required this.apiClient,
required this.calendarController,
required this.fromDate,
required this.toDate,
required this.onFromDateChanged,
required this.onToDateChanged,
required this.selectedProjectId,
required this.onProjectChanged,
this.selectedFiscalYearId,
this.onFiscalYearChanged,
this.fiscalYears,
this.showProjectFilter = true,
this.showDateFilters = true,
this.showFiscalYearFilter = true,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: Wrap(
spacing: 16,
runSpacing: 16,
children: [
// فیلتر تاریخ از
if (showDateFilters)
SizedBox(
width: 200,
child: DateInputField(
value: fromDate,
calendarController: calendarController,
onChanged: onFromDateChanged,
labelText: 'از تاریخ',
hintText: 'انتخاب تاریخ',
),
),
// فیلتر تاریخ تا
if (showDateFilters)
SizedBox(
width: 200,
child: DateInputField(
value: toDate,
calendarController: calendarController,
onChanged: onToDateChanged,
labelText: 'تا تاریخ',
hintText: 'انتخاب تاریخ',
),
),
// فیلتر سال مالی
if (showFiscalYearFilter && fiscalYears != null && fiscalYears!.isNotEmpty)
SizedBox(
width: 200,
child: DropdownButtonFormField<int>(
value: selectedFiscalYearId,
decoration: const InputDecoration(
labelText: 'سال مالی',
border: OutlineInputBorder(),
),
items: fiscalYears!.map((fy) {
return DropdownMenuItem<int>(
value: fy['id'] as int,
child: Text(fy['title'] as String),
);
}).toList(),
onChanged: onFiscalYearChanged,
),
),
// 🆕 فیلتر پروژه
if (showProjectFilter)
SizedBox(
width: 250,
child: ProjectSelectorWidget(
businessId: businessId,
apiClient: apiClient,
selectedProjectId: selectedProjectId,
onChanged: onProjectChanged,
allowNull: true,
labelText: 'پروژه (همه)',
),
),
],
),
);
}
}
```
### مرحله 3️⃣: Frontend - به‌روزرسانی صفحات گزارش
**مثال: گزارش دفتر کل**
```dart
// lib/pages/business/general_ledger_report_page.dart
class _GeneralLedgerReportPageState extends State<GeneralLedgerReportPage> {
DateTime? _fromDate;
DateTime? _toDate;
int? _selectedAccountId;
int? _selectedFiscalYearId;
int? _selectedProjectId; // 🆕 اضافه شده
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('گزارش دفتر کل')),
body: Column(
children: [
// 🆕 استفاده از ویجت فیلتر مشترک
ReportFiltersWidget(
businessId: widget.businessId,
apiClient: widget.apiClient,
calendarController: widget.calendarController,
fromDate: _fromDate,
toDate: _toDate,
onFromDateChanged: (date) {
setState(() => _fromDate = date);
_loadReport();
},
onToDateChanged: (date) {
setState(() => _toDate = date);
_loadReport();
},
selectedProjectId: _selectedProjectId,
onProjectChanged: (projectId) {
setState(() => _selectedProjectId = projectId);
_loadReport();
},
selectedFiscalYearId: _selectedFiscalYearId,
onFiscalYearChanged: (fyId) {
setState(() => _selectedFiscalYearId = fyId);
_loadReport();
},
fiscalYears: _fiscalYears,
),
// نمایش گزارش
Expanded(
child: _buildReportContent(),
),
],
),
);
}
Future<void> _loadReport() async {
final queryParams = <String, dynamic>{
'from_date': _fromDate?.toIso8601String(),
'to_date': _toDate?.toIso8601String(),
'fiscal_year_id': _selectedFiscalYearId,
'project_id': _selectedProjectId, // 🆕 پاس دادن به API
};
// فراخوانی API
final response = await widget.apiClient.get(
'/api/v1/businesses/${widget.businessId}/reports/general-ledger',
queryParameters: queryParams,
);
// پردازش و نمایش نتایج
// ...
}
}
```
---
## 🎨 نمایش بصری فیلتر پروژه در گزارشات
### قبل از پیاده‌سازی:
```
┌─────────────────────────────────────────┐
│ گزارش دفتر کل │
├─────────────────────────────────────────┤
│ از تاریخ: [____] تا تاریخ: [____] │
│ سال مالی: [__________▼] │
├─────────────────────────────────────────┤
│ [جدول داده‌ها] │
└─────────────────────────────────────────┘
```
### بعد از پیاده‌سازی:
```
┌─────────────────────────────────────────┐
│ گزارش دفتر کل │
├─────────────────────────────────────────┤
│ از تاریخ: [____] تا تاریخ: [____] │
│ سال مالی: [__________▼] │
│ 🆕 پروژه: [همه پروژه‌ها____▼] │
├─────────────────────────────────────────┤
│ [جدول داده‌ها - فیلتر شده با پروژه] │
└─────────────────────────────────────────┘
```
---
## 📊 مثال‌های کاربردی
### مثال 1: گزارش سود و زیان یک پروژه
**سناریو**: مدیر می‌خواهد سودآوری پروژه "ساخت ساختمان A" را ببیند
**درخواست**:
```http
GET /api/v1/businesses/1/reports/pnl?
from_date=2025-01-01&
to_date=2025-03-31&
project_id=5
```
**پاسخ**:
```json
{
"success": true,
"data": {
"project": {
"id": 5,
"code": "PRJ-001",
"name": "ساخت ساختمان A"
},
"period": {
"from": "2025-01-01",
"to": "2025-03-31"
},
"revenue": {
"total": 500000000,
"breakdown": {
"sales": 450000000,
"other_income": 50000000
}
},
"expenses": {
"total": 350000000,
"breakdown": {
"materials": 200000000,
"labor": 100000000,
"overhead": 50000000
}
},
"net_profit": 150000000,
"profit_margin": 30.0
}
}
```
### مثال 2: مقایسه عملکرد چند پروژه
**UI**: نمودار مقایسه‌ای
```
سودآوری پروژه‌ها (فروردین 1404)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
پروژه A ████████████░░ 80% سود: 150M
پروژه B ███████░░░░░░ 45% سود: 90M
پروژه C ██████████████ 95% سود: 200M
همه ████████████░░ 73% سود: 440M
```
---
## 🔄 فلوچارت تصمیم‌گیری
```
شروع گزارش
↓
آیا فیلتر پروژه انتخاب شده؟
├─ بله → Query با شرط project_id
│ ↓
│ داده‌های فیلتر شده
│ ↓
│ نمایش عنوان "گزارش پروژه: [نام]"
│
└─ خیر → Query بدون شرط پروژه
↓
همه داده‌ها
↓
نمایش عنوان "گزارش کلی"
↓
نمایش نتایج
↓
پایان
```
---
## ⚡ بهینه‌سازی عملکرد
### 1. Caching نتایج گزارش
```python
from app.core.cache import get_cache
def get_pnl_report_cached(business_id, from_date, to_date, project_id):
cache = get_cache()
cache_key = f"pnl:{business_id}:{from_date}:{to_date}:{project_id or 'all'}"
# بررسی cache
cached_data = cache.get(cache_key)
if cached_data:
return cached_data
# محاسبه گزارش
report_data = calculate_pnl(...)
# ذخیره در cache (1 ساعت)
cache.set(cache_key, report_data, ttl=3600)
return report_data
```
### 2. Index بر روی project_id
```sql
-- بهینه‌سازی query های گزارش
CREATE INDEX idx_documents_project_date
ON documents(project_id, document_date);
CREATE INDEX idx_documents_project_fiscal
ON documents(project_id, fiscal_year_id);
```
### 3. Materialized Views برای گزارشات پرکاربرد
```sql
-- View گزارش سود و زیان به تفکیک پروژه
CREATE MATERIALIZED VIEW mv_pnl_by_project AS
SELECT
d.project_id,
p.name as project_name,
DATE_FORMAT(d.document_date, '%Y-%m') as month,
SUM(CASE WHEN a.code LIKE '4%' THEN dl.credit - dl.debit ELSE 0 END) as revenue,
SUM(CASE WHEN a.code LIKE '5%' THEN dl.debit - dl.credit ELSE 0 END) as expense
FROM documents d
JOIN document_lines dl ON d.id = dl.document_id
JOIN accounts a ON dl.account_id = a.id
LEFT JOIN projects p ON d.project_id = p.id
GROUP BY d.project_id, p.name, DATE_FORMAT(d.document_date, '%Y-%m');
-- Refresh هر شب
REFRESH MATERIALIZED VIEW mv_pnl_by_project;
```
---
## 📱 نمونه UI/UX
### Card گزارش با فیلتر پروژه
```dart
Card(
child: Column(
children: [
// هدر با نام پروژه
if (_selectedProjectId != null)
Container(
padding: EdgeInsets.all(12),
color: Colors.blue.shade50,
child: Row(
children: [
Icon(Icons.folder_special, color: Colors.blue),
SizedBox(width: 8),
Text(
'گزارش پروژه: $_selectedProjectName',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
],
),
),
// محتوای گزارش
Padding(
padding: EdgeInsets.all(16),
child: _buildReportContent(),
),
],
),
)
```
---
## ✅ چک‌لیست پیاده‌سازی
### Backend
- [ ] به‌روزرسانی سرویس دفتر کل
- [ ] به‌روزرسانی سرویس روزنامه
- [ ] به‌روزرسانی سرویس تراز
- [ ] به‌روزرسانی سرویس سود و زیان
- [ ] به‌روزرسانی سرویس تراکنش‌های اشخاص
- [ ] به‌روزرسانی سرویس فروش
- [ ] به‌روزرسانی API endpoints گزارشات
- [ ] افزودن Index های بهینه‌ساز
- [ ] تست performance با داده‌های زیاد
### Frontend
- [ ] ایجاد `ReportFiltersWidget`
- [ ] به‌روزرسانی صفحه دفتر کل
- [ ] به‌روزرسانی صفحه سود و زیان
- [ ] به‌روزرسانی صفحه تراز
- [ ] به‌روزرسانی سایر گزارشات مالی
- [ ] به‌روزرسانی گزارشات فروش
- [ ] تست UX در موبایل و دسکتاپ
### Documentation
- [ ] به‌روزرسانی Swagger با پارامتر project_id
- [ ] راهنمای کاربری فیلتر پروژه در گزارشات
- [ ] نمونه‌های API در مستندات
---
## 🎯 اولویت‌بندی پیاده‌سازی
### فاز 1 (فوری - 1 هفته)
1. گزارش دفتر کل ⭐⭐⭐⭐⭐
2. گزارش روزنامه ⭐⭐⭐⭐⭐
3. گزارش سود و زیان ⭐⭐⭐⭐⭐
4. گزارش تراکنش‌های اشخاص ⭐⭐⭐⭐
### فاز 2 (مهم - 1 هفته)
5. گزارش تراز آزمایشی ⭐⭐⭐⭐
6. گزارش فروش روزانه ⭐⭐⭐⭐
7. گزارش گردش بانک ⭐⭐⭐⭐
8. گزارش بدهکاران/بستانکاران ⭐⭐⭐⭐
### فاز 3 (عادی - 1 هفته)
9. سایر گزارشات فروش ⭐⭐⭐
10. گزارشات انبار ⭐⭐⭐
11. گزارشات اقساط ⭐⭐
---
## 💡 نکات کلیدی
1. **سازگاری با گذشته**: فیلتر پروژه اختیاری است و عدم انتخاب آن به معنی "همه پروژه‌ها" است
2. **عملکرد**: استفاده از Index و Cache برای گزارشات پرکاربرد
3. **UI/UX**: نمایش واضح نام پروژه در هدر گزارش
4. **Export**: فایل‌های Excel/PDF خروجی باید نام پروژه را داشته باشند
5. **مقایسه**: امکان مشاهده همزمان چند پروژه در یک گزارش
---
**تاریخ**: دسامبر 2025
**نسخه**: 1.0
**وضعیت**: آماده پیاده‌سازی 🚀