arc/docs/INVOICE_CHECK_ANALYSIS.md
2026-04-14 19:34:55 +03:30

8.5 KiB
Executable file

بررسی ثبت چک در فاکتورها

خلاصه

در فاکتورها، چک به صورت غیرمستقیم ثبت می‌شود. یعنی:

  1. چک در بخش payments فاکتور ثبت می‌شود
  2. یک سند دریافت/پرداخت مرتبط با فاکتور ایجاد می‌شود
  3. چک در آن سند دریافت/پرداخت ثبت می‌شود

جریان ثبت چک در فاکتور

1. ثبت فاکتور (create_invoice)

  • خط 1025-1124: ثبت‌های حسابداری فاکتور (بدون چک)
  • خط 1275-1380: اگر payments موجود باشد، برای هر چک:
    • خط 1322-1329: بررسی وجود چک و تطابق ارز
    • خط 1335-1347: ایجاد account_line برای چک
    • خط 1373: فراخوانی create_receipt_payment برای ایجاد سند دریافت/پرداخت

2. ایجاد سند دریافت/پرداخت مرتبط

  • خط 1350: تعیین نوع سند بر اساس نوع فاکتور:
    • INVOICE_SALES, INVOICE_PURCHASE_RETURN → receipt
    • سایر انواع → payment
  • خط 1373: فراخوانی create_receipt_payment با account_lines شامل چک

سناریوهای مختلف

سناریو 1: فاکتور فروش + چک دریافتی ✅

جریان:

  1. چک دریافتی قبلاً ثبت شده (حساب 10403 بدهکار، حساب 10401 بستانکار)
  2. فاکتور فروش ثبت می‌شود:
    • حساب 10401 (شخص) بدهکار می‌شود
    • حساب درآمد بستانکار می‌شود
  3. سند دریافت ایجاد می‌شود:
    • چک در account_lines قرار می‌گیرد
    • is_receipt = True
    • حساب 10403 (اسناد دریافتنی) بستانکار می‌شود ✅
    • حساب 10401 (شخص) بستانکار می‌شود ✅
    • وضعیت چک به DEPOSITED یا CLEARED تغییر می‌کند ✅

نتیجه: ✅ صحیح - تداخلی وجود ندارد


سناریو 2: فاکتور خرید + چک پرداختی ✅

جریان:

  1. چک پرداختی قبلاً ثبت شده (حساب 20201 بدهکار، حساب 20202 بستانکار)
  2. فاکتور خرید ثبت می‌شود:
    • حساب 20201 (شخص) بستانکار می‌شود
    • حساب هزینه بدهکار می‌شود
  3. سند پرداخت ایجاد می‌شود:
    • چک در account_lines قرار می‌گیرد
    • is_receipt = False
    • حساب 20202 (اسناد پرداختنی) بدهکار می‌شود ✅
    • حساب 20201 (شخص) بدهکار می‌شود ✅
    • وضعیت چک به CLEARED تغییر می‌کند ✅

نتیجه: ✅ صحیح - تداخلی وجود ندارد


سناریو 3: برگشت از فروش + چک دریافتی ✅

جریان:

  1. چک دریافتی قبلاً ثبت شده
  2. برگشت از فروش ثبت می‌شود:
    • حساب 10401 (شخص) بستانکار می‌شود
    • حساب برگشت از فروش بدهکار می‌شود
  3. سند دریافت ایجاد می‌شود:
    • چک در account_lines قرار می‌گیرد
    • is_receipt = True
    • حساب 10403 (اسناد دریافتنی) بستانکار می‌شود ✅
    • حساب 10401 (شخص) بستانکار می‌شود ✅

نتیجه: ✅ صحیح - تداخلی وجود ندارد


سناریو 4: برگشت از خرید + چک پرداختی ✅

جریان:

  1. چک پرداختی قبلاً ثبت شده
  2. برگشت از خرید ثبت می‌شود:
    • حساب 20201 (شخص) بدهکار می‌شود
    • حساب برگشت از خرید بستانکار می‌شود
  3. سند پرداخت ایجاد می‌شود:
    • چک در account_lines قرار می‌گیرد
    • is_receipt = False
    • حساب 20202 (اسناد پرداختنی) بدهکار می‌شود ✅
    • حساب 20201 (شخص) بدهکار می‌شود ✅

نتیجه: ✅ صحیح - تداخلی وجود ندارد


بررسی مشکلات احتمالی

مشکل 1: بررسی نوع چک ❓

