From 1da1ccf9897183e1c8d6be09a6a70a4f7fd68f25 Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Sat, 28 Dec 2019 13:58:35 +0100 Subject: [PATCH] Refactor and redesign --- schoolapps/fibu/forms.py | 19 +--- .../migrations/0002_auto_20191228_1357.py | 90 +++++++++++++++++++ schoolapps/fibu/models.py | 30 ++++--- .../fibu/templates/fibu/account/edit.html | 14 ++- .../fibu/templates/fibu/account/index.html | 52 +++++------ .../fibu/templates/fibu/booking/check.html | 24 ++--- schoolapps/fibu/views.py | 56 ++++++------ 7 files changed, 182 insertions(+), 103 deletions(-) create mode 100644 schoolapps/fibu/migrations/0002_auto_20191228_1357.py diff --git a/schoolapps/fibu/forms.py b/schoolapps/fibu/forms.py index a808ea334..6ee071405 100644 --- a/schoolapps/fibu/forms.py +++ b/schoolapps/fibu/forms.py @@ -2,7 +2,7 @@ from django import forms from django.contrib.auth.models import User from material import Layout, Row, Fieldset -from .models import YEARLIST, Booking, Costcenter, Account, status_choices +from .models import YEARS, Booking, Costcenter, Account, status_choices class BookingForm(forms.ModelForm): @@ -19,11 +19,8 @@ class BookingForm(forms.ModelForm): class CheckBookingForm(forms.ModelForm): - accounts = Account.objects.filter().order_by('costcenter', 'name') - account = forms.ModelChoiceField(required=False, queryset=accounts, label='Buchungskonto') - class Meta: - model = Account + model = Booking fields = ('account',) @@ -66,7 +63,7 @@ class BookBookingForm(forms.ModelForm): class CostCenterForm(forms.ModelForm): name = forms.CharField(max_length=30, label='Kostenstelle') - year = forms.ChoiceField(choices=YEARLIST, label='Jahr') + year = forms.ChoiceField(choices=YEARS, label='Jahr') layout = Layout(Row('name', 'year')) @@ -75,15 +72,7 @@ class CostCenterForm(forms.ModelForm): fields = ('id', 'name', 'year') -class EditAccountForm(forms.ModelForm): - name = forms.CharField(max_length=30, label='Buchungskonto') - costcenterlist = Costcenter.objects.filter() - costcenter = forms.ModelChoiceField(queryset=costcenterlist, label='Kostenstelle') - income = forms.BooleanField(label='Budget-/Einnanhmekonto', required=False) - budget = forms.IntegerField(label='Budget') - - layout = Layout(Row('name', 'costcenter', 'income', 'budget')) - +class AccountForm(forms.ModelForm): class Meta: model = Account fields = ('id', 'name', 'costcenter', 'income', 'budget') diff --git a/schoolapps/fibu/migrations/0002_auto_20191228_1357.py b/schoolapps/fibu/migrations/0002_auto_20191228_1357.py new file mode 100644 index 000000000..5150e026d --- /dev/null +++ b/schoolapps/fibu/migrations/0002_auto_20191228_1357.py @@ -0,0 +1,90 @@ +# Generated by Django 2.2.6 on 2019-12-28 12:57 + +import datetime +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ('fibu', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='account', + options={'permissions': [('manage_account', 'Can manage account')], 'verbose_name': 'Buchungskonto', + 'verbose_name_plural': 'Buchungskonten'}, + ), + migrations.AlterModelOptions( + name='booking', + options={ + 'permissions': [('manage_booking', 'Can manage bookings'), ('request_booking', 'Can request a booking'), + ('check_booking', 'Can check bookings')], 'verbose_name': 'Buchung', + 'verbose_name_plural': 'Buchungen'}, + ), + migrations.AlterModelOptions( + name='costcenter', + options={'permissions': [('manage_costcenter', 'Can manage costcenter')], 'verbose_name': 'Kostenstelle', + 'verbose_name_plural': 'Kostenstellen'}, + ), + migrations.AlterField( + model_name='account', + name='budget', + field=models.DecimalField(decimal_places=2, default=0.0, max_digits=9, verbose_name='Budget'), + ), + migrations.AlterField( + model_name='account', + name='costcenter', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='fibu.Costcenter', + verbose_name='Kostenstelle'), + ), + migrations.AlterField( + model_name='account', + name='income', + field=models.BooleanField(default=False, verbose_name='Einnahmekonto'), + ), + migrations.AlterField( + model_name='account', + name='name', + field=models.CharField(max_length=20, verbose_name='Buchungskonto'), + ), + migrations.AlterField( + model_name='booking', + name='booking_date', + field=models.DateField(default=datetime.date.today), + ), + migrations.AlterField( + model_name='booking', + name='invoice_date', + field=models.DateField(default=datetime.date.today), + ), + migrations.AlterField( + model_name='booking', + name='maturity', + field=models.DateField(default=datetime.date.today), + ), + migrations.AlterField( + model_name='booking', + name='status', + field=models.IntegerField( + choices=[(0, 'beantragt'), (1, 'abgelehnt'), (2, 'bewilligt'), (3, 'bestellt'), (4, 'eingereicht'), + (5, 'bezahlt')], default=0, verbose_name='Status'), + ), + migrations.AlterField( + model_name='booking', + name='submission_date', + field=models.DateField(default=datetime.date.today), + ), + migrations.AlterField( + model_name='costcenter', + name='name', + field=models.CharField(max_length=30, verbose_name='Kostenstelle'), + ), + migrations.AlterField( + model_name='costcenter', + name='year', + field=models.IntegerField(choices=[(2019, '2019'), (2020, '2020'), (2021, '2021'), (2022, '2022')], + default=2019, verbose_name='Jahr'), + ), + ] diff --git a/schoolapps/fibu/models.py b/schoolapps/fibu/models.py index 04c0b5a34..be68eb87e 100644 --- a/schoolapps/fibu/models.py +++ b/schoolapps/fibu/models.py @@ -1,12 +1,10 @@ +from django.utils import timezone from django.db import models from django.contrib.auth.models import User from datetime import date -# TODO: Make dynamic -YEARLIST = [(2020, '2020'), - (2021, '2021'), - (2022, '2022'), - (2023, '2023')] +current_year = timezone.now().year +YEARS = [(x, str(x)) for x in range(current_year, current_year + 4)] class Status: @@ -32,13 +30,15 @@ status_choices = [(x, val.name) for x, val in enumerate(status_list)] class Costcenter(models.Model): # Kostenstellen z.B. Schulträger-konsumtiv, Schulträger-investiv, Elternverein, ... - name = models.CharField(max_length=30) - year = models.IntegerField(default=2019, choices=YEARLIST, verbose_name="Jahr") + name = models.CharField(max_length=30, blank=False, verbose_name="Kostenstelle") + year = models.IntegerField(default=timezone.now().year, choices=YEARS, blank=False, verbose_name="Jahr") def __str__(self): return self.name class Meta: + verbose_name = "Kostenstelle" + verbose_name_plural = "Kostenstellen" permissions = [ ('manage_costcenter', 'Can manage costcenter'), ] @@ -46,10 +46,11 @@ class Costcenter(models.Model): class Account(models.Model): # Buchungskonten, z.B. Fachschaften, Sekretariat, Schulleiter, Kopieren, Tafelnutzung - name = models.CharField(max_length=20, default='') - costcenter = models.ForeignKey(to=Costcenter, on_delete=models.CASCADE, default='') - income = models.BooleanField(default=False) # True, wenn es sich um ein Einnahmekonto handelt - budget = models.DecimalField(max_digits=9, decimal_places=2, default=0.00) + name = models.CharField(max_length=20, blank=False, verbose_name="Buchungskonto") + costcenter = models.ForeignKey(to=Costcenter, on_delete=models.CASCADE, blank=False, verbose_name="Kostenstelle") + income = models.BooleanField(default=False, + verbose_name="Einnahmekonto") # True, wenn es sich um ein Einnahmekonto handelt + budget = models.DecimalField(max_digits=9, decimal_places=2, default=0.00, verbose_name="Budget") saldo = models.DecimalField(max_digits=9, decimal_places=2, default=0.00) rest = models.DecimalField(max_digits=9, decimal_places=2, default=0.00) @@ -57,6 +58,8 @@ class Account(models.Model): return "{}: {}".format(self.costcenter, self.name) class Meta: + verbose_name = "Buchungskonto" + verbose_name_plural = "Buchungskonten" permissions = [ ('manage_account', 'Can manage account'), ] @@ -83,7 +86,12 @@ class Booking(models.Model): def get_status(self): return status_list[self.status] + def __str__(self): + return "{} ({})".format(self.description, self.account) + class Meta: + verbose_name = "Buchung" + verbose_name_plural = "Buchungen" permissions = [ ('manage_booking', 'Can manage bookings'), ('request_booking', 'Can request a booking'), diff --git a/schoolapps/fibu/templates/fibu/account/edit.html b/schoolapps/fibu/templates/fibu/account/edit.html index 85616988e..c977c32d4 100644 --- a/schoolapps/fibu/templates/fibu/account/edit.html +++ b/schoolapps/fibu/templates/fibu/account/edit.html @@ -2,21 +2,19 @@ {% load material_form %} <main> + <h4>Buchungskonto bearbeiten</h4> - <h4>Buchungskonto bearbeiten</h4> - - <form method="POST" style="background: #eee"> + <form method="POST" action=""> {% csrf_token %} {% form form=form %} {% endform %} + <span class="right"> <button type="submit" class="waves-effect waves-light btn green"> - <i class="material-icons left">send</i> Änderungen übernehmen - </button> - <a href="{% url 'account' %}"> - <button type="button" class="waves-effect waves-light btn grey"> - <i class="material-icons left">cancel</i> Abbrechen + <i class="material-icons left">save</i> Änderungen übernehmen </button> + <a href="{% url 'account' %}" class="waves-effect waves-light btn red"> + <i class="material-icons left">cancel</i> Abbrechen </a> </span> </form> diff --git a/schoolapps/fibu/templates/fibu/account/index.html b/schoolapps/fibu/templates/fibu/account/index.html index 58a8ea4fc..1451f422c 100755 --- a/schoolapps/fibu/templates/fibu/account/index.html +++ b/schoolapps/fibu/templates/fibu/account/index.html @@ -2,8 +2,7 @@ {% load material_form %} <main> - - <a class="waves-effect waves-light btn green modal-trigger right" href="#new-modal"> + <a class="waves-effect waves-light btn green modal-trigger right" href="#new-modal"> <i class="material-icons left">add</i> Buchungskonto anlegen </a> @@ -34,47 +33,44 @@ </form> <table> - <thead> - <tr> - <th>Buchungskonto</th> - <th>Kostenstelle</th> - <th>erwartete Einnahmen</th> - <th>erwartete Ausgaben</th> - <th>Aktionen</th> - </tr> - </thead> - <tbody> + <thead> + <tr> + <th>Buchungskonto</th> + <th>Kostenstelle</th> + <th>erwartete Einnahmen</th> + <th>erwartete Ausgaben</th> + <th>Aktionen</th> + </tr> + </thead> + <tbody> {% for account in accounts %} <tr> <td>{{ account.name }}</td> <td>{{ account.costcenter }}</td> - {% if account.income %} - <td>{{ account.budget }}</td> + {% if account.income %} + <td class="green-text">{{ account.budget }}</td> <td></td> {% else %} <td></td> - <td>{{ account.budget }}</td> + <td class="red-text">{{ account.budget }}</td> {% endif %} <td class="right-align"> - <form action="{% url 'account_edit' account.id %}" class="left"> - {% csrf_token %} - <input type="hidden" value="{{ account.id }}" name="account-id"> - <button type="submit" name="edit" - class="waves-effect waves-light btn-flat btn-flat-medium" title="Bearbeiten"> - <i class="material-icons center green-text">create</i> - </button> - </form> + <a href="{% url 'account_edit' account.id %}" + class="waves-effect waves-light btn-flat btn-flat-medium left" title="Bearbeiten"> + <i class="material-icons center green-text">create</i> + </a> <form action="" method="POST" class="left"> {% csrf_token %} - <input type="hidden" value="{{ account.id }}" name="account-id"> - <button type="submit" onclick="return confirm('Wollen Sie das Buchungskonto wirklich löschen?')" name="cancel" class="waves-effect waves-light btn-flat btn-flat-medium" title="Löschen"> - <i class="material-icons center red-text">cancel</i> - </button> + <input type="hidden" value="{{ account.id }}" name="id"> + <button type="submit" onclick="return confirm('Buchungskonto wirklich löschen?')" + name="cancel" class="waves-effect waves-light btn-flat btn-flat-medium" title="Löschen"> + <i class="material-icons center red-text">cancel</i> + </button> </form> </td> </tr> {% endfor %} - </tbody> + </tbody> </table> </main> {% include 'partials/footer.html' %} diff --git a/schoolapps/fibu/templates/fibu/booking/check.html b/schoolapps/fibu/templates/fibu/booking/check.html index 67e9ee228..9dad97f53 100755 --- a/schoolapps/fibu/templates/fibu/booking/check.html +++ b/schoolapps/fibu/templates/fibu/booking/check.html @@ -8,12 +8,12 @@ Keine offenen Anträge vorhanden </span> {% else %} - <div class="collection-item row grey white-text"> - <span class="col s2">Antragsteller</span> - <span class="col s3">Anschaffungswunsch</span> - <span class="col s2 right-align">Geplante Kosten</span> - <span class="col s3">Buchungskonto</span> - <span class="col s2">Aktionen</span> + <div class="collection-item row"> + <div class="col s2"><strong>Antragsteller</strong></div> + <div class="col s3"><strong>Anschaffungswunsch</strong></div> + <div class="col s2 right-align"><strong>Geplante Kosten</strong></div> + <div class="col s3"><strong>Buchungskonto</strong></div> + <div class="col s2"><strong>Aktionen</strong></div> </div> {% for booking in filter.qs %} @@ -21,11 +21,11 @@ <form method="POST"> {% csrf_token %} <input type="hidden" value="{{ booking.id }}" name="booking-id"> - <span class="col s2">{{ booking.contact.get_full_name }}</span> - <span class="col s3">{{ booking.description }}</span> - <span class="col s2 right-align">{{ booking.planned_amount }} €</span> - <span class="col s3">{{ form.account }}</span> - <span class="col s2"> + <div class="col s2">{{ booking.contact.get_full_name }}</div> + <div class="col s3">{{ booking.description }}</div> + <div class="col s2 right-align">{{ booking.planned_amount }} €</div> + <div class="col s3">{{ form.account }}</div> + <div class="col s2"> <button type="submit" name="allow" class="waves-effect waves-light btn-flat btn-flat-medium" title="Annehmen"> <i class="material-icons center green-text">check_circle</i> @@ -34,7 +34,7 @@ class="waves-effect waves-light btn-flat btn-flat-medium" title="Ablehnen"> <i class="material-icons center red-text">not_interested</i> </button> - </span> + </div> </form> </div> {% endfor %} diff --git a/schoolapps/fibu/views.py b/schoolapps/fibu/views.py index d95ab2bd1..33bcd20aa 100644 --- a/schoolapps/fibu/views.py +++ b/schoolapps/fibu/views.py @@ -5,7 +5,7 @@ from django.urls import reverse from django.shortcuts import render, redirect, get_object_or_404 from .models import Booking, Costcenter, Account from .filters import BookingFilter -from .forms import BookingForm, CheckBookingForm, BookBookingForm, CostCenterForm, EditAccountForm +from .forms import BookingForm, CheckBookingForm, BookBookingForm, CostCenterForm, AccountForm @login_required @@ -190,30 +190,25 @@ def cost_center_edit(request, id): @login_required @permission_required('fibu.manage_account') def account(request): + form = AccountForm() + if request.method == 'POST': - if 'account-id' in request.POST: - account_id = request.POST['account-id'] + if 'account-id' in request.POST and 'cancel' in request.POST: + account_id = request.POST['id'] account = Account.objects.get(id=account_id) - if 'cancel' in request.POST: - account.delete() + account.delete() - print('Eintrag gelöscht') - return redirect('account') - print('Edit-Form erstellt ############# form.is_valid:', form.is_valid()) - form = EditAccountForm(instance=account) + messages.success(request, "Das Buchungskonto wurde erfolgreich gelöscht") + return redirect('account') else: - form = EditAccountForm(request.POST or None) - else: - form = EditAccountForm() + form = AccountForm(request.POST) + if form.is_valid(): - name = form.cleaned_data['name'] - costcenter = form.cleaned_data['costcenter'] - income = form.cleaned_data['income'] - budget = form.cleaned_data['budget'] - account = Account(name=name, costcenter=costcenter, income=income, budget=budget) - account.save() + form.save() + messages.success(request, "Das Buchungskonto wurde erfolgreich angelegt.") return redirect('account') + accounts = Account.objects.filter() context = {'accounts': accounts, 'form': form} return render(request, 'fibu/account/index.html', context) @@ -223,17 +218,19 @@ def account(request): @permission_required('fibu.manage_account') def account_edit(request, id): account = get_object_or_404(Account, id=id) - form = EditAccountForm(instance=account) - template = 'fibu/account/edit.html' + form = AccountForm(instance=account) + if request.method == 'POST': - form = EditAccountForm(request.POST, instance=account) - print('\n\n\nBLUBB', form) + form = AccountForm(request.POST, instance=account) + if form.is_valid(): form.save() + messages.success(request, "Die Änderungen am Buchungskonto wurden erfolgreich übernommen.") return redirect(reverse('account')) + context = {'form': form} - return render(request, template, context) + return render(request, 'fibu/account/edit.html', context) @login_required @@ -245,11 +242,11 @@ def reports(request): @login_required @permission_required('fibu.manage_booking') def expenses(request): - costcenterlist = Costcenter.objects.filter() - costcenter_accounts = {} + cost_centers = Costcenter.objects.filter() + cost_center_accounts = {} account_rests = {} - for costcenter in costcenterlist: - accounts = Account.objects.filter(costcenter=costcenter) + for cost_center in cost_centers: + accounts = Account.objects.filter(costcenter=cost_center) # update saldo for account in accounts: saldo = Booking.objects.filter(account=account).aggregate(Sum('amount')) @@ -263,6 +260,7 @@ def expenses(request): except: Account.objects.filter(id=account.id).update(saldo=0, rest=0) - costcenter_accounts[costcenter.name] = list(Account.objects.filter(costcenter=costcenter).order_by('-income')) - context = {'costcenter_accounts': costcenter_accounts, 'account_rests': account_rests} + cost_center_accounts[cost_center.name] = list( + Account.objects.filter(costcenter=cost_center).order_by('-income')) + context = {'costcenter_accounts': cost_center_accounts, 'account_rests': account_rests} return render(request, 'fibu/reports/expenses.html', context) -- GitLab