45 lines
2.0 KiB
Python
45 lines
2.0 KiB
Python
"""مانده حساب مشتری برای استفاده در قالبهای پیامک.
|
||
|
||
تعریف (همان قاعدهٔ صفحهٔ حسابداری مشتری و گزارش مالی)::
|
||
|
||
مانده حساب = مجموع بدهکار (debit) − مجموع بستانکار (credit)
|
||
|
||
نکتهٔ مهم — تفاوت با «مانده سررسیدشده»:
|
||
|
||
* **مانده حساب** (این ماژول): تراز کل همهٔ اسناد حسابداری مشتری (``Article``).
|
||
منبع: ``admin_panel/models/finance.py::Article``.
|
||
* **مانده/مبلغ سررسیدشده**: مبلغ چکها و نسیههای پرداختنشده در جدول
|
||
``Sarresid`` (``payStatus='false'``). بسیار متفاوت از مانده حساب است و
|
||
جای دیگری (``views/finance.py``) محاسبه میشود.
|
||
|
||
به همین دلیل این مقدار با کلید مستقل ``{balance}`` در قالبها منتشر میشود و
|
||
هرگز با مبلغ سررسید (``{amount}`` در پیامک چک/نسیه) قاطی نمیشود.
|
||
"""
|
||
import logging
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
def customer_balance(customer):
|
||
"""مانده حساب مشتری (``debit − credit``) بهصورت عدد صحیح.
|
||
|
||
اگر مشتری یا اسنادش وجود نداشته باشد ``0`` برمیگردد. هیچ استثنایی پرتاب
|
||
نمیکند تا مسیر ساخت پیامک هرگز مختل نشود.
|
||
"""
|
||
if customer is None or getattr(customer, "pk", None) is None:
|
||
return 0
|
||
try:
|
||
from django.db.models import Sum
|
||
|
||
from ..models import Article
|
||
|
||
agg = Article.objects.filter(customer=customer).aggregate(
|
||
d=Sum("debit"), c=Sum("credit"),
|
||
)
|
||
debit = agg["d"] or 0
|
||
credit = agg["c"] or 0
|
||
return debit - credit
|
||
except Exception:
|
||
logger.exception("محاسبهٔ مانده حساب مشتری %s شکست خورد", customer.pk)
|
||
return 0
|