2025-08-12 13:33:25 +03:00

406 lines
20 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}{% if object %}Edit Delivery Log{% else %}New Delivery Log{% endif %}{% endblock %}
{% block content %}
<div class="d-flex align-items-center mb-3">
<div>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'communications:dashboard' %}">Communications</a></li>
<li class="breadcrumb-item"><a href="{% url 'communications:delivery_log_list' %}">Delivery Logs</a></li>
<li class="breadcrumb-item active">{% if object %}Edit{% else %}New{% endif %}</li>
</ol>
<h1 class="page-header mb-0">
{% if object %}Edit Delivery Log{% else %}Create Delivery Log{% endif %}
</h1>
</div>
<div class="ms-auto">
<a href="{% url 'communications:delivery_log_list' %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Back to List
</a>
</div>
</div>
<div class="row">
<div class="col-xl-8">
<div class="card">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-shipping-fast me-2"></i>
Delivery Log Details
</h4>
</div>
<div class="card-body">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
<form method="post" novalidate>
{% csrf_token %}
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.message.id_for_label }}" class="form-label">Message *</label>
<select class="form-select {% if form.message.errors %}is-invalid{% endif %}"
id="{{ form.message.id_for_label }}"
name="{{ form.message.name }}"
required>
<option value="">Select Message</option>
{% for choice in form.message.field.choices %}
{% if choice.0 %}
<option value="{{ choice.0 }}" {% if choice.0 == form.message.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endif %}
{% endfor %}
</select>
{% if form.message.errors %}
<div class="invalid-feedback">
{{ form.message.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.recipient.id_for_label }}" class="form-label">Recipient *</label>
<input type="text"
class="form-control {% if form.recipient.errors %}is-invalid{% endif %}"
id="{{ form.recipient.id_for_label }}"
name="{{ form.recipient.name }}"
value="{{ form.recipient.value|default:'' }}"
placeholder="Enter recipient email or phone"
required>
{% if form.recipient.errors %}
<div class="invalid-feedback">
{{ form.recipient.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.delivery_method.id_for_label }}" class="form-label">Delivery Method *</label>
<select class="form-select {% if form.delivery_method.errors %}is-invalid{% endif %}"
id="{{ form.delivery_method.id_for_label }}"
name="{{ form.delivery_method.name }}"
required>
{% for choice in form.delivery_method.field.choices %}
<option value="{{ choice.0 }}" {% if choice.0 == form.delivery_method.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
{% if form.delivery_method.errors %}
<div class="invalid-feedback">
{{ form.delivery_method.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.status.id_for_label }}" class="form-label">Status *</label>
<select class="form-select {% if form.status.errors %}is-invalid{% endif %}"
id="{{ form.status.id_for_label }}"
name="{{ form.status.name }}"
required>
{% for choice in form.status.field.choices %}
<option value="{{ choice.0 }}" {% if choice.0 == form.status.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
{% if form.status.errors %}
<div class="invalid-feedback">
{{ form.status.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.sent_at.id_for_label }}" class="form-label">Sent At</label>
<input type="datetime-local"
class="form-control {% if form.sent_at.errors %}is-invalid{% endif %}"
id="{{ form.sent_at.id_for_label }}"
name="{{ form.sent_at.name }}"
value="{{ form.sent_at.value|default:'' }}">
{% if form.sent_at.errors %}
<div class="invalid-feedback">
{{ form.sent_at.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.delivered_at.id_for_label }}" class="form-label">Delivered At</label>
<input type="datetime-local"
class="form-control {% if form.delivered_at.errors %}is-invalid{% endif %}"
id="{{ form.delivered_at.id_for_label }}"
name="{{ form.delivered_at.name }}"
value="{{ form.delivered_at.value|default:'' }}">
{% if form.delivered_at.errors %}
<div class="invalid-feedback">
{{ form.delivered_at.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.error_message.id_for_label }}" class="form-label">Error Message</label>
<textarea class="form-control {% if form.error_message.errors %}is-invalid{% endif %}"
id="{{ form.error_message.id_for_label }}"
name="{{ form.error_message.name }}"
rows="3"
placeholder="Enter any error messages or delivery issues...">{{ form.error_message.value|default:'' }}</textarea>
{% if form.error_message.errors %}
<div class="invalid-feedback">
{{ form.error_message.errors.0 }}
</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.retry_count.id_for_label }}" class="form-label">Retry Count</label>
<input type="number"
class="form-control {% if form.retry_count.errors %}is-invalid{% endif %}"
id="{{ form.retry_count.id_for_label }}"
name="{{ form.retry_count.name }}"
value="{{ form.retry_count.value|default:'0' }}"
min="0"
max="10">
{% if form.retry_count.errors %}
<div class="invalid-feedback">
{{ form.retry_count.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.next_retry_at.id_for_label }}" class="form-label">Next Retry At</label>
<input type="datetime-local"
class="form-control {% if form.next_retry_at.errors %}is-invalid{% endif %}"
id="{{ form.next_retry_at.id_for_label }}"
name="{{ form.next_retry_at.name }}"
value="{{ form.next_retry_at.value|default:'' }}">
{% if form.next_retry_at.errors %}
<div class="invalid-feedback">
{{ form.next_retry_at.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.delivery_details.id_for_label }}" class="form-label">Delivery Details</label>
<textarea class="form-control {% if form.delivery_details.errors %}is-invalid{% endif %}"
id="{{ form.delivery_details.id_for_label }}"
name="{{ form.delivery_details.name }}"
rows="4"
placeholder="Additional delivery details, tracking information, etc...">{{ form.delivery_details.value|default:'' }}</textarea>
{% if form.delivery_details.errors %}
<div class="invalid-feedback">
{{ form.delivery_details.errors.0 }}
</div>
{% endif %}
</div>
<div class="d-flex justify-content-between">
<div>
{% if object %}
<a href="{% url 'communications:delivery_log_detail' object.pk %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Cancel
</a>
{% else %}
<a href="{% url 'communications:delivery_log_list' %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Cancel
</a>
{% endif %}
</div>
<div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-2"></i>
{% if object %}Update Log{% else %}Create Log{% endif %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-xl-4">
<!-- Delivery Status Guide -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-info-circle me-2"></i>
Delivery Status Guide
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<span class="badge bg-warning me-2">Pending</span>
<small>Message queued for delivery</small>
</div>
<div class="mb-3">
<span class="badge bg-info me-2">Sending</span>
<small>Currently being sent</small>
</div>
<div class="mb-3">
<span class="badge bg-success me-2">Delivered</span>
<small>Successfully delivered</small>
</div>
<div class="mb-3">
<span class="badge bg-danger me-2">Failed</span>
<small>Delivery failed</small>
</div>
<div>
<span class="badge bg-secondary me-2">Cancelled</span>
<small>Delivery cancelled</small>
</div>
</div>
</div>
<!-- Delivery Methods -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-paper-plane me-2"></i>
Delivery Methods
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<i class="fas fa-envelope text-primary me-2"></i>
<strong>Email</strong>
<div class="small text-muted">Standard email delivery</div>
</div>
<div class="mb-3">
<i class="fas fa-sms text-success me-2"></i>
<strong>SMS</strong>
<div class="small text-muted">Text message delivery</div>
</div>
<div class="mb-3">
<i class="fas fa-bell text-warning me-2"></i>
<strong>Push</strong>
<div class="small text-muted">Push notification</div>
</div>
<div>
<i class="fas fa-globe text-info me-2"></i>
<strong>Web</strong>
<div class="small text-muted">In-app notification</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="card">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-bolt me-2"></i>
Quick Actions
</h5>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-outline-primary btn-sm" onclick="setCurrentTime('sent_at')">
<i class="fas fa-clock me-2"></i>Set Current Time (Sent)
</button>
<button type="button" class="btn btn-outline-success btn-sm" onclick="setCurrentTime('delivered_at')">
<i class="fas fa-check me-2"></i>Mark as Delivered Now
</button>
<button type="button" class="btn btn-outline-warning btn-sm" onclick="scheduleRetry()">
<i class="fas fa-redo me-2"></i>Schedule Retry
</button>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const statusSelect = document.getElementById('{{ form.status.id_for_label }}');
const errorMessageField = document.getElementById('{{ form.error_message.id_for_label }}');
const retryFields = ['{{ form.retry_count.id_for_label }}', '{{ form.next_retry_at.id_for_label }}'];
// Show/hide fields based on status
function toggleFieldsBasedOnStatus() {
const status = statusSelect.value;
if (status === 'failed') {
errorMessageField.parentElement.style.display = 'block';
retryFields.forEach(fieldId => {
document.getElementById(fieldId).parentElement.parentElement.style.display = 'block';
});
} else if (status === 'delivered') {
errorMessageField.parentElement.style.display = 'none';
errorMessageField.value = '';
}
}
statusSelect.addEventListener('change', toggleFieldsBasedOnStatus);
toggleFieldsBasedOnStatus(); // Initial call
// Auto-set delivered time when status changes to delivered
statusSelect.addEventListener('change', function() {
if (this.value === 'delivered') {
const deliveredAtField = document.getElementById('{{ form.delivered_at.id_for_label }}');
if (!deliveredAtField.value) {
setCurrentTime('delivered_at');
}
}
});
});
function setCurrentTime(fieldSuffix) {
const now = new Date();
const isoString = now.toISOString().slice(0, 16); // Format for datetime-local
const field = document.getElementById(`{{ form.${fieldSuffix}.id_for_label }}`.replace('${fieldSuffix}', fieldSuffix));
if (field) {
field.value = isoString;
}
}
function scheduleRetry() {
const retryCountField = document.getElementById('{{ form.retry_count.id_for_label }}');
const nextRetryField = document.getElementById('{{ form.next_retry_at.id_for_label }}');
// Increment retry count
const currentCount = parseInt(retryCountField.value) || 0;
retryCountField.value = currentCount + 1;
// Set next retry time (15 minutes from now)
const nextRetry = new Date();
nextRetry.setMinutes(nextRetry.getMinutes() + 15);
nextRetryField.value = nextRetry.toISOString().slice(0, 16);
// Set status to pending
document.getElementById('{{ form.status.id_for_label }}').value = 'pending';
}
</script>
{% endblock %}