81 lines
9.3 KiB
HTML
81 lines
9.3 KiB
HTML
{% extends 'base.html' %}{% load jalali %}
|
||
{% block title %}{{ dispatch.subject }}{% endblock %}
|
||
{% block content %}
|
||
<div class="operations-page operations-dispatch-detail">
|
||
<section class="dispatch-report-hero">
|
||
<div class="dispatch-report-title">
|
||
<div class="dispatch-title-line"><span class="report-status status-{{ dispatch.status|lower }}">{{ dispatch.get_status_display }}</span><span class="eyebrow">گزارش ارسال گروهی</span></div>
|
||
<h1>{{ dispatch.subject }}</h1>
|
||
<div class="dispatch-meta-list">
|
||
<span><b>واحد</b>{{ dispatch.unit }}</span>
|
||
<span><b>گروه مخاطبان</b>{{ dispatch.contact_group.name }}</span>
|
||
<span><b>تعداد گیرندگان</b>{{ dispatch.recipient_count }} نفر</span>
|
||
<span><b>زمان ایجاد</b><time datetime="{{ dispatch.created_at|date:'c' }}">{{ dispatch.created_at|jalali_datetime }}</time></span>
|
||
</div>
|
||
</div>
|
||
<div class="dispatch-head-actions">
|
||
<a class="button" href="{% url 'staff_tickets:dispatch_create' %}">+ ارسال گروهی جدید</a>
|
||
{% if metrics.failed %}<form method="post" action="{% url 'staff_tickets:dispatch_retry' dispatch.public_id %}">{% csrf_token %}<button class="button button-danger-soft" type="submit">↻ تلاش مجدد {{ metrics.failed }} پیامک</button></form>{% endif %}
|
||
</div>
|
||
</section>
|
||
|
||
<section class="dispatch-original-message" aria-labelledby="dispatch-message-title">
|
||
<header><div><span class="panel-index">متن اولیه کارشناس</span><h2 id="dispatch-message-title">پیام اصلی این ارسال</h2></div><span>شناسه عملیات: <b dir="ltr">{{ dispatch.public_id }}</b></span></header>
|
||
<blockquote>{{ dispatch.body|linebreaksbr }}</blockquote>
|
||
<footer><span>ایجادکننده: <b>{{ dispatch.created_by.staff_profile.display_name|default:dispatch.created_by.username }}</b></span><span>این متن در یک تیکت مستقل برای هر مخاطب ثبت شده است.</span></footer>
|
||
</section>
|
||
|
||
<section class="delivery-overview" aria-label="خلاصه دلیوری">
|
||
<div class="delivery-progress-copy"><div><span class="panel-index">پیشرفت تحویل</span><strong>{{ metrics.delivery_percent }}٪</strong></div><p>{{ metrics.delivered }} از {{ dispatch.recipient_count }} پیامک تحویل قطعی شده است.</p></div>
|
||
<div class="delivery-progress-track" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="{{ metrics.delivery_percent }}"><span style="width:{{ metrics.delivery_percent }}%"></span></div>
|
||
<div class="delivery-overview-note">{% if metrics.tracking %}<b>{{ metrics.tracking }} پیامک در حال پیگیری است</b><span>نتیجههای موقت هر ۳ دقیقه تا ۴۵ دقیقه دوباره استعلام میشوند.</span>{% elif metrics.failed %}<b>موارد ناموفق نیاز به بررسی دارند</b><span>علت دقیق و دکمه تلاش مجدد در ردیف مخاطب قرار دارد.</span>{% else %}<b>پردازش صف پایان یافته است</b><span>برای جزئیات هر مخاطب، گزارش پایین صفحه را ببینید.</span>{% endif %}</div>
|
||
</section>
|
||
|
||
<section class="dispatch-kpi-grid" aria-label="شاخصهای ارسال گروهی">
|
||
<article class="dispatch-kpi kpi-success"><span class="kpi-icon">✓</span><div><small>تحویل قطعی</small><strong>{{ metrics.delivered }}</strong><p>رسیده به گوشی</p></div></article>
|
||
<article class="dispatch-kpi kpi-info"><span class="kpi-icon">◌</span><div><small>پیگیری فعال</small><strong>{{ metrics.tracking }}</strong><p>{{ metrics.sent }} مورد پذیرفتهشده توسط درگاه</p></div></article>
|
||
<article class="dispatch-kpi kpi-danger"><span class="kpi-icon">!</span><div><small>نیازمند اقدام</small><strong>{{ metrics.failed }}</strong><p>ناموفق یا تحویلنشده قطعی</p></div></article>
|
||
<article class="dispatch-kpi kpi-view"><span class="kpi-icon">◉</span><div><small>تعامل با لینک</small><strong>{{ metrics.opened }}</strong><p>{{ metrics.total_views }} بازدید · {{ metrics.not_opened }} مخاطب بدون بازدید</p></div></article>
|
||
<article class="dispatch-kpi kpi-reply"><span class="kpi-icon">↵</span><div><small>پاسخ دریافتی</small><strong>{{ metrics.replied }}</strong><p>پاسخ ثبتشده در تیکتها</p></div></article>
|
||
</section>
|
||
|
||
<section class="ticket-stream dispatch-recipient-report">
|
||
<header class="stream-head"><div><span class="panel-index">جزئیات هر گیرنده</span><h2>وضعیت پیامک، مشاهده و پاسخ</h2></div><span>{{ dispatch.recipient_count }} مخاطب</span></header>
|
||
<div class="table-scroll"><table class="dispatch-detail-table"><thead><tr><th>مخاطب</th><th>تیکت</th><th>وضعیت پیامک</th><th>وضعیت تیکت</th><th>مشاهده لینک</th><th>آخرین پاسخ</th></tr></thead><tbody>
|
||
{% for ticket in tickets %}
|
||
<tr>
|
||
<td data-label="مخاطب"><div class="recipient-cell"><span class="recipient-avatar">{{ ticket.customer.customer_profile.first_name|first|default:'•' }}</span><div><strong>{{ ticket.customer.customer_profile|default:ticket.customer.username }}</strong><small dir="ltr">{{ ticket.customer.local_mobile }}</small></div></div></td>
|
||
<td data-label="تیکت"><a class="ticket-reference" href="{% url 'staff_tickets:detail' ticket.public_id %}"><strong dir="ltr">{{ ticket.ticket_number }}</strong><span>مشاهده تیکت ←</span></a></td>
|
||
<td data-label="وضعیت پیامک" class="dispatch-sms-state">
|
||
<div class="sms-state-card tone-{{ ticket.sms_state_tone }}">
|
||
<span class="sms-state-icon">{% if ticket.sms_state_tone == 'success' %}✓{% elif ticket.sms_state_tone == 'danger' %}!{% elif ticket.sms_state_tone == 'warning' %}◌{% else %}↑{% endif %}</span>
|
||
<div><strong>{{ ticket.sms_state_title }}</strong><p>{{ ticket.sms_state_hint }}</p>{% if ticket.sms_job.delivery_next_check_at %}<small>استعلام بعدی: {{ ticket.sms_job.delivery_next_check_at|timeuntil }} دیگر</small>{% endif %}</div>
|
||
</div>
|
||
{% if ticket.sms_job %}
|
||
<details class="sms-technical-details">
|
||
<summary>جزئیات فنی و رهگیری</summary>
|
||
<dl>
|
||
<div><dt>ارسال</dt><dd>{% if ticket.sms_job.attempts == 1 %}موفق در اولین تلاش{% else %}{{ ticket.sms_job.attempts }} تلاش از {{ sms_max_attempts }}{% endif %}</dd></div>
|
||
{% if ticket.sms_job.provider_message_id %}<div><dt>شناسه رهگیری</dt><dd dir="ltr">{{ ticket.sms_job.provider_message_id }}</dd></div>{% endif %}
|
||
{% if ticket.sms_job.delivery_status_code %}<div><dt>کد دلیوری</dt><dd dir="ltr">{{ ticket.sms_job.delivery_status_code }}</dd></div>{% endif %}
|
||
{% if ticket.sms_job.delivery_check_attempts %}<div><dt>تعداد استعلام</dt><dd>{{ ticket.sms_job.delivery_check_attempts }} نوبت</dd></div>{% endif %}
|
||
{% if ticket.sms_job.delivery_checked_at %}<div><dt>آخرین استعلام</dt><dd>{{ ticket.sms_job.delivery_checked_at|jalali_datetime }}</dd></div>{% endif %}
|
||
</dl>
|
||
{% if ticket.sms_job.delivery_description %}<p class="gateway-technical-message">{{ ticket.sms_job.delivery_description }}</p>{% endif %}
|
||
</details>
|
||
{% if ticket.sms_job.last_error %}<div class="sms-error-panel"><b>علت دقیق عدم ارسال</b><p>{{ ticket.sms_job.last_error }}</p></div>{% endif %}
|
||
{% if ticket.sms_retryable %}<form method="post" action="{% url 'staff_tickets:dispatch_retry' dispatch.public_id %}" class="inline-retry-form">{% csrf_token %}<input type="hidden" name="job_id" value="{{ ticket.sms_job.pk }}"><button type="submit">↻ تلاش مجدد همین پیامک</button></form>{% endif %}
|
||
{% endif %}
|
||
</td>
|
||
<td data-label="وضعیت تیکت"><span class="ticket-state-pill state-{{ ticket.status|lower }}">{{ ticket.get_status_display }}</span></td>
|
||
<td data-label="مشاهده لینک">
|
||
<div class="engagement-state {% if ticket.magic_total_views %}has-engagement{% endif %}"><span>{% if ticket.magic_total_views %}◉{% else %}○{% endif %}</span><div>{% if ticket.magic_total_views %}<strong>{{ ticket.magic_total_views }} بازدید</strong>{% if ticket.magic_last_used_at %}<small>آخرین بازدید {{ ticket.magic_last_used_at|jalali_datetime }}</small>{% endif %}{% elif ticket.magic_link_count %}<strong>مشاهده نشده</strong><small>{{ ticket.magic_active_count }} لینک فعال</small>{% else %}<strong>لینک صادر نشده</strong>{% endif %}</div></div>
|
||
</td>
|
||
<td data-label="آخرین پاسخ">{% if ticket.latest_customer_response %}<div class="recipient-reply"><p>{{ ticket.latest_customer_response.body|truncatechars:140 }}</p><small>{{ ticket.latest_customer_response.created_at|jalali_datetime }}</small></div>{% else %}<span class="no-reply-state">هنوز پاسخی ثبت نشده</span>{% endif %}</td>
|
||
</tr>
|
||
{% empty %}<tr><td colspan="6">برای این ارسال تیکتی ثبت نشده است.</td></tr>{% endfor %}
|
||
</tbody></table></div>
|
||
</section>
|
||
</div>
|
||
{% endblock %}
|