hesabresi and desc transfer

This commit is contained in:
javad committed 2026-08-16 15:42:48 +03:30
1 parent e353ed6fc2
commit 16eb747b5c
7 files changed
+678 -78

No files matched your search

@@ -38,38 +38,51 @@
</div>
</div>
<div class="columns is-multiline">
<div class="column is-12-mobile is-4-tablet">
<div class="box p-4 has-background-white shadow-card border-left-danger h-100">
<div class="level is-mobile m-0">
<div class="level-left">
<div>
<p class="heading has-text-grey-dark is-size-7 mb-1">کل مطالبات معوق بازار (سرمایه قفل شده)</p>
<p class="title is-size-4 is-size-5-mobile toCurrency has-text-danger-dark">{{ kpi_total_unpaid }}</p>
</div>
</div>
</div>
</div>
<!-- هشدار هوشمند خطاهای سیستمی -->
{% if group1_count > 0 or group2_count > 0 or group4_count > 0 %}
<div class="notification is-danger is-light mb-4 py-3 shadow-sm is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap">
<div class="mb-2-mobile">
<span class="icon has-text-danger"><i class="fas fa-exclamation-circle"></i></span>
<strong class="has-text-danger-dark">حسابرسی خودکار سیستم:</strong>
تعداد <b>{{ group1_count }} مورد</b> بدهی پرخطر، <b>{{ group2_count }} مورد</b> خطای ثبتی چک و <b>{{ group4_count }} مورد</b> رکورد نامتعارف یافت شد!
</div>
<a href="#audit-section" class="button is-danger is-small is-rounded is-outlined px-4">مشاهده گزارش حسابرسی (پایین صفحه)</a>
</div>
{% endif %}
<!-- بخش اول: کارت‌های شاخص (KPI) -->
<div class="columns is-multiline">
<div class="column is-12-mobile is-4-tablet">
<div class="box p-4 has-background-white shadow-card border-left-success h-100">
<div class="level is-mobile m-0">
<div class="level-left">
<div>
<p class="heading has-text-grey-dark is-size-7 mb-1">حجم ناخالص فروش در بازه انتخابی</p>
<p class="title is-size-4 is-size-5-mobile toCurrency has-text-success-dark">{{ kpi_total_sales }}</p>
<p class="heading has-text-grey-dark is-size-7 mb-1" title="مجموع مبلغ اسناد در دست (چک‌ها و سررسیدهای پرداخت نشده)">مطالبات دارای سند (چک/سررسید)</p>
<p class="title is-size-4 is-size-5-mobile toCurrency has-text-success-dark">{{ kpi_total_unpaid }}</p>
</div>
</div>
</div>
</div>
</div>
<div class="column is-12-mobile is-4-tablet">
<div class="box p-4 has-background-white shadow-card border-left-warning h-100">
<div class="box p-4 has-background-white shadow-card border-left-info h-100">
<div class="level is-mobile m-0">
<div class="level-left">
<div>
<p class="heading has-text-grey-dark is-size-7 mb-1">تعداد چک‌های سررسیدگذشته و برگشتی</p>
<p class="title is-size-4 is-size-5-mobile has-text-warning-dark">{{ kpi_overdue_checks }} <span class="is-size-6">فقره</span></p>
<p class="heading has-text-grey-dark is-size-7 mb-1">حجم ناخالص فروش در بازه انتخابی</p>
<p class="title is-size-4 is-size-5-mobile toCurrency has-text-info-dark">{{ kpi_total_sales }}</p>
</div>
</div>
</div>
</div>
</div>
<div class="column is-12-mobile is-4-tablet">
<div class="box p-4 has-background-danger-light shadow-card border-left-danger h-100" title="بدهی مشتریانی که هیچ‌گونه چک یا سررسیدی برای بدهی خود ارائه نکرده‌اند">
<div class="level is-mobile m-0">
<div class="level-left">
<div>
<p class="heading has-text-danger-dark is-size-7 mb-1 font-weight-bold">مجموع مطالبات پرخطر (بدون سند)</p>
<p class="title is-size-4 is-size-5-mobile toCurrency has-text-danger-dark">{{ group1_total }}</p>
</div>
</div>
</div>
@@ -77,6 +90,7 @@
</div>
</div>
<!-- بخش دوم: نمودارها -->
<div class="columns is-multiline mt-1">
<div class="column is-12">
<div class="box p-4 shadow-card">
@@ -96,11 +110,10 @@
</div>
<div class="columns is-multiline mt-1">
<div class="column is-12-mobile is-7-desktop">
<div class="box p-4 shadow-card h-100">
<p class="title is-6 is-size-7-mobile pb-2 mb-4" style="border-bottom: 1px solid #f0f0f0;">
📊 ماتریس ریسک و تحلیل سنی مطالبات
📊 ماتریس ریسک و تحلیل سنی اسناد (چک/نسیه)
</p>
<div class="chart-wrapper-tall">
<canvas id="agingChart"></canvas>
@@ -152,8 +165,266 @@
</div>
</div>
</div>
</div>
<!-- ========================================================= -->
<!-- بخش سوم: کالبدشکافی ۳۶۰ درجه و سیستم جامع حسابرسی -->
<!-- ========================================================= -->
<div id="audit-section" class="columns is-multiline mt-5 mb-4">
<div class="column is-12">
<h3 class="title is-5 mb-2"><i class="fas fa-microscope has-text-primary mr-2"></i> سیستم حسابرسی و مغایرت‌گیری </h3>
<!-- خلاصه تراز کل -->
<div class="box p-3 has-background-light shadow-sm" style="border: 1px solid #e0e0e0;">
<div class="columns is-mobile is-multiline has-text-centered is-size-7">
<div class="column is-4-tablet is-12-mobile">
<span class="has-text-grey">مجموع تراز دفتر کل:</span> <br>
<strong class="is-size-5 toCurrency">{{ global_mande }}</strong>
</div>
<div class="column is-4-tablet is-12-mobile" style="border-right: 1px solid #ddd; border-left: 1px solid #ddd;">
<span class="has-text-grey">مجموع چک‌ها/اسناد در سیستم:</span> <br>
<strong class="is-size-5 toCurrency has-text-success-dark">{{ g_sar }}</strong>
</div>
<div class="column is-4-tablet is-12-mobile">
<span class="has-text-grey">اختلاف ریاضی سیستم:</span> <br>
<strong class="is-size-5 toCurrency has-text-danger-dark" dir="ltr">{{ global_diff }}</strong>
</div>
</div>
</div>
</div>
<!-- 🔴 گروه اول: بدهکاران پرخطر -->
<div class="column is-12">
<div class="box p-4 shadow-card border-left-danger">
<div class="level is-mobile is-flex-wrap-wrap mb-4 pb-2" style="border-bottom: 1px solid #fee2e2;">
<div class="level-left mb-2-mobile">
<p class="title is-6 is-size-7-mobile mb-0 has-text-danger-dark">
<span class="icon is-small ml-1"><i class="fas fa-exclamation-triangle"></i></span>
گروه ۱: مطالبات فاقد پوشش (کسری چک / بدهی خطرناک)
</p>
</div>
<div class="level-right">
<span class="tag is-danger is-light ml-2">مجموع کسر سند: <span class="toCurrency mr-1">{{ group1_total }}</span> تومان</span>
<span class="tag is-danger">تعداد: {{ group1_count }} نفر</span>
</div>
</div>
{% if group1_sample %}
<div class="table-container">
<table class="table is-fullwidth is-hoverable is-striped is-bordered is-size-7">
<thead>
<tr class="has-background-danger-light">
<th class="has-text-centered">ردیف</th>
<th>نام مشتری</th>
<th>تراز دفتر کل (بدهی)</th>
<th>اسناد موجود</th>
<th class="has-text-danger-dark">مقدار کسر چک (بدهی روی هوا)</th>
<th class="has-text-centered">عملیات</th>
</tr>
</thead>
<tbody>
{% for c in group1_sample %}
<tr>
<td class="has-text-centered">{{ forloop.counter }}</td>
<td><strong>{{ c.name_family }}</strong></td>
<td class="toCurrency has-text-grey">{{ c.net_debt }}</td>
<td class="toCurrency has-text-success">{{ c.t_sarresid }}</td>
<td class="toCurrency has-text-danger has-text-weight-bold">{{ c.diff }}</td>
<td class="has-text-centered">
<a href="{% url 'admin_panel:customer' c.id %}" target="_blank" class="button is-small is-light is-danger is-outlined rounded">ثبت چک/پیگیری</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if group1_count > 20 %}
<p class="is-size-7 has-text-grey mt-2 has-text-centered">
* جهت جلوگیری از کندی سیستم، صرفاً ۲۰ مشتری با <strong>بیشترین بدهی رو هوا</strong> نمایش داده شده‌اند.
</p>
{% endif %}
{% else %}
<div class="notification is-success is-light has-text-centered py-4">
🎉 عالی! هیچ مشتری بدهکاری فاقد ثبت پوشش سند (کسری چک) در سیستم وجود ندارد.
</div>
{% endif %}
</div>
</div>
<!-- 🟡 گروه دوم: چک‌های اضافی و خطای اپراتور -->
<div class="column is-12">
<div class="box p-4 shadow-card border-left-warning">
<div class="level is-mobile is-flex-wrap-wrap mb-4 pb-2" style="border-bottom: 1px solid #fff3c4;">
<div class="level-left mb-2-mobile">
<p class="title is-6 is-size-7-mobile mb-0 has-text-warning-dark">
<span class="icon is-small ml-1"><i class="fas fa-search-dollar"></i></span>
گروه ۲: خطای ثبتی اپراتورها (چک پاس‌نشده اضافی در سیستم)
</p>
</div>
<div class="level-right">
<span class="tag is-warning is-light ml-2">جمع خطای مالی: <span class="toCurrency mr-1">{{ group2_total }}</span> تومان</span>
<span class="tag is-warning">تعداد: {{ group2_count }} فقره</span>
</div>
</div>
<p class="is-size-7 has-text-grey-dark mb-3">
💡 <b>راهنما:</b> این افراد چک خود را نقدی یا کارت‌به‌کارت تسویه کرده‌اند، اما اپراتور فراموش کرده وضعیت چک را از "پرداخت‌نشده" به "پاس‌شده" تغییر دهد.
</p>
{% if group2_sample %}
<div class="table-container">
<table class="table is-fullwidth is-hoverable is-striped is-bordered is-size-7">
<thead>
<tr class="has-background-warning-light">
<th class="has-text-centered">ردیف</th>
<th>نام مشتری</th>
<th>تراز واقعی مشتری</th>
<th>چک‌های ثبت‌شده (غلط)</th>
<th class="has-text-danger-dark">مبلغ چک اضافه در سیستم</th>
<th class="has-text-centered">عملیات</th>
</tr>
</thead>
<tbody>
{% for c in group2_sample %}
<tr>
<td class="has-text-centered">{{ forloop.counter }}</td>
<td><strong>{{ c.name_family }}</strong></td>
<td class="toCurrency has-text-info">{{ c.net_debt }}</td>
<td class="toCurrency has-text-grey">{{ c.t_sarresid }}</td>
<td class="toCurrency has-text-danger has-text-weight-bold">{{ c.fake_amount }}</td>
<td class="has-text-centered">
<a href="{% url 'admin_panel:customer' c.id %}" target="_blank" class="button is-small is-light is-warning is-outlined rounded">اصلاح چک‌ها</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if group2_count > 20 %}
<p class="is-size-7 has-text-grey mt-2 has-text-centered">
* جهت جلوگیری از کندی سیستم، صرفاً ۲۰ مشتری با <strong>بیشترین میزان خطای ثبتی</strong> نمایش داده شده‌اند.
</p>
{% endif %}
{% else %}
<div class="notification is-success is-light has-text-centered py-4">
🎉 عالی! هیچ چک اضافی یا پاس‌نشده‌ی اشتباهی در سیستم یافت نشد.
</div>
{% endif %}
</div>
</div>
<!-- 🟢 گروه سوم: پیش‌دریافت‌ها -->
<div class="column is-12">
<div class="box p-4 shadow-card border-left-success">
<div class="level is-mobile is-flex-wrap-wrap mb-4 pb-2" style="border-bottom: 1px solid #d4edda;">
<div class="level-left mb-2-mobile">
<p class="title is-6 is-size-7-mobile mb-0 has-text-success-dark">
<span class="icon is-small ml-1"><i class="fas fa-hand-holding-usd"></i></span>
گروه ۳: پیش‌دریافت‌ها و بستانکاری‌های خالص (بدون چک)
</p>
</div>
<div class="level-right">
<span class="tag is-success is-light ml-2">مجموع تعهدات: <span class="toCurrency mr-1" dir="ltr">{{ group3_total }}</span> تومان</span>
<span class="tag is-success">تعداد: {{ group3_count }} نفر</span>
</div>
</div>
{% if group3_sample %}
<div class="table-container">
<table class="table is-fullwidth is-hoverable is-striped is-bordered is-size-7">
<thead>
<tr class="has-background-success-light">
<th class="has-text-centered">ردیف</th>
<th>نام مشتری</th>
<th>شماره تماس</th>
<th class="has-text-success-dark">مبلغ بستانکاری (تراز منفی)</th>
<th class="has-text-centered">وضعیت چک</th>
<th class="has-text-centered">عملیات</th>
</tr>
</thead>
<tbody>
{% for c in group3_sample %}
<tr>
<td class="has-text-centered">{{ forloop.counter }}</td>
<td><strong>{{ c.name_family }}</strong></td>
<td><span dir="ltr">{{ c.phone1 }}</span></td>
<td class="toCurrency has-text-success-dark has-text-weight-bold" dir="ltr">{{ c.net_debt }}</td>
<td class="has-text-centered has-text-grey">ندارد</td>
<td class="has-text-centered">
<a href="{% url 'admin_panel:customer' c.id %}" target="_blank" class="button is-small is-light is-success is-outlined rounded">بررسی پرونده</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if group3_count > 20 %}
<p class="is-size-7 has-text-grey mt-2 has-text-centered">
* جهت جلوگیری از کندی سیستم، صرفاً ۲۰ مشتری بستانکار نمایش داده شده‌اند.
</p>
{% endif %}
{% else %}
<div class="notification is-light has-text-centered py-4">
هیچ پیش‌دریافت یا بستانکاری خالصی در سیستم یافت نشد.
</div>
{% endif %}
</div>
</div>
<!-- 🟣 گروه چهارم: رکوردهای نامتعارف -->
{% if group4_count > 0 %}
<div class="column is-12">
<div class="box p-4 shadow-card" style="border-right: 4px solid #b86bff !important;">
<div class="level is-mobile is-flex-wrap-wrap mb-4 pb-2" style="border-bottom: 1px solid #f3e8ff;">
<div class="level-left mb-2-mobile">
<p class="title is-6 is-size-7-mobile mb-0" style="color: #6b21a8;">
<span class="icon is-small ml-1"><i class="fas fa-bug"></i></span>
گروه ۴: رکوردهای نامتعارف (بستانکارانی که چک پرداخت‌نشده دارند!)
</p>
</div>
<div class="level-right">
<span class="tag is-light ml-2" style="background-color: #f3e8ff; color: #6b21a8;">مجموع اختلاف: <span class="toCurrency mr-1" dir="ltr">{{ group4_total }}</span></span>
<span class="tag" style="background-color: #b86bff; color: white;">تعداد: {{ group4_count }} مورد</span>
</div>
</div>
<p class="is-size-7 has-text-grey-dark mb-3">
💡 <b>توجه:</b> این مشتریان در دفتر کل طلبکارند، اما اپراتور چک پرداخت‌نشده‌ای هم از آن‌ها نگه داشته است! (نیاز به بررسی حسابداری دارد).
</p>
<div class="table-container">
<table class="table is-fullwidth is-hoverable is-striped is-bordered is-size-7">
<thead>
<tr style="background-color: #faf5ff;">
<th class="has-text-centered">ردیف</th>
<th>نام مشتری</th>
<th>تراز واقعی (بستانکار)</th>
<th>چک ثبت‌شده</th>
<th class="has-text-centered">عملیات</th>
</tr>
</thead>
<tbody>
{% for c in group4_sample %}
<tr>
<td class="has-text-centered">{{ forloop.counter }}</td>
<td><strong>{{ c.name_family }}</strong></td>
<td class="toCurrency has-text-success-dark" dir="ltr">{{ c.net_debt }}</td>
<td class="toCurrency has-text-danger">{{ c.t_sarresid }}</td>
<td class="has-text-centered">
<a href="{% url 'admin_panel:customer' c.id %}" target="_blank" class="button is-small is-light is-outlined rounded" style="border-color: #b86bff; color: #b86bff;">بررسی فنی</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
</div>
</div>
<style>
@@ -161,6 +432,7 @@
.shadow-card { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04); border: 1px solid #f0f0f0; border-radius: 8px; }
.border-left-danger { border-right: 4px solid #f14668 !important; }
.border-left-success { border-right: 4px solid #48c78e !important; }
.border-left-info { border-right: 4px solid #3e8ed0 !important; }
.border-left-warning { border-right: 4px solid #ffdd57 !important; }
.bg-light-filter { background-color: #fafafa; border-radius: 6px; }
.h-100 { height: 100%; }
@@ -178,22 +450,16 @@
/* مدیا کوئری اختصاصی برای موبایل و تبلت‌های کوچک */
@media screen and (max-width: 1023px) {
/* در موبایل خط عمودی به خط افقی بالا تغییر می‌کند */
.responsive-border-between {
border-right: none;
border-top: 1px solid #f0f0f0;
padding-top: 1.5rem !important;
margin-top: 1rem;
}
/* کاهش ارتفاع نمودارها در موبایل برای جلوگیری از اسکرول طولانی */
.chart-wrapper-tall { height: 260px; }
.chart-wrapper-medium { height: 240px; }
.chart-wrapper-short { height: 200px; }
.mb-2-mobile { margin-bottom: 0.5rem !important; }
/* برای بهتر دیده شدن تگ‌ها در صفحه کوچک */
.is-flex-grow-1-mobile { flex-grow: 1; text-align: right; }
}
</style>
@@ -211,7 +477,7 @@
autoClose: true,
format: 'YYYY/MM/DD',
calendar: { persian: { locale: 'fa' } },
responsive: true // قابلیت تقویم برای موبایل
responsive: true
});
var pickerTa = $(".date-picker-ta").pDatepicker({
@@ -226,9 +492,8 @@
{% if filters.azTarikh %} pickerAz.setDate({{ filters.azTarikh }}); {% endif %}
{% if filters.taTarikh %} pickerTa.setDate({{ filters.taTarikh }}); {% endif %}
// 🌟 نمودار روند خطی مانده حساب کل مشتریان در ۱۲ ماه
// نمودار روند خطی
var ctxTrend = document.getElementById('debtTrendChart').getContext('2d');
var gradientTrend = ctxTrend.createLinearGradient(0, 0, 0, 300);
gradientTrend.addColorStop(0, 'rgba(62, 142, 208, 0.45)');
gradientTrend.addColorStop(1, 'rgba(62, 142, 208, 0.0)');
@@ -273,27 +538,14 @@
}
},
scales: {
y: {
beginAtZero: true,
ticks: { font: { family: 'Tahoma, Vazir', size: 10 } }
},
x: {
ticks: {
font: { family: 'Tahoma, Vazir', size: 10 },
maxRotation: 45, // چرخش لیبل‌ها برای جا شدن در موبایل
minRotation: 0
},
grid: { display: false }
}
},
interaction: {
intersect: false,
mode: 'index',
y: { beginAtZero: true, ticks: { font: { family: 'Tahoma, Vazir', size: 10 } } },
x: { ticks: { font: { family: 'Tahoma, Vazir', size: 10 }, maxRotation: 45, minRotation: 0 }, grid: { display: false } }
},
interaction: { intersect: false, mode: 'index' },
}
});
// ۲. نمودار سنی مطالبات
// نمودار سنی مطالبات
var ctxAging = document.getElementById('agingChart').getContext('2d');
new Chart(ctxAging, {
type: 'bar',
@@ -304,7 +556,7 @@
backgroundColor: ['rgba(72, 199, 142, 0.85)', 'rgba(255, 221, 87, 0.85)', 'rgba(241, 70, 104, 0.5)', 'rgba(241, 70, 104, 0.95)'],
borderColor: ['#48c78e', '#ffdd57', '#f14668', '#f14668'],
borderWidth: 1.5,
barThickness: 30 // ضخامت میله‌ها برای موبایل بهتر است
barThickness: 30
}]
},
options: {
@@ -318,7 +570,7 @@
}
});
// ۳. نمودار دایره‌ای تسویه مبالغ
// نمودار دایره‌ای تسویه مبالغ
var ctxPay = document.getElementById('paymentMethodsChart').getContext('2d');
new Chart(ctxPay, {
type: 'doughnut',
@@ -335,14 +587,14 @@
maintainAspectRatio: false,
plugins: {
legend: {
position: window.innerWidth < 768 ? 'bottom' : 'right', // در موبایل لجند پایین می‌رود
position: window.innerWidth < 768 ? 'bottom' : 'right',
labels: { font: { family: 'Tahoma, Vazir', size: 11 }, boxWidth: 12 }
}
}
}
});
// ۴. نمودار افقی انبار
// نمودار افقی انبار
var ctxLeak = document.getElementById('inventoryLeakChart').getContext('2d');
new Chart(ctxLeak, {
type: 'bar',
@@ -367,6 +619,17 @@
}
}
});
// اسکرول نرم برای لینک‌های درون صفحه
$('a[href^="#"]').on('click', function(event) {
var target = $(this.getAttribute('href'));
if( target.length ) {
event.preventDefault();
$('html, body').stop().animate({
scrollTop: target.offset().top - 20
}, 800);
}
});
});
</script>
{% endblock %}