forked from hesabix/arc
177 lines
7.4 KiB
HTML
Executable file
177 lines
7.4 KiB
HTML
Executable file
{% extends "pdf/base.html" %}
|
|
{% block content %}
|
|
<style>
|
|
.report-installments .header {
|
|
margin-bottom: 10px;
|
|
padding: 10px 12px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
background: #fff;
|
|
box-shadow: none;
|
|
}
|
|
.report-installments .title { font-size: 18px; }
|
|
.report-installments .filters-line {
|
|
margin-bottom: 10px;
|
|
padding: 6px 8px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
background: #fff;
|
|
color: var(--text);
|
|
font-size: 10.5px;
|
|
line-height: 1.45;
|
|
page-break-inside: avoid;
|
|
}
|
|
.report-installments .filters-line .label {
|
|
font-weight: 700;
|
|
margin-inline-end: 6px;
|
|
white-space: nowrap;
|
|
}
|
|
.report-installments td.num, .report-installments th.num {
|
|
text-align: {{ 'left' if is_fa else 'right' }};
|
|
font-variant-numeric: tabular-nums;
|
|
white-space: nowrap;
|
|
}
|
|
.report-installments .status {
|
|
font-weight: 700;
|
|
white-space: nowrap;
|
|
}
|
|
.report-installments .status.paid { color: #0a7; }
|
|
.report-installments .status.overdue { color: #c00; }
|
|
.report-installments .status.partial { color: #b60; }
|
|
.report-installments .status.pending { color: #666; }
|
|
.report-installments .summary-grid {
|
|
display: flex;
|
|
gap: 10px;
|
|
flex-wrap: wrap;
|
|
margin-bottom: 10px;
|
|
page-break-inside: avoid;
|
|
}
|
|
.report-installments .summary-grid .box {
|
|
flex: 1;
|
|
min-width: 240px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
padding: 8px 10px;
|
|
background: #fff;
|
|
}
|
|
.report-installments .summary-grid .row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 8px;
|
|
font-size: 10.5px;
|
|
padding: 2px 0;
|
|
border-bottom: 1px dashed #c7c7c7;
|
|
}
|
|
.report-installments .summary-grid .row:last-child { border-bottom: none; }
|
|
.report-installments .summary-grid .k { color: var(--muted); }
|
|
.report-installments .summary-grid .v { font-weight: 700; color: var(--text); }
|
|
</style>
|
|
|
|
<div class="report-installments">
|
|
<div class="header">
|
|
<div>
|
|
<div class="title">{{ title_text }}</div>
|
|
<div class="meta">{{ business_name or '' }}</div>
|
|
</div>
|
|
<div class="meta">
|
|
{{ generated_at | format_date("%Y/%m/%d %H:%M") }}
|
|
</div>
|
|
</div>
|
|
|
|
{% if filters_summary and filters_summary|length > 0 %}
|
|
{% set max_filters = 8 %}
|
|
{% set shown = filters_summary[:max_filters] %}
|
|
{% set remaining = (filters_summary|length) - (shown|length) %}
|
|
<div class="filters-line">
|
|
<span class="label">{{ 'فیلترها' if is_fa else 'Filters' }}:</span>
|
|
<span class="text">
|
|
{% for f in shown %}
|
|
{% if not loop.first %} | {% endif %}
|
|
{{ (f.label | default('', true)) }}: {{ (f.value | default('', true)) }}
|
|
{% endfor %}
|
|
</span>
|
|
{% if remaining > 0 %}
|
|
<span class="more"> | +{{ remaining }}</span>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if stats %}
|
|
<div class="summary-grid">
|
|
<div class="box">
|
|
<div class="row"><span class="k">{{ 'تعداد' if is_fa else 'Count' }}</span><span class="v">{{ (stats.total_count or 0) | smart_number(0) | ltr | safe }}</span></div>
|
|
<div class="row"><span class="k">{{ 'جمع اصل' if is_fa else 'Principal' }}</span><span class="v">{{ (stats.principal_total or 0) | smart_number(0) | ltr | safe }}</span></div>
|
|
<div class="row"><span class="k">{{ 'جمع سود' if is_fa else 'Interest' }}</span><span class="v">{{ (stats.interest_total or 0) | smart_number(0) | ltr | safe }}</span></div>
|
|
<div class="row"><span class="k">{{ 'جمع کل' if is_fa else 'Total' }}</span><span class="v">{{ (stats.amount_total or 0) | smart_number(0) | ltr | safe }}</span></div>
|
|
</div>
|
|
<div class="box">
|
|
<div class="row"><span class="k">{{ 'پرداختشده' if is_fa else 'Paid' }}</span><span class="v">{{ (stats.paid_total or 0) | smart_number(0) | ltr | safe }}</span></div>
|
|
<div class="row"><span class="k">{{ 'مانده' if is_fa else 'Remaining' }}</span><span class="v">{{ (stats.remaining_total or 0) | smart_number(0) | ltr | safe }}</span></div>
|
|
<div class="row"><span class="k">{{ 'جریمه دیرکرد' if is_fa else 'Late fee' }}</span><span class="v">{{ (stats.late_fee_total or 0) | smart_number(0) | ltr | safe }}</span></div>
|
|
<div class="row"><span class="k">{{ 'وضعیتها' if is_fa else 'Statuses' }}</span>
|
|
<span class="v">
|
|
{% if stats.status_breakdown %}
|
|
{% for k, v in stats.status_breakdown.items() %}
|
|
{% if not loop.first %} | {% endif %}
|
|
{{ k }}: {{ v }}
|
|
{% endfor %}
|
|
{% else %}
|
|
—
|
|
{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="table-wrapper">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>{{ 'فاکتور' if is_fa else 'Invoice' }}</th>
|
|
<th class="num">{{ 'قسط' if is_fa else 'Seq' }}</th>
|
|
<th>{{ 'شخص' if is_fa else 'Person' }}</th>
|
|
<th>{{ 'سررسید' if is_fa else 'Due date' }}</th>
|
|
<th>{{ 'وضعیت' if is_fa else 'Status' }}</th>
|
|
<th class="num">{{ 'اصل' if is_fa else 'Principal' }}</th>
|
|
<th class="num">{{ 'سود' if is_fa else 'Interest' }}</th>
|
|
<th class="num">{{ 'کل' if is_fa else 'Total' }}</th>
|
|
<th class="num">{{ 'پرداخت' if is_fa else 'Paid' }}</th>
|
|
<th class="num">{{ 'مانده' if is_fa else 'Remaining' }}</th>
|
|
<th class="num">{{ 'جریمه' if is_fa else 'Late fee' }}</th>
|
|
<th class="num">{{ 'روزهای معوق' if is_fa else 'Overdue days' }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for it in items or [] %}
|
|
{% set st = (it.status | default('', true) | lower) %}
|
|
<tr>
|
|
<td>{{ it.invoice_code | default('-', true) }}</td>
|
|
<td class="num">{{ it.seq | default('-', true) | ltr | safe }}</td>
|
|
<td>{{ it.person_name | default('-', true) }}</td>
|
|
<td>{{ it.due_date | default('-', true) }}</td>
|
|
<td>
|
|
<span class="status {{ st if st else 'pending' }}">
|
|
{% if is_fa %}
|
|
{% if st == 'paid' %}پرداختشده{% elif st == 'partial' %}نیمهپرداخت{% elif st == 'overdue' %}معوق{% else %}در انتظار{% endif %}
|
|
{% else %}
|
|
{{ st if st else 'pending' }}
|
|
{% endif %}
|
|
</span>
|
|
</td>
|
|
<td class="num">{{ it.principal | smart_number(0) | ltr | safe }}</td>
|
|
<td class="num">{{ it.interest | smart_number(0) | ltr | safe }}</td>
|
|
<td class="num">{{ it.total | smart_number(0) | ltr | safe }}</td>
|
|
<td class="num">{{ it.paid_amount | smart_number(0) | ltr | safe }}</td>
|
|
<td class="num">{{ it.remaining | smart_number(0) | ltr | safe }}</td>
|
|
<td class="num">{{ it.late_fee_amount | smart_number(0) | ltr | safe }}</td>
|
|
<td class="num">{{ it.overdue_days | default('', true) | ltr | safe }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
|