22 KiB
مستند کامل سامانه حسابداری FunZone
این سند توضیح میدهد اعداد و شمارهها چطور ساخته میشوند، و هر بخش منو چطور به بقیه وصل است — از داشبورد تا تنظیمات.
۱. نمای کلی معماری
| لایه | تکنولوژی | آدرس تقریبی |
|---|---|---|
| فرانتاند حسابداری | React + TypeScript + Vite | اپ funzone-accounting |
| API حسابداری | Django REST | معمولاً localhost:8010/api |
| API اصلی FunZone | Django (مشتری، پرداخت، مالک، رویداد) | معمولاً localhost:8000/api |
منبع حقیقت دادهها: AppStore همه موجودیتها را از API حسابداری بارگذاری میکند و CRUD را از همانجا انجام میدهد. همگامسازی با FunZone (بلیت، کیف پول، برداشت) از API اصلی میخواند و در دفتر حسابداری ثبت میکند.
┌─────────────────┐ همگامسازی ┌──────────────────────┐
│ FunZone API │ ──────────────────► │ Accounting Frontend │
│ پرداخت/کیفپول │ │ AppStore + صفحات │
└─────────────────┘ └──────────┬───────────┘
│ REST
▼
┌──────────────────────┐
│ Accounting Backend │
│ جداول دفتر / شماره سند│
└──────────────────────┘
۲. ساختار منو و مسیرها
| گروه | برچسب منو | مسیر | صفحه اصلی |
|---|---|---|---|
| اصلی | داشبورد | / |
Dashboard.tsx |
| حسابداری | حسابها (کدینگ) | /accounts |
Accounts.tsx |
| حسابداری | اسناد حسابداری | /vouchers |
Vouchers.tsx |
| عملیات | مشتریان و فروش | /sales/* |
Sales.tsx + زیرصفحات |
| عملیات | تأمینکنندگان و خرید | /purchases/* |
Purchases.tsx |
| عملیات | انبارداری | /inventory |
Inventory.tsx |
| عملیات | دریافت و پرداخت | /treasury |
Treasury.tsx |
| عملیات | حقوق و دستمزد | /payroll |
Payroll.tsx |
| تحلیل | گزارشها | /reports |
Reports.tsx |
| سیستم | تنظیمات | /settings |
Settings.tsx |
زیرمنوی فروش
| مسیر | نقش |
|---|---|
/sales |
فرایند فروش |
/sales/proforma |
پیشفاکتور |
/sales/invoice |
فاکتور فروش |
/sales/return |
برداشتها و لغو شده |
/sales/adjustments |
اعلامیه بدهکار/بستانکار |
/sales/sales-types |
نوع فروش |
/sales/customers |
مشتریان |
/sales/review |
مرور فروش |
تعریف منو: src/components/layout/navigation.ts
۳. تولید اعداد و شمارهها (قلب سیستم)
۳.۱ الگوریتم مشترک فرانتاند
فایل: src/utils/id.ts
// شناسه موقت کلاینت (قبل از UUID سرور)
createId(prefix) → مثلاً "v-" + زمان + تصادفی
// شماره ترتیبی سند/فاکتور/…
nextNumber(items) → max(item.number) + 1
نکات مهم:
- هیچ جدول Sequence / سری شمارهگذاری جدا در دیتابیس نیست.
- سال مالی (
fiscalYear) فقط نمایشی است و شمارهها را ریست یا جدا نمیکند. - برای بیشتر اسناد، شماره را کلاینت با
nextNumberروی لیست فیلترشده میسازد و سرور همان عدد را ذخیره میکند. - استثنا: شماره سند حسابداری (
Voucher.number) — سرور شماره کلاینت را نادیده میگیرد و خودش اختصاص میدهد.
۳.۲ ماتریس شمارهگذاری
| نوع سند | فیلد | محدوده سری | کی میسازد؟ | فایل / منطق |
|---|---|---|---|---|
| سند حسابداری | number |
همه اسناد | سرور (_next_number + قفل ردیف) |
serializers.py |
| پیشفاکتور فروش | number |
فقط documentType=proforma و kind=sale |
کلاینت | SalesDocumentSection |
| فاکتور فروش | number |
فقط documentType=invoice و kind=sale |
کلاینت | SalesDocumentSection + سینک FunZone |
| فاکتور خرید | number |
همه kind=purchase |
کلاینت | TradeModule |
| دریافت | number |
فقط kind=receipt |
کلاینت | Treasury.tsx / سینک خزانه |
| پرداخت | number |
فقط kind=payment |
کلاینت | Treasury.tsx / سینک |
| برداشت کیف پول | number |
کل لیست treasury (نه فقط payment) |
کلاینت | withdrawalTreasury.ts |
| اعلامیه بدهکار/بستانکار | number |
همه اعلامیهها | کلاینت | PartyAdjustmentsPage |
| کد حساب | code |
دستی / یکتا در DB | کاربر | Accounts.tsx + seed |
| کد کالا / نوع فروش / پرسنل | code |
دستی | کاربر | بدون auto |
| فیش حقوقی | — | ندارد | — | با id و period |
۳.۳ شماره سند حسابداری (تنها شماره قطعی سمت سرور)
در funzone-accounting-backend/accounting/serializers.py:
- فیلد
numberدرVoucherSerializerread-only است. - هنگام
create، سرور باselect_for_updateآخرین شماره را میگیرد و+1میکند. - بعد از ایجاد، شماره تغییر نمیکند (
updateفیلدnumberرا حذف میکند). - اگر سندی با
number <= 0باشد، در update میتواند شماره بگیرد.
فرانت قبل از POST ممکن است شماره موقت با nextNumber(data.vouchers) نشان دهد؛ بعد از ذخیره، شماره واقعی همانی است که سرور برمیگرداند.
۳.۴ شناسههای داخلی (createId)
| پیشوند | موجودیت |
|---|---|
v- |
سند |
vl- |
سطر سند |
inv- |
فاکتور |
il- |
سطر فاکتور |
tr- |
دریافت/پرداخت |
acc- |
حساب |
prod- |
کالا |
party- |
طرفحساب |
st- |
نوع فروش |
adj- |
اعلامیه |
emp- |
کارمند |
ps- |
فیش حقوقی |
اینها شناسه موقت UI هستند؛ بعد از ایجاد در بکاند معمولاً با UUID سرور جایگزین میشوند.
۳.۵ تگهای پایدار source (برای جلوگیری از دوبارهثبتی)
| الگو | معنی |
|---|---|
invoice:{uuid} |
فاکتور دستی |
funzone:invoice:{paymentId} |
سند بلیت درگاه |
funzone:invoice:wallet:{paymentId} |
سند بلیت از کیف پول |
adjustment:{id} |
اعلامیه |
treasury:{id} |
خزانه دستی |
funzone:cust-pay:{id} |
پرداخت مشتری (قدیمی/خزانه) |
funzone:wallet-pay:{id} |
تراکنش کیف پول |
funzone:owner-txn:{id} |
تراکنش مالک |
withdrawal:{id} |
برداشت IBAN |
فایل کلیدی لینک بلیت↔خزانه: src/pages/sales/funzoneVoucherLink.ts
منبع حقیقت تقسیم کارمزد بلیت = سند فاکتور فروش؛ اگر سند خزانه تکراری برای همان پرداخت بماند، حذف میشود.
۴. کدینگ حسابها و نقش هر کد
حسابهای پیشفرض از seeding.py (نمونه مهمها):
| کد | نام | نقش در سیستم |
|---|---|---|
| 1001 | صندوق | نقدینگی داشبورد |
| 1002 | بانک ملت | بدهکار/بستانکار نقد در اسناد خودکار |
| 1003 | بانک سامان | نقدینگی |
| 1004 | دریافتنی مشتریان | فروش عادی، اعلامیه، تسویه خزانه |
| 1005 | موجودی کالا | فاکتور خرید |
| 2001 | پرداختنی تأمینکنندگان | خرید |
| 2002 | مالیات پرداختنی | ۱۰٪ بلیت FunZone |
| 2003 / 2004 | حقوق / بیمه | در کدینگ هست؛ حقوق هنوز سند نمیزند |
| 2005 | بدهی به مالکان (کیف پول) | ۷۶٪ سهم مالک |
| 2006 | بدهی به مشتریان (کیف پول) | شارژ/برداشت/بلیت از کیف |
| 4001 | درآمد فروش | فروش عادی + ۱۴٪ سود پلتفرم |
| 5002 | هزینه حقوق | رزرو شده؛ Payroll وصل نیست |
| 5007 | سهم مالکان | در تنظیمات مپ شده؛ مسیر فعلی بلیت بیشتر از 2005/4001/2002 استفاده میکند |
تنظیمات نگاشت حسابها (Settings → voucherAccounts): بانک، بدهی مالک، بدهی مشتری، سهم مالک، درآمد فروش.
بدون کدینگ درست، buildSalesVoucher / buildPurchaseVoucher / buildTreasuryVoucher سند نمیسازند (null).
۵. فلوچارت اتصال ماژولها
۵.۱ نمای کلی ارتباطات
flowchart TB
subgraph سیستم["سیستم"]
SET[تنظیمات<br/>نگاشت حسابها / سال مالی نمایشی]
end
subgraph حسابداری["حسابداری"]
ACC[حسابها / کدینگ]
VOC[اسناد حسابداری]
end
subgraph عملیات["عملیات"]
SAL[مشتریان و فروش]
PUR[تأمینکنندگان و خرید]
INV[انبارداری]
TRE[دریافت و پرداخت]
PAY[حقوق و دستمزد]
end
subgraph تحلیل["تحلیل"]
REP[گزارشها]
DAS[داشبورد]
end
subgraph خارجی["خارج از اپ"]
FZ[FunZone API]
end
SET --> ACC
SET --> SAL
SET --> TRE
ACC --> VOC
ACC --> SAL
ACC --> PUR
ACC --> TRE
FZ -->|سینک طرفحساب| SAL
FZ -->|سینک بلیت / لغو| SAL
FZ -->|شارژ کیف / پرداخت مالک| TRE
FZ -->|رویداد / رزرو| INV
SAL -->|buildSalesVoucher + موجودی| VOC
SAL -->|اعلامیه| VOC
PUR -->|buildPurchaseVoucher + موجودی| VOC
PUR -->|افزایش stock| INV
SAL -->|کاهش stock| INV
TRE -->|buildTreasuryVoucher + تسویه فاکتور| VOC
TRE -->|reconcile paid/confirmed| SAL
PAY -.->|فعلاً بدون سند| VOC
VOC --> REP
VOC --> DAS
SAL --> DAS
PUR --> DAS
INV --> DAS
TRE --> DAS
۵.۲ جریان تولید سند از عملیات
flowchart LR
A[عملیات کاربر یا سینک FunZone] --> B{نوع؟}
B -->|فاکتور فروش/خرید| C[ذخیره Invoice]
B -->|دریافت/پرداخت| D[ذخیره TreasuryTxn]
B -->|اعلامیه| E[ذخیره PartyAdjustment]
B -->|سند دستی| F[Vouchers UI]
C --> G[invoiceSideEffects]
G --> H[تغییر موجودی کالا]
G --> I[buildInvoiceVoucher]
D --> J[buildTreasuryVoucher]
D --> K[reconcileInvoicePaymentStatus]
E --> L[buildAdjustmentVoucher]
F --> M[createDraft + nextNumber کلاینت]
I --> N[POST سند]
J --> N
L --> N
M --> N
N --> O[سرور: شماره قطعی Voucher]
O --> P[دفتر کل / تراز / داشبورد / گزارش]
۵.۳ جریان بلیت FunZone (تقسیم مبالغ)
برای مبلغ ناخالص G:
| جزء | نرخ | حساب بستانکار معمول |
|---|---|---|
| مالیات | ۱۰٪ | 2002 |
| سود پلتفرم | ۱۴٪ | 4001 |
| سهم مالک | ۷۶٪ (باقیمانده) | 2005 |
بدهکار:
- درگاه: 1002 بانک
- کیف پول مشتری: 2006
تابع: splitEventPayment در src/utils/funzoneFees.ts
سند: buildSalesVoucher وقتی note شامل funzone:pay: است.
flowchart TB
P[پرداخت بلیت در FunZone] --> S[funzoneSalesSync]
S --> I[فاکتور فروش status=paid]
I --> V[سند با source=funzone:invoice:…]
V --> L1[بدهکار بانک یا کیف 2006]
V --> L2[بستانکار مالک 2005]
V --> L3[بستانکار درآمد 4001]
V --> L4[بستانکار مالیات 2002]
T[سند خزانه تکراری همان پرداخت] -.->|حذف توسط funzoneVoucherLink| X[حذف]
۵.۴ ترتیب همگامسازی یکپارچه
unifiedVoucherSync.ts:
- سینک خزانه از FunZone (شارژ کیف، تراکنش مالک، …)
- سینک فاکتورهای فروش بلیت + ثبت سند فاکتور
- حذف اسناد تکراری / منسوخ (
supersededVoucherIds+ لینک بلیت)
۶. جزئیات هر بخش منو
۶.۱ داشبورد
میخواند از: اسناد posted، فاکتورها، موجودی کالا، حسابهای نقدی.
نمایش تقریبی:
- نقدینگی (کدهای 1001–1003)
- جمع فروش / خرید از فاکتورها
- سود و زیان و تراز از
trialBalanceروی اسناد - موجودی کم / فاکتورهای تسویهنشده
- نمودار چندماهه
تولید عدد: خودش شماره سند نمیسازد؛ فقط تجمیع میکند.
۶.۲ حسابها (کدینگ)
نقش: درخت حسابها (parentId)، مانده افتتاحیه، نوع (دارایی/بدهی/درآمد/هزینه).
اتصال: پایه همه سطرهای سند (VoucherLine.accountId). بدون حسابهای اجباری، اسناد خودکار ساخته نمیشوند.
شماره: کد حساب دستی و یکتا — بدون nextNumber.
۶.۳ اسناد حسابداری
ورودیها:
| منبع | چگونه |
|---|---|
| دستی در همین صفحه | پیشنویس + ثبت |
| فروش | buildSalesVoucher |
| خرید | buildPurchaseVoucher |
| خزانه | buildTreasuryVoucher |
| اعلامیه | buildAdjustmentVoucher |
| دکمه همگام FunZone | unifiedVoucherSync |
شماره: سرور قطعی میکند.
وضعیت: draft | posted — گزارشها معمولاً روی posted (منهای اسناد حذفشده/منسوخ).
۶.۴ مشتریان و فروش
موجودیتها: Party (مشتری)، Invoice فروش، نوع فروش، اعلامیه، سینک FunZone.
| عمل | اثر حسابداری | اثر انبار |
|---|---|---|
| پیشفاکتور | بدون سند | معمولاً بدون تغییر قطعی موجودی مسیر اصلی سند |
| فاکتور فروش عادی confirmed | بدهکار 1004 / بستانکار درآمد | کاهش stock |
| بلیت FunZone | تقسیم ۱۰/۱۴/۷۶ | — |
| لغو بلیت درگاه | بانک بدهکار / 2006 بستانکار | — |
| لغو بلیت کیف پول | حذف/بازگردانی سند قبلی | — |
| اعلامیه بدهکار | ↑ مطالبات / ↑ درآمد | — |
| اعلامیه بستانکار | عکس بالا | — |
شماره فاکتور: سری جدا برای پیشفاکتور و فاکتور (nextNumber روی همان documentType).
تسویه: خزانه با reconcileInvoicePaymentStatus به صورت FIFO وضعیت confirmed ↔ paid را عوض میکند (بلیتهای FunZone prepaid میمانند).
۶.۵ تأمینکنندگان و خرید
موجودیتها: Party (supplier)، Invoice خرید.
سند خودکار (confirmed):
- بدهکار 1005 موجودی
- بستانکار 2001 پرداختنی
شماره: یک سری برای همه فاکتورهای خرید.
اتصال به خزانه: پرداخت به تأمینکننده از ماژول دریافت/پرداخت؛ تسویه فاکتور خرید از همان منطق reconcile.
۶.۶ انبارداری
دو لایه:
- موجودی کالا در حسابداری — فیلد
Product.stock؛ با تأیید فاکتور خرید/فروش عوض میشود (applyStockChanges/stockDeltas). - نمای عملیاتی FunZone — رویداد/رزرو زنده (
funzoneInventory.ts)؛ سند حسابداری نمیزند.
یعنی انبار «دفتر انبار جدا» ندارد؛ موجودی از فاکتورها مشتق میشود + نمای FunZone برای عملیات.
۶.۷ دریافت و پرداخت (خزانه)
| نوع تراکنش | سند تقریبی |
|---|---|
| شارژ کیف پول مشتری | بدهکار بانک / بستانکار 2006 |
| برداشت کیف پول | بدهکار 2006 / بستانکار بانک |
| دریافت عادی از مشتری | بدهکار بانک / بستانکار 1004 |
| پرداخت به تأمینکننده/مالک | بدهکار 2005 یا 2001 / بستانکار بانک |
| مسیر قدیمی split روی خزانه | همان ۱۰/۱۴/۷۶ (امروز ترجیح با سند فاکتور بلیت است) |
شماره: دریافت و پرداخت سری جدا در UI؛ مسیر برداشت ممکن است از nextNumber روی کل خزانه استفاده کند.
۶.۸ حقوق و دستمزد
CRUD کارمند و فیش حقوقی.
اتصال به اسناد: فعلاً وجود ندارد. حسابهای 2003/2004/5002 در کدینگ آماده هستند ولی Payroll سند ثبت نمیکند.
۶.۹ گزارشها
از توابع src/utils/accounting.ts:
- تراز آزمایشی (
trialBalance) - دفتر حساب (
accountLedger) - سود و زیان (
incomeStatement) - ترازنامه (
balanceSheet)
ورودی: حسابها (مانده افتتاحیه) + اسناد posted (فیلتر اسناد منسوخ).
۶.۱۰ تنظیمات
- اطلاعات شرکت و سال مالی نمایشی
- نگاشت حسابهای پیشفرض اسناد خودکار
- ریست/seed دادهها (در صورت فعال بودن در UI)
بدون نگاشت درست، زنجیره فروش/خزانه/بلیت میشکند.
۷. موجودیتها و روابط
Account (درخت)
└── VoucherLine.accountId → Voucher
Party (customer | supplier ، گاهی externalId از FunZone)
├── Invoice.partyId
├── PartyAdjustment.partyId
└── TreasuryTxn.partyId
Invoice (sale | purchase)
└── Voucher با source پایدار
TreasuryTxn
└── Voucher با source خزانه / FunZone / withdrawal
Employee → Payslip (بدون Voucher)
CompanySettings (singleton) → FKs به Account
وضعیت فاکتور: draft | confirmed | paid | cancelled
وضعیت سند: draft | posted
۸. فایلهای کلیدی (مرجع سریع)
| فایل | نقش |
|---|---|
src/utils/id.ts |
createId / nextNumber |
src/pages/sales/salesUtils.ts |
همه سازندههای سند + تسویه + source |
src/pages/sales/invoiceEffects.ts |
اثر جانبی ذخیره فاکتور |
src/utils/funzoneFees.ts |
تقسیم ۱۰٪ / ۱۴٪ / ۷۶٪ |
src/pages/sales/funzoneVoucherLink.ts |
لینک بلیت و حذف سند تکراری خزانه |
src/accounting/unifiedVoucherSync.ts |
ارکستراسیون سینک |
src/accounting/voucherDedupe.ts |
حذف/مخفی اسناد تکراری |
src/pages/sales/funzoneSalesSync.ts |
پرداخت FunZone → فاکتور |
src/pages/treasury/funzoneTreasurySync.ts |
کیف پول / مالک → خزانه |
src/utils/accounting.ts |
محاسبات گزارش و تراز |
src/store/AppStore.tsx |
بارگذاری و CRUD |
backend/.../serializers.py |
شماره قطعی سند |
backend/.../seeding.py |
کدینگ اولیه |
⚠️
voucherSync.tsمسیر قدیمی است؛ برای جلوگیری از دوبارهثبتی از مسیر یکپارچه (unifiedVoucherSync) استفاده شود.
۹. جمعبندی قوانین شمارهگذاری (برای تیم)
- فقط شماره سند حسابداری روی سرور قطعی است؛ بقیه
max+1سمت کلاینت روی لیست فیلترشده. - سال مالی شمارهها را جدا یا ریست نمیکند.
- پیشفاکتور و فاکتور فروش سری جدا دارند؛ خرید یک سری دارد.
- دریافت و پرداخت در UI سری جدا دارند؛ مسیر برداشت ممکن است با سری دیگر همپوشانی عددی داشته باشد.
- بلیت FunZone: فاکتور + سند با تگ
funzone:invoice:…؛ تقسیم کارمزد روی همان سند؛ خزانه برای همان بلیت نباید دوبار ثبت شود. - حقوق هنوز به دفتر کل وصل نیست.
آخرین بهروزرسانی بر اساس کدبیس funzone-accounting و funzone-accounting-backend.