موقعیت: invoice_service.py خط 1322-1329

  • فقط وجود چک و تطابق ارز بررسی می‌شود
  • نوع چک بررسی نمی‌شود!
  • آیا باید چک دریافتی فقط در فاکتور فروش استفاده شود؟
  • آیا باید چک پرداختی فقط در فاکتور خرید استفاده شود؟

مثال مشکل:

  • چک دریافتی در فاکتور خرید استفاده می‌شود
  • is_receipt = False → سند پرداخت ایجاد می‌شود
  • در create_receipt_payment: ALLOWED_PAYMENT_CHECK_STATUSES = {TRANSFERRED_ISSUED}
  • چک دریافتی وضعیت RECEIVED_ON_HAND دارد
  • validation رد می‌شود! ✅ (این مشکل نیست، سیستم جلوگیری می‌کند)

اما:

  • اگر validation نباشد یا از validation عبور کند:
    • چک دریافتی در سند پرداخت استفاده می‌شود
    • حساب 20202 بدهکار می‌شود (اشتباه!)
    • باید حساب 10403 بستانکار می‌شد

مشکل 2: بررسی وضعیت چک ❓

موقعیت: invoice_service.py خط 1322-1329

  • فقط وجود چک بررسی می‌شود
  • وضعیت چک بررسی نمی‌شود!
  • آیا چک باید RECEIVED_ON_HAND باشد؟
  • آیا چک باید TRANSFERRED_ISSUED باشد؟

جواب:

  • این بررسی در create_receipt_payment انجام می‌شود (خط 224)
  • ALLOWED_RECEIPT_CHECK_STATUSES = {RECEIVED_ON_HAND}
  • ALLOWED_PAYMENT_CHECK_STATUSES = {TRANSFERRED_ISSUED}
  • ✅ پس مشکل نیست

مشکل 3: تداخل با ثبت اولیه چک ❌

موقعیت: چک قبلاً در create_check ثبت شده

  • خط 146: حساب 10403 بدهکار می‌شود (چک دریافتی)
  • خط 147: حساب 10401 بستانکار می‌شود

در فاکتور فروش:

  • خط 1035: حساب 10401 بدهکار می‌شود (فاکتور فروش)
  • در سند دریافت مرتبط:
    • حساب 10403 بستانکار می‌شود (چک خارج شد) ✅
    • حساب 10401 بستانکار می‌شود (تسویه بدهی) ✅

نتیجه: ✅ تداخلی وجود ندارد - منطق صحیح است


خلاصه مشکلات

✅ چیزهایی که درست هستند:

  1. چک در سند دریافت/پرداخت مرتبط ثبت می‌شود (نه مستقیم در فاکتور)
  2. منطق حسابداری در create_receipt_payment درست است
  3. تغییر وضعیت چک انجام می‌شود
  4. validation وضعیت چک در create_receipt_payment انجام می‌شود

⚠️ مشکلات احتمالی:

1. عدم بررسی نوع چک در فاکتور (کم اهمیت)

مشکل: در invoice_service.py نوع چک بررسی نمی‌شود راه‌حل: می‌توان validation اضافه کرد که:

  • چک دریافتی فقط در فاکتور فروش/برگشت از فروش استفاده شود
  • چک پرداختی فقط در فاکتور خرید/برگشت از خرید استفاده شود

اما: این validation فعلاً در create_receipt_payment انجام می‌شود (از طریق وضعیت چک)

2. عدم validation مستقیم در فاکتور (کم اهمیت)

مشکل: اگر validation در create_receipt_payment شکست بخورد، خطا مبهم است راه‌حل: می‌توان validation را در create_invoice هم اضافه کرد


نتیجه‌گیری

وضعیت کلی: ✅ خوب

مشکلات اصلی که در اسناد دریافت/پرداخت و هزینه/درآمد وجود داشت، در فاکتورها وجود ندارد چون:

  1. چک به صورت مستقیم در فاکتور ثبت نمی‌شود
  2. منطق حسابداری از طریق create_receipt_payment انجام می‌شود که قبلاً اصلاح شده
  3. تغییر وضعیت چک در create_receipt_payment انجام می‌شود

پیشنهادات بهبود (اختیاری):

  1. اضافه کردن validation نوع چک در create_invoice برای خطای واضح‌تر
  2. اضافه کردن validation وضعیت چک در create_invoice برای خطای واضح‌تر

اما این تغییرات ضروری نیستند چون validation در create_receipt_payment انجام می‌شود.