Files
Jan Remmer Siebels c289cc3c58 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
2025-10-05 00:38:18 +02:00

184 lines
6.4 KiB
HTML

{% 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-week 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-outline-primary">
<i class="fas fa-calendar me-1"></i>Monat
</a>
<a href="?view=week"
class="btn btn-sm btn-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>
<!-- Week View -->
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<h6 class="mb-0">{{ start_date|date:"d.m.Y" }} - {{ end_date|date:"d.m.Y" }}</h6>
<div class="btn-group btn-group-sm">
<a href="?view=week&date={{ start_date|add:'-7'|date:'Y-m-d' }}" class="btn btn-outline-secondary">
<i class="fas fa-chevron-left"></i> Vorherige Woche
</a>
<a href="?view=week" class="btn btn-secondary">Diese Woche</a>
<a href="?view=week&date={{ start_date|add:'7'|date:'Y-m-d' }}" class="btn btn-outline-secondary">
Nächste Woche <i class="fas fa-chevron-right"></i>
</a>
</div>
</div>
</div>
<div class="card-body">
{% if events %}
<div class="week-timeline">
{% for i in "1234567"|make_list %}
{% with day_date=start_date|add:forloop.counter0 %}
<div class="day-column">
<div class="day-header {% if day_date == today %}today{% endif %}">
<div class="day-name">{{ day_date|date:"l" }}</div>
<div class="day-date">{{ day_date|date:"d.m" }}</div>
</div>
<div class="day-events">
{% for event in events %}
{% if event.date == day_date %}
<div class="event-block event-{{ event.category }}">
<div class="event-time">
{% if event.time %}{{ event.time }}{% else %}ganztags{% endif %}
</div>
<div class="event-title">
<i class="{{ event.icon }} me-1"></i>{{ event.title }}
</div>
{% if event.description %}
<div class="event-desc">{{ event.description|truncatechars:50 }}</div>
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endwith %}
{% endfor %}
</div>
{% else %}
<div class="text-center py-5">
<i class="fas fa-calendar-times fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Termine diese Woche</h5>
<p class="text-muted">Fügen Sie einen neuen Termin hinzu.</p>
<a href="{% url 'stiftung:kalender_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Termin hinzufügen
</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<style>
.week-timeline {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 1px;
background-color: #dee2e6;
border: 1px solid #dee2e6;
}
.day-column {
background-color: white;
min-height: 400px;
}
.day-header {
padding: 10px;
background-color: #f8f9fa;
text-align: center;
border-bottom: 1px solid #dee2e6;
}
.day-header.today {
background-color: #e3f2fd;
color: #1976d2;
font-weight: bold;
}
.day-name {
font-size: 0.8rem;
text-transform: uppercase;
margin-bottom: 2px;
}
.day-date {
font-size: 1.2rem;
font-weight: bold;
}
.day-events {
padding: 8px;
display: flex;
flex-direction: column;
gap: 4px;
}
.event-block {
padding: 8px;
border-radius: 4px;
border-left: 4px solid;
cursor: pointer;
}
.event-block:hover {
opacity: 0.8;
}
.event-time {
font-size: 0.75rem;
font-weight: bold;
margin-bottom: 2px;
}
.event-title {
font-size: 0.85rem;
font-weight: 600;
margin-bottom: 2px;
}
.event-desc {
font-size: 0.75rem;
color: #666;
}
.event-termin { background-color: #e3f2fd; border-left-color: #2196f3; }
.event-zahlung { background-color: #fff3e0; border-left-color: #ff9800; }
.event-deadline { background-color: #ffebee; border-left-color: #f44336; }
.event-geburtstag { background-color: #e8f5e8; border-left-color: #4caf50; }
.event-vertrag { background-color: #f3e5f5; border-left-color: #9c27b0; }
.event-pruefung { background-color: #e0f2f1; border-left-color: #009688; }
</style>
{% endblock %}