Files
ACORE/templates/pages/reports-it-monthly.html
T
lokses 03019898b0 reports: КЕП-подпись PDF отчётов; задачи: загрузка вложений.
Добавлена офлайн/EndUser-подпись «ознакомлен и принял в работу» для документов отчётов и файловые вложения к задачам через Nextcloud.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-06 21:13:28 +03:00

275 lines
19 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 class="page-content">
<div style="margin-bottom:1rem;">
<a href="/reports/" hx-get="/reports/" hx-target="#main-content" hx-push-url="/reports/" hx-indicator="#loader"
style="font-size:0.8125rem; color:var(--color-muted-foreground); text-decoration:none;">← {% trans "Все отчёты" %}</a>
</div>
{% if reports_message %}
<div style="margin-bottom:1rem; padding:0.75rem 1rem; border-radius:0.5rem; background:color-mix(in srgb, var(--color-primary) 12%, transparent); font-size:0.875rem;">{{ reports_message }}</div>
{% endif %}
{% if reports_error %}
<div style="margin-bottom:1rem; padding:0.75rem 1rem; border-radius:0.5rem; background:color-mix(in srgb, #dc2626 12%, transparent); font-size:0.875rem; color:#b91c1c;">{{ reports_error }}</div>
{% endif %}
{% with report=report %}
<div style="display:flex; flex-wrap:wrap; align-items:flex-end; justify-content:space-between; gap:1rem; margin-bottom:1.25rem;">
<div>
<h1 style="font-size:1.25rem; font-weight:500; color:var(--color-foreground); margin:0;">{{ report.title }}</h1>
<p style="font-size:0.8125rem; color:var(--color-muted-foreground); margin:0.25rem 0 0;">
{% if show_live_report and report.period_from %}
{% trans "Период" %}: {{ report.period_from }} – {{ report.period_to }}
{% else %}
{% trans "Месяц" %}: {{ report.id }}
{% endif %}
{% if report_is_published %}
· <span style="color:var(--color-primary);">{% trans "Опубликован" %}</span>
{% elif can_publish_report %}
· <span style="color:var(--color-muted-foreground);">{% trans "Черновик — виден только руководителю" %}</span>
{% endif %}
</p>
{% if can_publish_report %}
<p style="font-size:0.75rem; color:var(--color-muted-foreground); margin:0.35rem 0 0; max-width:36rem;">
{% trans "Сформируйте Word, поправьте в редакторе, затем опубликуйте документ в «Документах отдела» — тогда отчёт увидит отдел." %}
</p>
{% endif %}
</div>
<div style="display:flex; flex-wrap:wrap; gap:0.5rem; align-items:center;">
<form method="get" action="/reports/it/monthly/"
hx-get="/reports/it/monthly/" hx-target="#main-content" hx-push-url="true" hx-indicator="#loader"
style="display:flex; gap:0.5rem; align-items:center; flex-wrap:wrap;">
<label for="report-month" style="font-size:0.8125rem; color:var(--color-muted-foreground);">{% trans "Месяц" %}</label>
<select name="month" id="report-month" class="input" onchange="this.form.requestSubmit()" style="min-width:9rem;">
{% for m in report.available_months %}
<option value="{{ m }}" {% if m == report.id %}selected{% endif %}>{{ m }}</option>
{% endfor %}
</select>
</form>
{% if can_publish_report %}
{% if report_is_published %}
<form method="post" action="/reports/it/monthly/{{ report.id }}/unpublish/" style="display:inline;">
{% csrf_token %}
<button type="submit" class="btn btn-secondary">{% trans "Снять с публикации" %}</button>
</form>
{% endif %}
{% if can_prepare_word %}
<form method="post" action="/reports/it/monthly/{{ report.id }}/publish/" style="display:inline;">
{% csrf_token %}
<button type="submit" class="btn btn-primary">{% trans "Сформировать Word" %}</button>
</form>
{% endif %}
{% endif %}
{% if show_live_report %}
<button type="button" class="btn btn-secondary"
onclick="itReportPreviewOpen('/reports/it/monthly/{{ report.id }}/preview/', '{{ report.title|escapejs }}')">
{% trans "Предпросмотр" %}
</button>
<a href="/reports/it/monthly/{{ report.id }}.pdf" class="btn btn-secondary">{% trans "Скачать PDF" %}</a>
<a href="/reports/it/monthly/{{ report.id }}.docx" class="btn btn-secondary">{% trans "Скачать Word" %}</a>
<a href="/reports/it/monthly/{{ report.id }}.md" class="btn btn-secondary" download>{% trans "Скачать Markdown" %}</a>
{% if can_manage_templates %}
<a href="/reports/templates/" hx-get="/reports/templates/" hx-target="#main-content" hx-push-url="/reports/templates/" hx-indicator="#loader"
class="btn btn-ghost" style="font-size:0.8125rem;">{% trans "Шаблон HTML-превью" %}</a>
{% endif %}
{% endif %}
{% if published_document %}
<a href="{% url 'report_document_download' published_document.pk %}" class="btn btn-primary">{% trans "Скачать опубликованный Word" %}</a>
<a href="{% url 'report_document_sign' published_document.pk %}"
hx-get="{% url 'report_document_sign' published_document.pk %}" hx-target="#main-content"
hx-push-url="{% url 'report_document_sign' published_document.pk %}" hx-indicator="#loader"
class="btn btn-secondary">{% trans "Подписать КЕП" %}</a>
{% if kep_signature %}
<a href="{% url 'report_document_signed_download' published_document.pk kep_signature.pk %}"
class="btn btn-ghost" style="font-size:0.8125rem;">{% trans "Подписанный PDF" %}</a>
{% endif %}
{% if show_live_report and onlyoffice_ready %}
<a href="/documents/edit/?report_doc={{ published_document.pk }}" class="btn btn-secondary">{% trans "Открыть Word" %}</a>
{% endif %}
{% endif %}
</div>
</div>
{% if not show_live_report %}
<div style="background:var(--color-card); border:1px solid var(--color-border); border-radius:0.75rem; padding:1.25rem;">
{% if published_document %}
<p style="margin:0 0 0.75rem; font-size:0.9375rem;">{% trans "Опубликованный файл отчёта:" %} <strong>{{ published_document.title }}</strong></p>
<div style="display:flex; flex-wrap:wrap; gap:0.5rem; align-items:center;">
<a href="{% url 'report_document_download' published_document.pk %}" class="btn btn-primary">{% trans "Скачать Word" %}</a>
<a href="{% url 'report_document_sign' published_document.pk %}"
hx-get="{% url 'report_document_sign' published_document.pk %}" hx-target="#main-content"
hx-push-url="{% url 'report_document_sign' published_document.pk %}" hx-indicator="#loader"
class="btn btn-secondary">{% trans "Подписать КЕП" %}</a>
{% if kep_signature %}
<span class="badge badge-success">{% trans "Подписано КЕП" %}</span>
<a href="{% url 'report_document_signed_download' published_document.pk kep_signature.pk %}"
class="btn btn-ghost" style="font-size:0.8125rem;">{% trans "Подписанный PDF" %}</a>
{% endif %}
</div>
{% else %}
<p style="margin:0; color:var(--color-muted-foreground);">{% trans "Опубликованный Word-файл для этого месяца пока не найден." %}</p>
{% endif %}
</div>
{% else %}
<div style="display:grid; grid-template-columns:repeat(4, 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.5rem; font-weight:500; color:var(--color-foreground);">{{ report.total_tasks }}</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.5rem; font-weight:500; color:var(--color-foreground);">{{ report.people_active }}</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.5rem; font-weight:500; color:var(--color-foreground);">{{ report.objects_count }}</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.5rem; font-weight:500; color:var(--color-foreground);">{{ report.summary|length }}</div>
</div>
</div>
<div style="display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,1fr); gap:1rem; margin-bottom:1.25rem;">
<div style="background:var(--color-card); border:1px solid var(--color-border); border-radius:0.75rem; padding:1rem 1.25rem;">
<h3 style="font-size:0.9375rem; font-weight:500; margin:0 0 0.75rem;">{% trans "Сводка по направлениям" %}</h3>
{% if report.summary %}
<ul style="list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:0.5rem;">
{% for row in report.summary %}
<li style="display:flex; justify-content:space-between; gap:1rem; font-size:0.875rem; border-bottom:1px solid var(--color-border); padding-bottom:0.5rem;">
<span>
<span style="color:var(--color-foreground);">{{ row.name }}</span>
{% if row.people %}<span style="color:var(--color-muted-foreground); font-size:0.75rem;"> — {{ row.people }}</span>{% endif %}
</span>
<strong style="color:var(--color-foreground);">{{ row.count }}</strong>
</li>
{% endfor %}
</ul>
{% else %}
<p style="color:var(--color-muted-foreground); font-size:0.875rem; margin:0;">{% trans "За выбранный месяц записей в журнале нет." %}</p>
{% endif %}
</div>
<div style="background:var(--color-card); border:1px solid var(--color-border); border-radius:0.75rem; padding:1rem 1.25rem;">
<h3 style="font-size:0.9375rem; font-weight:500; margin:0 0 0.75rem;">{% trans "Объекты" %}</h3>
{% if report.pharmacies %}
<p style="font-size:0.8125rem; margin:0 0 0.5rem;"><span style="color:var(--color-muted-foreground);">{% trans "Аптеки" %}:</span> {{ report.pharmacies|join:", " }}</p>
{% endif %}
{% if report.other_points %}
<p style="font-size:0.8125rem; margin:0 0 0.5rem;"><span style="color:var(--color-muted-foreground);">{% trans "Другие объекты" %}:</span> {{ report.other_points|join:", " }}</p>
{% endif %}
{% if not report.pharmacies and not report.other_points %}
<p style="color:var(--color-muted-foreground); font-size:0.875rem; margin:0;">{% trans "Объекты не указаны." %}</p>
{% endif %}
</div>
</div>
{% if report.conclusions %}
<div style="background:var(--color-card); border:1px solid var(--color-border); border-radius:0.75rem; padding:1rem 1.25rem; margin-bottom:1.25rem;">
<h3 style="font-size:0.9375rem; font-weight:500; margin:0 0 0.75rem;">{% trans "Основные выводы и рекомендации" %}</h3>
<div style="display:flex; flex-direction:column; gap:0.75rem;">
{% for item in report.conclusions %}
<div style="font-size:0.875rem; color:var(--color-foreground); line-height:1.45;">
<div>{{ item.text }}</div>
{% if item.bullets %}
<ul style="margin:0.375rem 0 0; padding-left:1.25rem; color:var(--color-muted-foreground); font-size:0.8125rem;">
{% for bullet in item.bullets %}
<li style="margin-bottom:0.2rem;">{{ bullet }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% for emp in report.employees %}
{% if emp.tasks or emp.systems %}
<div style="background:var(--color-card); border:1px solid var(--color-border); border-radius:0.75rem; padding:1rem 1.25rem; margin-bottom:0.75rem;">
<div style="display:flex; justify-content:space-between; gap:1rem; align-items:baseline; margin-bottom:0.75rem;">
<div>
<h3 style="font-size:0.9375rem; font-weight:500; margin:0;">{{ emp.name }}</h3>
{% if emp.role %}<div style="font-size:0.75rem; color:var(--color-muted-foreground);">{{ emp.role }}</div>{% endif %}
</div>
<div style="font-size:0.75rem; color:var(--color-muted-foreground); white-space:nowrap;">
{{ emp.tasks_count }} {% trans "работ" %}{% if emp.systems_count %} · {{ emp.systems_count }} {% trans "систем" %}{% endif %}
</div>
</div>
{% if emp.systems %}
<div style="margin-bottom:0.75rem;">
{% for sys in emp.systems %}
<div style="font-size:0.8125rem; margin-bottom:0.375rem;">
<strong>{{ sys.name }}</strong>
<span style="color:var(--color-muted-foreground);"> — {{ sys.work }}</span>
</div>
{% endfor %}
</div>
{% endif %}
{% if emp.tasks %}
<div style="overflow-x:auto;">
<table style="width:100%; border-collapse:collapse; font-size:0.8125rem;">
<thead>
<tr style="border-bottom:1px solid var(--color-border);">
<th style="padding:0.5rem 0.75rem 0.5rem 0; text-align:left; color:var(--color-muted-foreground); font-weight:600; width:6.5rem;">{% trans "Дата" %}</th>
<th style="padding:0.5rem 0.75rem; text-align:left; color:var(--color-muted-foreground); font-weight:600; width:4.5rem;">{% trans "Объект" %}</th>
<th style="padding:0.5rem 0; text-align:left; color:var(--color-muted-foreground); font-weight:600;">{% trans "Работы" %}</th>
</tr>
</thead>
<tbody>
{% for task in emp.tasks %}
<tr style="border-bottom:1px solid var(--color-border); vertical-align:top;">
<td style="padding:0.625rem 0.75rem 0.625rem 0; color:var(--color-muted-foreground); white-space:nowrap;">{{ task.date }}</td>
<td style="padding:0.625rem 0.75rem; color:var(--color-foreground); font-weight:500; white-space:nowrap;">{{ task.object|default:"—" }}</td>
<td style="padding:0.625rem 0; color:var(--color-foreground);">
{% if task.work_items|length > 1 %}
<ul style="margin:0; padding-left:1.1rem; display:flex; flex-direction:column; gap:0.2rem;">
{% for item in task.work_items %}
<li style="line-height:1.35;">{{ item }}</li>
{% endfor %}
</ul>
{% else %}
<span style="line-height:1.4;">{{ task.work }}</span>
{% endif %}
{% if task.ticket %} <span class="badge badge-muted">{{ task.ticket }}</span>{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
</div>
{% endif %}
{% empty %}
<p style="color:var(--color-muted-foreground);">{% trans "Нет данных для отчёта." %}</p>
{% endfor %}
<div id="it-report-preview-overlay" onclick="itReportPreviewClose()"
style="display:none; position:fixed; inset:0; background:rgba(15,23,42,0.55); z-index:1100;"></div>
<div id="it-report-preview-modal" role="dialog" aria-modal="true" aria-labelledby="it-report-preview-title"
onclick="itReportPreviewClose()"
style="display:none; position:fixed; inset:0; z-index:1101; padding:1.25rem; box-sizing:border-box; align-items:center; justify-content:center;">
<div style="width:min(920px, 96vw); height:min(90vh, 980px); background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 24px 64px rgba(0,0,0,0.28); display:flex; flex-direction:column; overflow:hidden;"
onclick="event.stopPropagation()">
<div style="display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:0.75rem 1rem; border-bottom:1px solid var(--color-border); flex-shrink:0;">
<div>
<div id="it-report-preview-title" style="font-size:0.9375rem; font-weight:500; color:var(--color-foreground);">{% trans "Предпросмотр отчёта" %}</div>
<div id="it-report-preview-subtitle" style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.125rem;"></div>
</div>
<div style="display:flex; gap:0.5rem; align-items:center;">
<a id="it-report-preview-open-tab" href="#" target="_blank" rel="noopener" class="btn btn-ghost" style="font-size:0.8125rem;">{% trans "В новой вкладке" %}</a>
<button type="button" class="btn btn-ghost btn-icon" onclick="itReportPreviewClose()" aria-label="{% trans 'Закрыть' %}">✕</button>
</div>
</div>
<div style="flex:1; min-height:0; background:#e8edf4;">
<iframe id="it-report-preview-frame" title="{% trans 'Предпросмотр отчёта' %}"
style="width:100%; height:100%; border:0; background:#e8edf4;"></iframe>
</div>
</div>
</div>
{% endif %}
{% endwith %}
</div>