PDF Rechnung fertig

This commit is contained in:
holger.trampe 2020-10-02 00:12:57 +02:00
parent 8b106c569c
commit 91114eea82
6 changed files with 96 additions and 27 deletions

View File

@ -0,0 +1,8 @@
{% extends "users/base.html" %}
{% block content %}
<div class="content-section col-12">
<h3>Rechnung betrachten</h3>
<hr>
<a href="{% url 'ag-getbillpdf' bill.pk %}" target="_blank">Hier herunterladen</a>
</div>
{% endblock content %}

View File

@ -37,19 +37,21 @@
{% getNextMonth request.user.profile.agency as nextMonth %}
Ihre Agentur wurde am {{ request.user.profile.agency.registerdate|date:"d.m.Y" }} registriert.
{% if paymentplan == "" or request.user.profile.agency.lexofficeid == "" %}
{% 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>
{% else %}
<br />Ausgewählter Zahlungsplan: {{request.user.profile.agency.paymentplan}} Monat{% if request.user.profile.agency.paymentplan > 1 %}e{% endif %} <br />
<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>
{% endif %}
<hr>
<h5 class="card-title.">Fragen, Hilfe, Kündigung</h5>
Bei Fragen zu Ihrer Abrechnung melden Sie sich bitte per E-Mail an <a href="mailto:abrechnung@digitale-agentur.com">abrechnung@digitale-agentur.com</a>.
<!-- TASK: Kündigungsmodaliäten einfügen -->
KÜNDIGUNGSMODALITÄTEN NOCH EINFÜGEN
Die Kündigungsmodalitäten finden Sie in den AGB's. Alternativ wenden Sie sich an den Support.
</div>
</div>
</div>
@ -73,7 +75,7 @@
<div class="card-body">
<h5 class="card-title">Rechnungen</h5>
{% for bill in bills %}
<a href="{{bill.lexid}}">Rechnung vom {{bill.billdate|date:"d.m.Y"}} (Nr. {{bill.billnumber}})</a><br />
<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 %}
</div>
</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
from .views import NewUserFirstStep, UserProfileUpdate, UserChangeMain, BillMailUpdate, BillPlanUpdate, GetBill, GetBillPDF
'''
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
'''
@ -35,6 +35,7 @@ urlpatterns = [
path('abcatadd/', AbsenceReasonAddView.as_view(), name="abcat-add"),
path('ag/billmail/update/<int:pk>', permission_required('users.agencyinfo')(BillMailUpdate.as_view()), name='ag-billmailupdate'),
path('ag/billplan/<int:pk>', permission_required('users.agencyinfo')(BillPlanUpdate.as_view()), name='ag-billplanupdate'),
#path('ag/getbill/<slug:billid>', permission_required('users.agencyinfo')(GetBill), name='ag-getbill'),
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'),
]

View File

