Fix payment system balance integration and add calendar functionality

- Implement automated payment tracking with Django signals
- Fix duplicate transaction creation with unique referenz system
- Add calendar system with CRUD operations and event management
- Reorganize navigation menu (rename sections, move admin functions)
- Replace Geschichte editor with EasyMDE markdown editor
- Add management commands for balance reconciliation
- Create missing transactions for previously paid payments
- Ensure account balances accurately reflect all payment activity

Features added:
- Calendar entries creation and administration via menu
- Payment status tracking with automatic balance updates
- Duplicate prevention for payment transactions
- Markdown editor with live preview for Geschichte pages
- Database reconciliation tools for payment/balance sync

Bug fixes:
- Resolved IntegrityError on payment status changes
- Fixed missing account balance updates for paid payments
- Prevented duplicate balance deductions on re-saves
- Corrected menu structure and admin function placement
This commit is contained in:
2025-10-05 00:38:18 +02:00
parent 2961f376c3
commit c289cc3c58
36 changed files with 4039 additions and 99 deletions

View File

@@ -0,0 +1,200 @@
{% extends "base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="container-fluid">
<!-- Calendar Header with View Controls -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">
<i class="fas fa-calendar-alt me-2"></i>{{ title }}
</h1>
<div class="d-flex gap-2">
<!-- View Type Buttons -->
<div class="btn-group" role="group">
<a href="?view=month&year={{ year }}&month={{ month }}"
class="btn btn-sm btn-primary">
<i class="fas fa-calendar me-1"></i>Monat
</a>
<a href="?view=week"
class="btn btn-sm btn-outline-primary">
<i class="fas fa-calendar-week me-1"></i>Woche
</a>
<a href="?view=agenda"
class="btn btn-sm btn-outline-primary">
<i class="fas fa-list me-1"></i>Agenda
</a>
<a href="?view=list"
class="btn btn-sm btn-outline-primary">
<i class="fas fa-list-ul me-1"></i>Liste
</a>
</div>
<a href="{% url 'stiftung:kalender_create' %}" class="btn btn-success">
<i class="fas fa-plus me-1"></i>Neuer Termin
</a>
</div>
</div>
<!-- Navigation for Month View -->
<div class="row mb-3">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group" role="group">
<a href="?view=month&year={{ prev_year }}&month={{ prev_month }}"
class="btn btn-outline-secondary">
<i class="fas fa-chevron-left me-1"></i>Vorheriger Monat
</a>
<a href="?view=month&year={{ today.year }}&month={{ today.month }}"
class="btn btn-secondary">Heute</a>
<a href="?view=month&year={{ next_year }}&month={{ next_month }}"
class="btn btn-outline-secondary">
Nächster Monat<i class="fas fa-chevron-right ms-1"></i>
</a>
</div>
<h4 class="mb-0">{{ month_name }} {{ year }}</h4>
</div>
</div>
</div>
<!-- Month Calendar Grid -->
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-body p-0">
<div class="calendar-grid">
<!-- Weekday Headers -->
<div class="calendar-header">
{% for weekday in weekdays %}
<div class="weekday-header">{{ weekday }}</div>
{% endfor %}
</div>
<!-- Calendar Days -->
{% for week in calendar_grid %}
<div class="calendar-week">
{% for day_data in week %}
<div class="calendar-day {% if day_data.is_today %}today{% endif %} {% if not day_data %}empty{% endif %}">
{% if day_data %}
<div class="day-number">{{ day_data.day }}</div>
{% if day_data.events %}
<div class="day-events">
{% for event in day_data.events %}
<div class="event-item event-{{ event.category }}" title="{{ event.title }} - {{ event.description }}">
<i class="{{ event.icon }}"></i>
<span>{{ event.title|truncatechars:20 }}</span>
</div>
{% endfor %}
{% if day_data.event_count > 3 %}
<div class="more-events">+{{ day_data.event_count|add:"-3" }} weitere</div>
{% endif %}
</div>
{% endif %}
{% endif %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.calendar-grid {
display: grid;
grid-template-rows: auto repeat(6, 1fr);
gap: 1px;
background-color: #dee2e6;
border: 1px solid #dee2e6;
}
.calendar-header {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 1px;
}
.weekday-header {
background-color: #f8f9fa;
padding: 10px;
text-align: center;
font-weight: bold;
color: #495057;
}
.calendar-week {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 1px;
}
.calendar-day {
background-color: white;
min-height: 120px;
padding: 8px;
position: relative;
cursor: pointer;
}
.calendar-day.empty {
background-color: #f8f9fa;
}
.calendar-day.today {
background-color: #e3f2fd;
border: 2px solid #2196f3;
}
.calendar-day:hover {
background-color: #f5f5f5;
}
.day-number {
font-weight: bold;
margin-bottom: 5px;
color: #495057;
}
.calendar-day.today .day-number {
color: #1976d2;
}
.day-events {
display: flex;
flex-direction: column;
gap: 2px;
}
.event-item {
font-size: 0.75rem;
padding: 2px 4px;
border-radius: 3px;
display: flex;
align-items: center;
gap: 4px;
cursor: pointer;
}
.event-item i {
font-size: 0.6rem;
}
.event-termin { background-color: #e3f2fd; color: #1565c0; }
.event-zahlung { background-color: #fff3e0; color: #ef6c00; }
.event-deadline { background-color: #ffebee; color: #c62828; }
.event-geburtstag { background-color: #e8f5e8; color: #2e7d32; }
.event-vertrag { background-color: #f3e5f5; color: #7b1fa2; }
.event-pruefung { background-color: #e0f2f1; color: #00695c; }
.more-events {
font-size: 0.6rem;
color: #757575;
font-style: italic;
text-align: center;
margin-top: 2px;
}
</style>
{% endblock %}