From 4e3f916ffbdbb2af47ac380e9cb2b2b5b9de3c88 Mon Sep 17 00:00:00 2001 From: "holger.trampe" Date: Thu, 1 Oct 2020 09:20:54 +0200 Subject: [PATCH] Abrechnung --- dasettings/forms.py | 6 +- .../templates/dasettings/calc_content.html | 4 +- .../dasettings/dasettings_billplan.html | 14 ++- dasettings/views.py | 118 ++++++++++++++---- .../templates/standards/standards_add.html | 13 +- .../templates/standards/standards_update.html | 2 +- .../__pycache__/counter_tag.cpython-38.pyc | Bin 17240 -> 17223 bytes standards/templatetags/counter_tag.py | 5 +- users/models.py | 3 + users/urls.py | 1 + users/views.py | 3 + 11 files changed, 134 insertions(+), 35 deletions(-) diff --git a/dasettings/forms.py b/dasettings/forms.py index b85775c..0e31586 100644 --- a/dasettings/forms.py +++ b/dasettings/forms.py @@ -58,13 +58,15 @@ class AgencyBillPlan(forms.ModelForm): "phone" : "Telefon", "agb" : "AGB akzeptieren", "contract" : "Auftragsdatenverarbeitung akzeptieren" - } - fields = ['name','inhaber','agency_email', 'phone', 'street', 'plz', 'city', 'paymentplan', 'agb', 'contract'] + fields = ['name','inhaber','agency_email', 'phone', 'street', 'plz', 'city', 'paymentplan', 'agb', 'contract', 'lexofficeid', 'firstbillid'] def __init__(self, *args, **kwargs): super(AgencyBillPlan, self).__init__(*args, **kwargs) self.fields['paymentplan'] = forms.CharField(initial=6, required=True, widget=forms.HiddenInput()) + self.fields['lexofficeid'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput()) + self.fields['firstbillid'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput()) + self.fields['name'] = forms.CharField(required=True) self.fields['inhaber'] = forms.CharField(required=True) diff --git a/dasettings/templates/dasettings/calc_content.html b/dasettings/templates/dasettings/calc_content.html index 37bb399..5ed2d7a 100644 --- a/dasettings/templates/dasettings/calc_content.html +++ b/dasettings/templates/dasettings/calc_content.html @@ -35,10 +35,10 @@
Ihre Zahlungsweise
{% getNextMonth request.user.profile.agency as nextMonth %} - + {{request.user.profile.agency.firstbillid}} Ihre Agentur wurde am {{ request.user.profile.agency.registerdate|date:"d.m.Y" }} registriert. - {% if paymentplan == None %} + {% if paymentplan == None and request.user.profile.agency.firstbillid == None %} 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.
Zahlplan jetzt auswählen diff --git a/dasettings/templates/dasettings/dasettings_billplan.html b/dasettings/templates/dasettings/dasettings_billplan.html index 9d22ced..05e6eb3 100644 --- a/dasettings/templates/dasettings/dasettings_billplan.html +++ b/dasettings/templates/dasettings/dasettings_billplan.html @@ -25,20 +25,26 @@

Wählen Sie aus, für welchen Zeitraum die Abrechnung Ihrer Digitalen Agentur durchgeführt werden soll.

