Enhanced quarterly confirmation system with approval workflow and export improvements

Features added:
-  Fixed quarterly confirmation approval system with URL pattern
-  Added re-approval and status reset functionality for quarterly confirmations
-  Synchronized quarterly approval status with support payment system
-  Enhanced Destinataer export with missing fields (anrede, titel, mobil)
-  Added quarterly confirmation data and documents to export system
-  Fixed address field display issues in destinataer template
-  Added quarterly statistics dashboard to support payment lists
-  Implemented duplicate support payment prevention and cleanup
-  Added visual indicators for quarterly-linked support payments

Technical improvements:
- Enhanced create_quarterly_support_payment() with duplicate detection
- Added get_related_support_payment() method to VierteljahresNachweis model
- Improved quarterly confirmation workflow with proper status transitions
- Added computed address property to Destinataer model
- Fixed template field mismatches (anrede, titel, mobil vs strasse, plz, ort)
- Enhanced backup system with operation tracking and cancellation

Workflow enhancements:
- Quarterly confirmations now properly sync with support payments
- Single support payment per destinataer per quarter (no duplicates)
- Approval button works for both eingereicht and geprueft status
- Reset functionality allows workflow restart
- Export includes complete quarterly data with uploaded documents
This commit is contained in:
2025-09-28 19:09:08 +02:00
parent b00cf62d87
commit acac8695fd
73 changed files with 283380 additions and 206 deletions

View File

@@ -101,6 +101,7 @@
<thead>
<tr>
<th>Erstellt</th>
<th>Vorgang</th>
<th>Typ</th>
<th>Status</th>
<th>Größe</th>
@@ -117,10 +118,19 @@
<small class="text-muted">{{ backup.created_at|date:"H:i:s" }}</small>
</td>
<td>
<span class="badge bg-info">{{ backup.get_backup_type_display }}</span>
<span class="badge bg-{% if backup.operation == 'backup' %}info{% else %}warning{% endif %}">
{% if backup.operation == 'backup' %}
<i class="fas fa-save me-1"></i>Backup
{% else %}
<i class="fas fa-undo me-1"></i>Restore
{% endif %}
</span>
</td>
<td>
<span class="badge bg-{% if backup.status == 'completed' %}success{% elif backup.status == 'failed' %}danger{% elif backup.status == 'running' %}primary{% else %}secondary{% endif %}">
<span class="badge bg-secondary">{{ backup.get_backup_type_display }}</span>
</td>
<td>
<span class="badge bg-{% if backup.status == 'completed' %}success{% elif backup.status == 'failed' %}danger{% elif backup.status == 'running' %}primary{% elif backup.status == 'cancelled' %}warning{% else %}secondary{% endif %}">
{{ backup.get_status_display }}
</span>
{% if backup.status == 'running' %}
@@ -153,7 +163,7 @@
{% endif %}
</td>
<td>
{% if backup.status == 'completed' %}
{% if backup.status == 'completed' and backup.operation == 'backup' %}
<a href="{% url 'stiftung:backup_download' backup.id %}" class="btn btn-outline-primary btn-sm" title="Herunterladen">
<i class="fas fa-download"></i>
</a>
@@ -162,9 +172,27 @@
<i class="fas fa-exclamation-triangle"></i>
</button>
{% elif backup.status == 'running' %}
<button class="btn btn-outline-primary btn-sm" disabled title="Läuft...">
<i class="fas fa-spinner fa-spin"></i>
</button>
<div class="btn-group" role="group">
<button class="btn btn-outline-primary btn-sm" disabled title="Läuft...">
<i class="fas fa-spinner fa-spin"></i>
</button>
{% if backup.created_by == request.user or request.user.is_staff %}
<a href="{% url 'stiftung:backup_cancel' backup.id %}"
class="btn btn-outline-danger btn-sm"
onclick="return confirm('Sind Sie sicher, dass Sie diesen Backup-Job abbrechen möchten?')"
title="Abbrechen">
<i class="fas fa-times"></i>
</a>
{% endif %}
</div>
{% elif backup.status == 'cancelled' %}
<span class="badge bg-warning" title="Abgebrochen">
<i class="fas fa-ban"></i> Abgebrochen
</span>
{% elif backup.status == 'completed' and backup.operation == 'restore' %}
<span class="badge bg-success" title="Wiederherstellung abgeschlossen">
<i class="fas fa-check"></i> Fertig
</span>
{% else %}
<span class="text-muted">-</span>
{% endif %}