hesabresi and desc transfer
This commit is contained in:
1 parent
e353ed6fc2
commit
16eb747b5c
7 files changed
+678
-78
No files matched your search
@@ -0,0 +1,110 @@
|
||||
import os
|
||||
import csv
|
||||
import datetime
|
||||
|
||||
# ============================================================================
|
||||
# ۱. تنظیمات محیطی جنگو (بسیار مهم)
|
||||
# ============================================================================
|
||||
# نام 'myproject' را با نام پوشه اصلی پروژه خود (که فایل settings.py در آنجاست) عوض کنید
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'khatibi.settings')
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from django.db.models import Sum, Subquery, OuterRef, F, IntegerField
|
||||
from django.db.models.functions import Coalesce
|
||||
from admin_panel.models import Article, Sarresid, Customer
|
||||
|
||||
# ============================================================================
|
||||
# ۲. هسته اصلی محاسبات (الگوریتم پرسرعت با Subquery)
|
||||
# ============================================================================
|
||||
def run_audit():
|
||||
print("\n" + "="*65)
|
||||
print(" 🚀 در حال اسکن دیتابیس و اجرای عملیات مغایرتگیری هوشمند...")
|
||||
print("="*65 + "\n")
|
||||
|
||||
# واکشی سریع مجموع بدهکاری مشتریان
|
||||
sq_debit = Article.objects.filter(
|
||||
customer=OuterRef('pk')
|
||||
).values('customer').annotate(s=Sum('debit')).values('s')
|
||||
|
||||
# واکشی سریع مجموع بستانکاری مشتریان
|
||||
sq_credit = Article.objects.filter(
|
||||
customer=OuterRef('pk')
|
||||
).values('customer').annotate(s=Sum('credit')).values('s')
|
||||
|
||||
# واکشی سریع مجموع اسناد (چک/نسیه) پرداختنشده
|
||||
sq_sarresid = Sarresid.objects.filter(
|
||||
customer=OuterRef('pk'), payStatus="false"
|
||||
).values('customer').annotate(s=Sum('price')).values('s')
|
||||
|
||||
# پردازش نهایی در لایه دیتابیس (بدون نیاز به لود کردن دیتا در RAM سرور)
|
||||
base_customers = Customer.objects.filter(is_active=True).annotate(
|
||||
t_debit=Coalesce(Subquery(sq_debit, output_field=IntegerField()), 0),
|
||||
t_credit=Coalesce(Subquery(sq_credit, output_field=IntegerField()), 0),
|
||||
t_sarresid=Coalesce(Subquery(sq_sarresid, output_field=IntegerField()), 0),
|
||||
).annotate(
|
||||
net_debt=F('t_debit') - F('t_credit') # تراز نهایی
|
||||
).annotate(
|
||||
diff=F('net_debt') - F('t_sarresid') # اختلاف تراز و اسناد
|
||||
)
|
||||
|
||||
# استخراج گروه اول: بدهکاران مطلقاً بدون چک
|
||||
group1 = base_customers.filter(net_debt__gt=0, t_sarresid=0).order_by('-net_debt')
|
||||
|
||||
# استخراج گروه دوم: دارای خطای چک اضافی در سیستم
|
||||
group2 = base_customers.filter(diff__lt=0, t_sarresid__gt=0).annotate(
|
||||
fake_amount=F('t_sarresid') - F('net_debt')
|
||||
).order_by('-fake_amount')
|
||||
|
||||
# ============================================================================
|
||||
# ۳. نمایش گزارش در کنسول
|
||||
# ============================================================================
|
||||
print(f"🔴 گروه اول: بدهکاران فاقد سند/چک (تعداد: {group1.count()})")
|
||||
print("-" * 65)
|
||||
for c in group1[:10]: # نمایش ۱۰ نفر اول در کنسول
|
||||
print(f"👤 {c.name_family} | موبایل: {c.phone1} | بدهی روی هوا: {c.net_debt:,} ریال")
|
||||
if group1.count() > 10:
|
||||
print(f" ... و {group1.count() - 10} نفر دیگر (لیست کامل در فایل خروجی)")
|
||||
|
||||
print("\n" + f"🟡 گروه دوم: دارای خطای ثبت چک اضافه (تعداد: {group2.count()})")
|
||||
print("-" * 65)
|
||||
for c in group2[:10]:
|
||||
print(f"👤 {c.name_family} | تراز واقعی: {c.net_debt:,} | مبلغ چک تو سیستم: {c.t_sarresid:,} | ❌ چک اضافی: {c.fake_amount:,}")
|
||||
if group2.count() > 10:
|
||||
print(f" ... و {group2.count() - 10} نفر دیگر (لیست کامل در فایل خروجی)")
|
||||
|
||||
# ============================================================================
|
||||
# ۴. تولید فایل خروجی CSV برای حسابدار
|
||||
# ============================================================================
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"financial_audit_{timestamp}.csv"
|
||||
|
||||
with open(filename, mode='w', newline='', encoding='utf-8-sig') as file:
|
||||
writer = csv.writer(file)
|
||||
|
||||
# هدر فایل
|
||||
writer.writerow(["شناسه مشتری", "نام و نام خانوادگی", "شماره تماس", "گروه خطا", "شرح خطا", "تراز واقعی (Article)", "جمع اسناد در دست (Sarresid)", "مبلغ مغایرت"])
|
||||
|
||||
# نوشتن دیتای گروه اول
|
||||
for c in group1:
|
||||
writer.writerow([
|
||||
c.id, c.name_family, c.phone1,
|
||||
"گروه 1 (خطرناک)", "بدهی دفتری باز - بدون چک یا موعد نسیه",
|
||||
c.net_debt, c.t_sarresid, c.diff
|
||||
])
|
||||
|
||||
# نوشتن دیتای گروه دوم
|
||||
for c in group2:
|
||||
writer.writerow([
|
||||
c.id, c.name_family, c.phone1,
|
||||
"گروه 2 (خطای ثبتی)", "چک پاس نشده در سیستم بیشتر از بدهی واقعی است",
|
||||
c.net_debt, c.t_sarresid, c.fake_amount
|
||||
])
|
||||
|
||||
print("\n" + "="*65)
|
||||
print(f"✅ عملیات با موفقیت انجام شد. فایل گزارش تولید شد: {filename}")
|
||||
print("="*65 + "\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_audit()
|
||||
Reference in new issue
Block a user