- + +
+
+ +
- 6 Monate
- -
diff --git a/dasettings/views.py b/dasettings/views.py index cbc9760..968cef0 100644 --- a/dasettings/views.py +++ b/dasettings/views.py @@ -242,6 +242,27 @@ def DASettings(request): agencyform = AgencyUpdateForm(instance=request.user.profile.agency) context.update({'agencyform' : agencyform}) + # Abrechnung BILLS + + # TEST ID + # TODO: Hier Rechnungen der Agentur laden + lexdata = {} + + # HEADERS CURL + headers = { + 'Authorization': 'Bearer 8f9ba01f-9e84-42c7-9548-48c254f14c19', + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + + json_data = json.dumps(lexdata) + + r = requests.get("https://api.lexoffice.io/v1/invoices/ad75e041-1657-43a3-b3cb-7349aa00a94f", data=json_data, headers=headers) + + + + + return render(request, 'dasettings/settings.html', context) ''' @@ -1470,13 +1491,6 @@ class BillPlanUpdate(UpdateView): def form_valid(self, form): agency = self.request.user.profile.agency - # HEADERS CURL - headers = { - 'Authorization': 'Bearer 33bfb1b9-2994-4fd4-b447-1f4754a5c7cb', - 'Content-Type': 'application/json', - 'Accept': 'application/json', - } - month = agency.registerdate next_month = month + relativedelta(months=1) @@ -1490,11 +1504,41 @@ class BillPlanUpdate(UpdateView): else: usercount = usercount - 3 + # HEADERS CURL + headers = { + 'Authorization': 'Bearer 8f9ba01f-9e84-42c7-9548-48c254f14c19', + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + + plan = int(form.cleaned_data['paymentplan']) + + start_date = month + start_date_string = month.strftime("%d.%m.%Y") + end_date = month + relativedelta(months=plan) + end_date_string= end_date.strftime("%d.%m.%Y") + + # TODO: Nachgebuchte Mitarbeiter + # TODO: Was passiert bei Änderungen der Agenturdaten? + # TODO: Kündigungsmöglichkeit, den Zahlplan zu beenden # DataJSON + ''' + + Bei Beschreibung noch Zeitraum vom XX.XX.XXXX bis XX.XX.XXXX + + ''' + monthword = "Monate" + if form.cleaned_data['paymentplan'] == "1": + monthword = "Monat" + + lexdata = { - "voucherDate": voucher_date + "T00:00:00.000+01:00", + "voucherDate": voucher_date + "T00:00:00.000+00:00", "address" : { "name" : agency.name, + "street": agency.street, + "zip": agency.plz, + "city": agency.city, "countryCode" : "DE" }, "totalPrice" : { @@ -1503,46 +1547,76 @@ class BillPlanUpdate(UpdateView): "lineItems" : [ { "type" : "custom", - "name" : "Monatsbeitrag", - "quantity" : form.cleaned_data['paymentplan'], - "unitName" : "Stück", + "name" : "Digitale Agentur: Grundbetrag für " + str(plan) + " " + monthword, + "quantity" : 1, + "unitName" : "Anzahl", + "description" : "Zeitraum " + start_date_string + " - " + end_date_string, "unitPrice" : { "currency" : "EUR", - "netAmount" : 21.00, - "taxRatePercentage" : 19 + "netAmount" : 21.00 * int(form.cleaned_data['paymentplan']), + "taxRatePercentage" : 16 }, }, { "type" : "custom", - "name" : "Weitere Mitarbeiter", + "name" : "Digitale Agentur: Zusätzliche Mitarbeiter", + "description" : "Zeitraum " + start_date_string + " - " + end_date_string, "quantity" : usercount, - "unitName" : "Stück", + "unitName" : "Anzahl", "unitPrice" : { "currency" : "EUR", - "netAmount" : 3, - "taxRatePercentage" : 19 + "netAmount" : 3 * int(form.cleaned_data['paymentplan']), + "taxRatePercentage" : 16 }, } ], "taxConditions": { "taxType": "net" }, + "paymentConditions": { + "paymentTermLabel": "Bitte zahlen Sie innerhalb von 14 Tagen.", + "paymentTermDuration": 14, + }, "shippingConditions": { - "shippingDate": voucher_date + "T00:00:00.000+01:00", + "shippingDate": voucher_date + "T00:00:00.000+00:00", "shippingType": "service" }, } json_data = json.dumps(lexdata) - r = requests.post("https://api.lexoffice.io/v1/vouchers", data=json_data, headers=headers) + self.object = form.save(commit=False) - if(r.status_code != 200): + r = requests.post("https://api.lexoffice.io/v1/invoices", data=json_data, headers=headers) + + if(r.status_code == 201): + messages.success(self.request, f"Rechnung erstellt!") + # Response in JSON umwandeln + response_text = json.loads(r.text) + # Rechnungsidee speichern + self.object.firstbillid = response_text["id"] + # HEADERS CURL + headers = { + 'Authorization': 'Bearer 8f9ba01f-9e84-42c7-9548-48c254f14c19', + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + + json_data = json.dumps(lexdata) + + if len(agency.lexofficeid) == 0: + # OrganizationId berechnen, wenn noch nicht gesetzt + r = requests.get("https://api.lexoffice.io/v1/invoices/" + response_text["id"], data=json_data, headers=headers) + + response_text = json.loads(r.text) + self.object.lexofficeid = response_text["organizationId"] + + self.object.save() + + else: messages.warning(self.request, f"Fehlercode "+str(r.status_code)+". Es wurde keine Rechnung erstellt. Bitte wenden Sie sich an den Support!") - print(r.status_code) - return super().form_valid(form) diff --git a/standards/templates/standards/standards_add.html b/standards/templates/standards/standards_add.html index 189a530..e30a75d 100644 --- a/standards/templates/standards/standards_add.html +++ b/standards/templates/standards/standards_add.html @@ -1081,7 +1081,18 @@ $(document).ready(function() { $('#id_content').summernote({ height: 400, lang: "de-DE", - disableDragAndDrop: true + disableDragAndDrop: true, + /* TASK: Hier Fontsize zzgl zu den anderen machen, damit das auch geht */ + /* + toolbar: [ + ['style', ['style']], + ['text', ['bold', 'italic', 'underline', 'color', 'clear']], + ['para', ['ul', 'ol', 'paragraph']], + ['height', ['height']], + ['fontsize', ['fontsize']], + ['font', ['fontname']], + ], + */ }); }); diff --git a/standards/templates/standards/standards_update.html b/standards/templates/standards/standards_update.html index e3685d0..d8cfd7d 100644 --- a/standards/templates/standards/standards_update.html +++ b/standards/templates/standards/standards_update.html @@ -827,7 +827,7 @@ $("#id_area").change(function () { $(document).ready(function() { $('#id_content').summernote({ lang: "de-DE", - height: 400, + height: 100, disableDragAndDrop: true }); }); diff --git a/standards/templatetags/__pycache__/counter_tag.cpython-38.pyc b/standards/templatetags/__pycache__/counter_tag.cpython-38.pyc index d2391546ee01c53e7b4defd99549b7e354596815..beb32a1561fd24c470514852411ad7db5ab6f2a3 100644 GIT binary patch delta 3248 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 Pz(%~*m^D?ju9W@@A3_Uj diff --git a/standards/templatetags/counter_tag.py b/standards/templatetags/counter_tag.py index d889e4e..1c8f2ae 100644 --- a/standards/templatetags/counter_tag.py +++ b/standards/templatetags/counter_tag.py @@ -715,7 +715,7 @@ def loadMWST(user): else: usercount = usercount - 3 - mwst = (21.0 + usercount*3)/100 * 19 + mwst = (21.0 + usercount*3)/100 * 16 return mwst @@ -728,8 +728,7 @@ def loadFinalMoney(user): else: usercount = usercount - 3 - finalMoney = ((21.0 + usercount*3)/100 * 19) + 21.0 + usercount*3 - + finalMoney = (21.0 + usercount*3) * 1.16 return finalMoney diff --git a/users/models.py b/users/models.py index 0034b03..afc0666 100644 --- a/users/models.py +++ b/users/models.py @@ -98,6 +98,9 @@ class Agency(models.Model): # ID für die Verbindung mit Lexoffice lexofficeid = models.CharField(default="", max_length=200, blank=True) + # First Bill id to retrieve office-organization-id + firstbillid = models.CharField(default=None, max_length=200, blank=True, null=True) + # Bezahlplan 3,6,12 Monate paymentplan = models.IntegerField(default=None, null=True, blank=True) diff --git a/users/urls.py b/users/urls.py index cfb2149..890fde2 100644 --- a/users/urls.py +++ b/users/urls.py @@ -39,6 +39,7 @@ urlpatterns = [ path('changeonlinestat/', views.changeonlinestat, name="users-updateonlinestat"), path('dacron/', views.cronactions, name="cronmain"), path('dacrondaily/', views.cronactionsdaily, name="cronmaindaily"), + path('isalive/', views.isAlive, name="isalive") ] diff --git a/users/views.py b/users/views.py index af907e9..4d4d6c4 100644 --- a/users/views.py +++ b/users/views.py @@ -1148,3 +1148,6 @@ def sendMailNoti(notificationtext, user_touched, linktarget=""): html_message=msg_html, fail_silently=True ) + +def isAlive(request): + return JsonResponse({"status" : True})