Files
ACORE/templates/pages/internet-billing.html
T
lokses 0da9c13192 it_manager+reports: иерархия договоров, биллинг и месячные отчёты
Иерархия рамочных/дочерних договоров и платежей, интернет-биллинг,
месячные IT-отчёты (импорт, DOCX/PDF, шаблоны выводов).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-09 18:03:44 +03:00

155 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% load i18n %}
<div id="internet-billing-panel">
{% if billing_form_message %}
<div style="margin-bottom:1rem; padding:0.75rem 1rem; border-radius:0.5rem; border:1px solid hsl(152 40% 70%); background:color-mix(in srgb, var(--color-success) 12%, var(--color-card)); color:var(--color-foreground); font-size:0.875rem;">
{{ billing_form_message }}
</div>
{% endif %}
{% if billing_form_error %}
<div style="margin-bottom:1rem; padding:0.75rem 1rem; border-radius:0.5rem; background:hsl(0 70% 96%); border:1px solid hsl(0 70% 85%); color:hsl(0 55% 35%); font-size:0.8125rem;">
{{ billing_form_error }}
</div>
{% endif %}
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:1rem; flex-wrap:wrap; gap:0.75rem;">
<div style="display:flex; align-items:center; gap:0.5rem;">
<a href="#" class="btn btn-ghost btn-icon"
{% if accounting_embed %}hx-get="{{ accounting_base_url }}&month={{ billing_prev_month }}{% if billing_filter_provider %}&provider={{ billing_filter_provider }}{% endif %}"
{% else %}hx-get="/accounting/?tab=internet&month={{ billing_prev_month }}"{% endif %}
hx-target="#main-content" hx-push-url="true" hx-indicator="#loader">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>
</a>
<span style="font-size:0.9375rem; font-weight:500; color:var(--color-foreground); min-width:9rem; text-align:center;">{{ billing_period_label }}</span>
<a href="#" class="btn btn-ghost btn-icon"
{% if accounting_embed %}hx-get="{{ accounting_base_url }}&month={{ billing_next_month }}{% if billing_filter_provider %}&provider={{ billing_filter_provider }}{% endif %}"
{% else %}hx-get="/accounting/?tab=internet&month={{ billing_next_month }}"{% endif %}
hx-target="#main-content" hx-push-url="true" hx-indicator="#loader">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
</a>
</div>
<form method="get"
{% if accounting_embed %}hx-get="{{ accounting_base_url }}"{% else %}hx-get="/accounting/?tab=internet"{% endif %}
hx-target="#main-content" hx-push-url="true" hx-indicator="#loader"
style="display:flex; align-items:center; gap:0.5rem;">
<input type="hidden" name="tab" value="internet">
<input type="hidden" name="month" value="{{ billing_period }}">
<select name="provider" class="input" style="min-width:14rem;" onchange="this.form.requestSubmit()">
<option value="">{% trans "Все провайдеры" %}</option>
{% for p in billing_providers %}
<option value="{{ p.pk }}" {% if billing_filter_provider == p.pk|stringformat:"s" %}selected{% endif %}>{{ p.name }}</option>
{% endfor %}
</select>
</form>
</div>
<div style="display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:0.75rem; margin-bottom:1.25rem;">
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "К оплате" %}</div>
<div style="font-size:1.375rem; font-weight:600; color:var(--color-foreground);">{{ billing_total_amount|default:"0" }} {% trans "грн" %}</div>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.25rem;">{{ billing_contract_count }} {% trans "договоров" %}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Оплачено" %}</div>
<div style="font-size:1.375rem; font-weight:600; color:var(--color-success);">{{ billing_paid_amount|default:"0" }} {% trans "грн" %}</div>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.25rem;">{{ billing_paid_count }} {% trans "договоров" %}</div>
</div>
<div class="stat-card" style="padding:1rem 1.25rem;">
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.375rem;">{% trans "Не оплачено" %}</div>
<div style="font-size:1.375rem; font-weight:600; color:{% if billing_unpaid_count %}var(--color-destructive){% else %}var(--color-foreground){% endif %};">{{ billing_unpaid_count }}</div>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.25rem;">{% trans "договоров" %}</div>
</div>
</div>
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden;">
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.875rem;">
<thead>
<tr style="border-bottom:1px solid var(--color-border);">
<th style="padding:0.75rem 1rem; text-align:left; color:var(--color-muted-foreground); font-weight:600; font-size:0.8125rem;">{% trans "Договор / локация" %}</th>
<th style="padding:0.75rem 1rem; text-align:left; color:var(--color-muted-foreground); font-weight:600; font-size:0.8125rem;">{% trans "Провайдер" %}</th>
<th style="padding:0.75rem 1rem; text-align:right; color:var(--color-muted-foreground); font-weight:600; font-size:0.8125rem;">{% trans "Сумма" %}</th>
<th style="padding:0.75rem 1rem; text-align:center; color:var(--color-muted-foreground); font-weight:600; font-size:0.8125rem;">{% trans "Статус" %}</th>
<th style="padding:0.75rem 1rem; text-align:left; color:var(--color-muted-foreground); font-weight:600; font-size:0.8125rem;">{% trans "Счёт" %}</th>
<th style="padding:0.75rem 1rem; text-align:right; color:var(--color-muted-foreground); font-weight:600; font-size:0.8125rem;"></th>
</tr>
</thead>
<tbody>
{% for row in billing_rows %}
{% if row.is_provider_header %}
<tr style="background:color-mix(in srgb, var(--color-muted) 65%, var(--color-card)); border-bottom:1px solid var(--color-border);">
<td colspan="6" style="padding:0.625rem 1rem; font-size:0.8125rem; font-weight:600; color:var(--color-foreground); letter-spacing:0.02em;">
{{ row.provider.name }}
</td>
</tr>
{% else %}
{% with c=row.contract %}
<tr style="border-bottom:1px solid var(--color-border);{% if row.is_paid %} background:color-mix(in srgb, var(--color-success) 6%, transparent);{% elif row.is_framework %} background:color-mix(in srgb, var(--color-muted) 35%, transparent);{% elif row.indent %} background:color-mix(in srgb, var(--color-muted) 18%, transparent);{% endif %}">
<td style="padding:0.75rem 1rem; color:var(--color-foreground);">
<div style="display:flex; align-items:flex-start; gap:0.5rem; padding-left:{{ row.indent_rem }}rem;">
{% if row.indent %}
<span style="flex:none; width:1rem; color:var(--color-muted-foreground); font-size:0.875rem; line-height:1.35;">└</span>
{% elif row.is_framework and row.has_children %}
<span style="flex:none; width:1rem; color:var(--color-primary); font-size:0.75rem; line-height:1.5;">▾</span>
{% else %}
<span style="flex:none; width:1rem;"></span>
{% endif %}
<div style="min-width:0;{% if row.indent %} border-left:2px solid color-mix(in srgb, var(--color-border) 80%, var(--color-primary)); padding-left:0.75rem;{% endif %}">
{% if row.is_framework %}
<span class="badge badge-info" style="font-size:0.6875rem; margin-right:0.35rem;">{% trans "Общий" %}</span>
{% endif %}
<strong>№{{ c.contract_number }}</strong>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.125rem;">{{ c.location_display }}</div>
{% if row.has_children %}
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); margin-top:0.2rem;">{% trans "группа договоров" %}</div>
{% endif %}
</div>
</div>
</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground);">
{% if row.indent %}—{% else %}{{ c.provider.name }}{% endif %}
</td>
<td style="padding:0.75rem 1rem; text-align:right; color:var(--color-foreground); font-weight:500;">
{{ row.amount|default:"—" }}{% if row.amount %} {% trans "грн" %}{% endif %}
</td>
<td style="padding:0.75rem 1rem; text-align:center;">
{% if row.is_paid %}
<span class="badge badge-success">{% trans "Оплачено" %}</span>
{% if row.payment.paid_at %}
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); margin-top:0.125rem;">{{ row.payment.paid_at|date:"d.m.Y" }}</div>
{% endif %}
{% else %}
<span class="badge badge-warning">{% trans "Не оплачено" %}</span>
{% endif %}
</td>
<td style="padding:0.75rem 1rem; color:var(--color-muted-foreground); font-size:0.8125rem;">
{{ row.payment.invoice_number|default:"—" }}
</td>
<td style="padding:0.75rem 1rem; text-align:right;">
<form method="post" action="/accounting/internet-payment/" hx-post="/accounting/internet-payment/" hx-target="#main-content" hx-indicator="#loader" style="display:inline-flex; gap:0.35rem; align-items:center; margin:0;">
{% csrf_token %}
<input type="hidden" name="month" value="{{ billing_period }}">
<input type="hidden" name="contract_id" value="{{ c.pk }}">
<input type="hidden" name="action" value="{% if row.is_paid %}mark_unpaid{% else %}mark_paid{% endif %}">
{% if billing_filter_provider %}<input type="hidden" name="provider" value="{{ billing_filter_provider }}">{% endif %}
<button type="submit" class="btn {% if row.is_paid %}btn-secondary{% else %}btn-primary{% endif %}" style="font-size:0.75rem; padding:0.35rem 0.65rem;">
{% if row.is_paid %}{% trans "Снять оплату" %}{% else %}{% trans "Отметить оплату" %}{% endif %}
</button>
</form>
</td>
</tr>
{% endwith %}
{% endif %}
{% empty %}
<tr>
<td colspan="6" style="padding:2rem; text-align:center; color:var(--color-muted-foreground);">
{% trans "Нет активных договоров для учёта оплат." %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>