Abrechnung inkl. Abbestellen fertig

This commit is contained in:
holger.trampe 2020-10-02 11:15:53 +02:00
parent 91114eea82
commit 2e3ac42c1b
6 changed files with 102 additions and 30 deletions

View File

@ -80,7 +80,15 @@ class AgencyBillPlan(forms.ModelForm):
self.fields['contract'] = forms.BooleanField(required=True, label="Auftragsdatenverarbeitung akzeptieren")
class AgencyEndBillPlan(forms.ModelForm):
class Meta:
model = Agency
fields = ['paymentplan']
def __init__(self, *args, **kwargs):
super(AgencyEndBillPlan, self).__init__(*args, **kwargs)
self.fields['paymentplan'] = forms.CharField(initial=None, required=True, widget=forms.HiddenInput())
# Form für die Benachrichtigungseinstellungen
'''

View File

@ -0,0 +1,36 @@
{% extends "users/base.html" %}
{% load crispy_forms_tags %}
{% load counter_tag %}
{% block content %}
<div class="content-section col-12">
<h3>Zahlplan abbestellen</h3>
<hr>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form|crispy}}
<p>Bestellen Sie den Zahlplan ab, erhalten Sie keine automatische Verlängerung. Beachten Sie, dass sich Ihre Mitarbeiter spätestens zwei Wochen nach dem letzten Tag des bezahlten Zeitraums Ihre Digitale Agentur nicht mehr anmelden können.</p>
<p>Sie können jederzeit einen neuen Zahlplan auswählen. Dieser beginnt dann frühestens nach dem Tag, an dem der aktuelle Plan ausläuft.</p>
<hr>
<div class="col-8">
<a class="btn" href="{% url 'dasettings' %}">Abbrechen</a>
<button type="submit" class="btn btn-primary" style="float: right">Zahlplan abbestellen</button>&nbsp;
</div>
</form>
</div>
{% endblock content %}

View File

@ -11,7 +11,7 @@
<div class="card-body">
<h5 class="card-title">Ihr Betrag</h5>
<p>Ihr monatlicher Nutzungsbeitrag setzt sich wie folgt zusammen:</p>
<table style="width: 55%">
<table style="width: 75%">
<tr>
<td>Grundbetrag (inkl. 3 Nutzer)</td><td>21,00 €</td>
</tr>
@ -35,17 +35,19 @@
<h5 class="card-title">Ihre Zahlungsweise</h5>
{% getNextMonth request.user.profile.agency as nextMonth %}
Ihre Agentur wurde am {{ request.user.profile.agency.registerdate|date:"d.m.Y" }} registriert.
{% if paymentplan == "" %}
Es wurde noch keine Zahlungsweise ausgewählt. Sie können die Digitale Agentur bis zum {{nextMonth|date:"d.m.Y"}} kostenlos nutzen. Möchten Sie die Digitale Agentur auch nach diesem Zeitraum nutzen, wählen Sie bitte einen Zahlplan aus.
<br />
<a href="{% url 'ag-billplanupdate' request.user.profile.agency.pk %}" class="btn btn-primary btn mt-2" onclick="">Zahlplan jetzt auswählen</a>
{% if paymentplan == None and bills|length == 0 %}
Es wurde noch keine Zahlungsweise ausgewählt und keine Rechnungen gefunden. Sie können die Digitale Agentur bis zum {{nextMonth|date:"d.m.Y"}} kostenlos nutzen. Möchten Sie die Digitale Agentur auch nach diesem Zeitraum nutzen, wählen Sie bitte einen Zahlplan aus.
<br />
<a href="{% url 'ag-billplanupdate' request.user.profile.agency.pk %}" class="btn btn-primary btn mt-2" onclick="">Zahlplan jetzt auswählen</a>
{% elif bills|length > 0 and paymentplan == "" %}
Ihre aktuelle Rechnungen erlaubt Ihnen die Nutzung der digitalen Agentur bis zum {{bills.0.end|date:"d.m.Y"}}. Danach wird der Zugang gesperrt. Legen Sie einen neuen Zahlplan fest, um die digitale Agentur auch weiterhin zu nutzen.<br />
<a href="{% url 'ag-billplanupdate' request.user.profile.agency.pk %}" class="btn btn-primary btn mt-2" onclick="">Zahlplan jetzt auswählen</a>
{% else %}
<br />
Ausgewählter Zahlungsplan: {{request.user.profile.agency.paymentplan}} Monat{% if request.user.profile.agency.paymentplan > 1 %}e{% endif %}<br />
Nächste Rechnungserstellung am: {{bills.0.end|date:"d.m.Y"}}<br />
<a href="#" class="btn btn-primary btn mt-2" onclick="">Zahlplan abbestellen</a>
<br />
Ausgewählter Zahlungsplan: {{request.user.profile.agency.paymentplan}} Monat{% if request.user.profile.agency.paymentplan > 1 %}e{% endif %}<br />
Nächste Rechnungserstellung am {{bills.0.end|date:"d.m.Y"}}<br />
<a href="{% url 'ag-billplanend' request.user.profile.agency.pk %}" class="btn btn-primary btn mt-2" onclick="">Zahlplan abbestellen</a>
{% endif %}
<hr>
<h5 class="card-title.">Fragen, Hilfe, Kündigung</h5>
@ -60,7 +62,7 @@
<div class="card d-block mb-3">
<div class="card-body">
<h5 class="card-title">E-Mail-Adresse</h5>
Ihre Rechnungen werden automatisch an folgende E-Mailadresse gesendet.<br />
Informationen über neue Rechnungen werden automatisch an folgende E-Mailadresse gesendet.<br />
{% if request.user.profile.agency.payment_address == None %}
<i>Es wurde keine Adresse hinterlegt. Die Adresse wird an die Agenturadresse versendet:</i>&nbsp;<b>{{request.user.profile.agency.agency_email}}</b>
{% else %}
@ -74,6 +76,9 @@
<div class="card d-block mb-3">
<div class="card-body">
<h5 class="card-title">Rechnungen</h5>
{% if bills|length == 0 %}
Es liegen keine Rechnungen vor.
{% endif %}
{% for bill in bills %}
<a href="{% url 'ag-getbillpdf' bill.pk %}" target="_blank">Rechnung vom {{bill.billdate|date:"d.m.Y"}} ({{bill.billnumber}})</a> - {% if bill.billstatus == "open" %} Offen {% elif bill.billstatus == "paid" %} Bezahlt {% endif %} <br />
{% endfor %}

View File

@ -54,6 +54,7 @@
<hr>
<p>Mit Klick auf dem Button <i>Jetzt kostenpflichtig bestellen</i> wird eine Rechnung für Ihre Agentur generiert und per E-Mail an die hinterlegte Rechnungs-E-Mailadresse oder an die Agentur-E-Mailadresse versendet. Der Rechnungsbetrag muss innerhalb von 14 Tagen beglichen werden.
<hr>
<b>Beginn des Leistungszeitraums: </b>{{start|date:"d.m.Y"}}<br />
{% loadFinalMoney user as fm %}
<b>Rechnungsbetrag: <span id="billfinal">{{fm|floatformat:2|intcomma}}</span>&nbsp;</b>
</div>

View File

@ -3,7 +3,7 @@ from django.contrib.auth import views as auth_views
from django.contrib.auth.decorators import login_required, permission_required
from . import views
from .views import FreeDayDeleteView, AbsenceReasonDeleteView, AbsenceReasonUpdateView, AbsenceReasonAddView
from .views import NewUserFirstStep, UserProfileUpdate, UserChangeMain, BillMailUpdate, BillPlanUpdate, GetBill, GetBillPDF
from .views import NewUserFirstStep, UserProfileUpdate, UserChangeMain, BillMailUpdate, BillPlanUpdate, GetBill, GetBillPDF, BillPlanEnd
'''
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
'''
@ -37,5 +37,6 @@ urlpatterns = [
path('ag/billplan/<int:pk>', permission_required('users.agencyinfo')(BillPlanUpdate.as_view()), name='ag-billplanupdate'),
path('ag/getbill/<int:pk>', permission_required('users.agencyinfo')(GetBill), name='ag-getbill'),
path('ag/getbillpdf/<int:pk>', permission_required('users.agencyinfo')(GetBillPDF), name='ag-getbillpdf'),
path('ag/billplanend/<int:pk>', permission_required('users.agencyinfo')(BillPlanEnd.as_view()), name='ag-billplanend'),
]

View File

@ -1,7 +1,7 @@
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from .forms import UsersSelfChangeForm, UsersNotificationFormStandard, AgencyGroupPerms, AgencyModulsForm, UserNewUserForm, UserProfileForm, AgencyNetworkForm, AgencyOrganigrammForm, UserTimeForm, AbsenceReasonForm, UsersNotificationFormNews, UsersNotificationFormFiles, UsersNotificationFormMessages ,UsersNotificationFormOrganizer, UsersNotificationFormChat, UsersNotificationFormAbTime, UsersNotificationFormGroups, UsersNotificationFormAgn, UsersNotificationFormTasks, AgencyBillMail, AgencyBillPlan
from .forms import UsersSelfChangeForm, UsersNotificationFormStandard, AgencyGroupPerms, AgencyModulsForm, UserNewUserForm, UserProfileForm, AgencyNetworkForm, AgencyOrganigrammForm, UserTimeForm, AbsenceReasonForm, UsersNotificationFormNews, UsersNotificationFormFiles, UsersNotificationFormMessages ,UsersNotificationFormOrganizer, UsersNotificationFormChat, UsersNotificationFormAbTime, UsersNotificationFormGroups, UsersNotificationFormAgn, UsersNotificationFormTasks, AgencyBillMail, AgencyBillPlan, AgencyEndBillPlan
from django.contrib import messages
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm
@ -33,6 +33,8 @@ from timemanagement.forms import AddFreeDayForm
from django.urls import reverse_lazy
import re
import json
from django.conf import settings # import the settings file
def randomString(stringLength=10):
"""Generate a random string of fixed length """
@ -250,7 +252,7 @@ def DASettings(request):
# HEADERS CURL
headers = {
'Authorization': 'Bearer 8f9ba01f-9e84-42c7-9548-48c254f14c19',
'Authorization': 'Bearer ' + settings.LEX_API,
'Content-Type': 'application/json',
'Accept': 'application/json',
}
@ -270,7 +272,7 @@ from django.http import FileResponse, Http404
def GetBill(request, pk):
# HEADERS CURL
headers = {
'Authorization': 'Bearer 8f9ba01f-9e84-42c7-9548-48c254f14c19',
'Authorization': 'Bearer ' + settings.LEX_API,
'Content-Type': 'application/json',
'Accept': 'application/json',
}
@ -288,18 +290,15 @@ def GetBill(request, pk):
return render(request, 'dasettings/bill_single.html', context)
from fpdf import FPDF, HTMLMixin
class HtmlPdf(FPDF, HTMLMixin):
pass
import io as BytesIO
import base64
from django.http import HttpResponse
@login_required
def GetBillPDF(request, pk):
headers = {
'Authorization': 'Bearer 8f9ba01f-9e84-42c7-9548-48c254f14c19',
'Authorization': 'Bearer ' + settings.LEX_API,
'Content-Type': 'application/json',
'Accept': 'application/json',
}
@ -1548,6 +1547,17 @@ def getBill(request, billid):
else:
pass
'''
class BillPlanEnd(UpdateView):
model = Agency
success_url = reverse_lazy('dasettings')
form_class = AgencyEndBillPlan
template_name = "dasettings/bill_removepayplan.html"
def form_valid(self, form):
self.object.paymentplan = None
messages.success(self.request, f"Zahlplan abbestellt!")
return super().form_valid(form)
from dateutil.relativedelta import *
class BillPlanUpdate(UpdateView):
@ -1561,6 +1571,11 @@ class BillPlanUpdate(UpdateView):
agency = self.request.user.profile.agency
month = agency.registerdate
# Wenn die Agentur noch KEINE Lexoffice-ID hat, dann ist der Freimonat noch nicht durch.
if agency.lexofficeid == "":
month = month + relativedelta(months=1)
next_month = month + relativedelta(months=1)
voucher_date = next_month.strftime("%Y-%m-%d")
@ -1575,7 +1590,7 @@ class BillPlanUpdate(UpdateView):
# HEADERS CURL
headers = {
'Authorization': 'Bearer 8f9ba01f-9e84-42c7-9548-48c254f14c19',
'Authorization': 'Bearer ' + settings.LEX_API,
'Content-Type': 'application/json',
'Accept': 'application/json',
}
@ -1591,14 +1606,8 @@ class BillPlanUpdate(UpdateView):
voucher_date_today = date.today().strftime("%Y-%m-%d")
# TODO: Nachgebuchte Mitarbeiter
# TODO: Was passiert bei Änderungen der Agenturdaten?
# TODO: Kündigungsmöglichkeit, den Zahlplan zu beenden
# TODO: voucherDate muss HEUTE sein, Leistungszeitraum aber das von der Agenturregistrierung
# DataJSON
'''
Bei Beschreibung noch Zeitraum vom XX.XX.XXXX bis XX.XX.XXXX
'''
monthword = "Monate"
if form.cleaned_data['paymentplan'] == "1":
monthword = "Monat"
@ -1670,7 +1679,7 @@ class BillPlanUpdate(UpdateView):
# HEADERS CURL
headers = {
'Authorization': 'Bearer 8f9ba01f-9e84-42c7-9548-48c254f14c19',
'Authorization': 'Bearer ' + settings.LEX_API,
'Content-Type': 'application/json',
'Accept': 'application/json',
}
@ -1697,7 +1706,19 @@ class BillPlanUpdate(UpdateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'dasettings'})
# Rechnungsbegin setzen
agency = self.request.user.profile.agency
month = agency.registerdate
# Wenn die Agentur noch KEINE Lexoffice-ID hat, dann ist der Freimonat noch nicht durch.
if agency.lexofficeid == "":
month = month + relativedelta(months=1)
context.update({'active_link' : 'dasettings', 'start' : month})
return context