@ -259,15 +259,70 @@ def DASettings(request):
# Alle Rechnungen der Agentur abfragen
context.update({"bills" : AgencyBills.objects.filter(agency=request.user.profile.agency)})
#r = requests.get("https://api.lexoffice.io/v1/invoices/" + AgencyBills.objects.filter(agency=request.user.profile.agency)[0].lexid, data=json_data, headers=headers)
context.update({"bills" : AgencyBills.objects.filter(agency=request.user.profile.agency).order_by("billdate")})
return render(request, 'dasettings/settings.html', context)
from django.http import FileResponse, Http404
@login_required
def GetBill(request, pk):
# HEADERS CURL
headers = {
'Authorization': 'Bearer 8f9ba01f-9e84-42c7-9548-48c254f14c19',
'Content-Type': 'application/json',
'Accept': 'application/json',
}
json_data = {}
r = requests.get("https://api.lexoffice.io/v1/invoices/"+AgencyBills.objects.get(pk=pk).lexid+"/document", data=json_data, headers=headers)
context = {
'active_link' : 'dasettings',
'bill' : AgencyBills.objects.get(pk=pk),
'fileid' : json.loads(r.text)["documentFileId"]
}
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',
'Content-Type': 'application/json',
'Accept': 'application/json',
}
lexdata = {
"renderType" : "pdf"
}
json_data = json.dumps(lexdata)
r = requests.get("https://api.lexoffice.io/v1/invoices/"+AgencyBills.objects.get(pk=pk).lexid+"/document", data=json_data, headers=headers)
json.loads(r.text)
base64String = requests.get("https://api.lexoffice.io/v1/files/"+json.loads(r.text)["documentFileId"]+"/", data=json_data, headers=headers)
buffer = BytesIO.BytesIO()
content = base64.b64decode(base64String.text)
buffer.write(content)
response = HttpResponse(buffer.getvalue(),content_type="application/pdf")
response['Content-Disposition'] = 'inline;filename=some_file.pdf'
return response
'''
AGENCY
@ -1532,9 +1587,12 @@ class BillPlanUpdate(UpdateView):
end_date = month + relativedelta(months=plan)
end_date_string= end_date.strftime("%d.%m.%Y")
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
'''
@ -1545,9 +1603,8 @@ class BillPlanUpdate(UpdateView):
if form.cleaned_data['paymentplan'] == "1":
monthword = "Monat"
lexdata = {
"voucherDate": voucher_date + "T00:00:00.000+00:00",
"voucherDate": voucher_date_today + "T00:00:00.000+00:00",
"address" : {
"name" : agency.name,
"street": agency.street,
@ -1563,7 +1620,7 @@ class BillPlanUpdate(UpdateView):
"type" : "custom",
"name" : "Digitale Agentur: Grundbetrag für " + str(plan) + " " + monthword,
"quantity" : 1,
"unitName" : "Anzahl",
"unitName" : "Stück",
"description" : "Zeitraum " + start_date_string + " - " + end_date_string,
"unitPrice" :
{
@ -1577,7 +1634,7 @@ class BillPlanUpdate(UpdateView):
"name" : "Digitale Agentur: Zusätzliche Mitarbeiter",
"description" : "Zeitraum " + start_date_string + " - " + end_date_string,
"quantity" : usercount,
"unitName" : "Anzahl",
"unitName" : "Stück",
"unitPrice" :
{
"currency" : "EUR",
@ -1594,16 +1651,16 @@ class BillPlanUpdate(UpdateView):
"paymentTermDuration": 14,
},
"shippingConditions": {
"shippingDate": voucher_date + "T00:00:00.000+00:00",
"shippingType": "service"
},
#"shippingDate": voucher_date_today + "T00:00:00.000+00:00",
"shippingType": "none"
}
}
json_data = json.dumps(lexdata)
self.object = form.save(commit=False)
r = requests.post("https://api.lexoffice.io/v1/invoices", data=json_data, headers=headers)
r = requests.post("https://api.lexoffice.io/v1/invoices/?finalize=true", data=json_data, headers=headers)
if(r.status_code == 201):
messages.success(self.request, f"Rechnung erstellt!")
# Response in JSON umwandeln
@ -1627,12 +1684,9 @@ class BillPlanUpdate(UpdateView):
response_text = json.loads(r.text)
if len(agency.lexofficeid) == 0:
self.object.lexofficeid = response_text["organizationId"]
newbill = AgencyBills(agency=agency, lexid=newbill_id, billtype="invoice", billnumber=response_text["voucherNumber"])
newbill = AgencyBills(agency=agency, lexid=newbill_id, billtype="invoice", billnumber=response_text["voucherNumber"], billstatus=response_text["voucherStatus"], start=start_date, end=end_date, plan=plan)
newbill.save()
self.object.save()
else:

1
test.pdf Normal file

File diff suppressed because one or more lines are too long

View File

@ -153,8 +153,11 @@ class AgencyBills(models.Model):
billtype = models.CharField(default="", max_length=200)
billdate = models.DateField(default=timezone.now)
billnumber = models.CharField(default="", max_length=200)
# TODO: Rechnungsstatus dazu ob offen oder nicht
billstatus = models.CharField(default="", max_length=200, null=True, blank=True)
start = models.DateField(default=timezone.now)
end = models.DateField(default=timezone.now)
plan = models.CharField(default="", max_length=20)
def __str__(self):
return f'{self.lexid}'