444 lines
13 KiB
Python
444 lines
13 KiB
Python
from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView, FormView, TemplateView
|
|
from django.contrib import messages
|
|
from django.shortcuts import render, redirect, reverse
|
|
from django.urls import reverse_lazy
|
|
from django.conf import settings
|
|
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
|
|
from .models import MainStatistic
|
|
from django.contrib.auth.models import User
|
|
from chat.models import ChatMessage
|
|
from users.models import Agency, AgencyBills, RegNotfallhilfe
|
|
from standards.models import Standards
|
|
import csv
|
|
from auditlog.models import LogEntry
|
|
from datetime import date, datetime
|
|
import json
|
|
from users.models import UserYearAbsenceInfo, UserTime
|
|
from timemanagement.models import Workday, Absence
|
|
from .forms import AgencyBillForm
|
|
from datetime import date, timedelta
|
|
|
|
from django.core.mail import EmailMessage
|
|
from django.core.mail import EmailMultiAlternatives
|
|
import io as BytesIO
|
|
import base64
|
|
from django.http import HttpResponse
|
|
from dateutil.relativedelta import *
|
|
import requests
|
|
from django.template.loader import render_to_string
|
|
'''
|
|
Prüfung, ob angemeldeter User Mitarbeiterstatus hat. IMMER PER DISPATCH EINBAUEN!
|
|
'''
|
|
def checkForStuffUser(request):
|
|
if request.user.is_staff:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
'''
|
|
|
|
CSV mit Bestellungen herunterladen
|
|
|
|
'''
|
|
def getCSVRDOrders(request):
|
|
if(request.method == "GET"):
|
|
|
|
response = HttpResponse(content_type='text/csv')
|
|
|
|
today = date.today()
|
|
|
|
response['Content-Disposition'] = 'attachment; charset=UTF-8; filename="DA-Export_NF_Bestellungen_' + str(today.day) + '_'+ str(today.month)+'_'+ str(today.year)+'.csv"'
|
|
|
|
writer = csv.writer(response)
|
|
writer.writerow(['Datum', 'E-Mail', 'Name', 'Personalnummer', 'mitgliedsnummer', 'PLZ', 'Stadt', 'Strasse', 'Rabatt'])
|
|
orders = RegNotfallhilfe.objects.filter(wassend=False)
|
|
|
|
for order in orders:
|
|
rabatt = "NEIN"
|
|
if order.rabatt:
|
|
rabatt = "JA"
|
|
writer.writerow([str(order.orderdate),str(order.mail),str(order.name),str(order.persnumber),str(order.mitgliedsnummer),str(order.plz), str(order.stadt),str(order.street), rabatt ])
|
|
order.wassend = True
|
|
order.save()
|
|
return response
|
|
else:
|
|
pass
|
|
|
|
|
|
class delAgency(DeleteView):
|
|
model = Agency
|
|
success_url = reverse_lazy("adm-agencys")
|
|
template_name = "adm/adm_admdelconfirm.html"
|
|
|
|
def delete(self, *args, **kwargs):
|
|
messages.success(self.request, f'Agentur erfolgreich gelöscht!')
|
|
return super(delAgency, self).delete(*args, **kwargs)
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
if(checkForStuffUser(self.request)):
|
|
return super().dispatch(*args, **kwargs)
|
|
else:
|
|
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
|
return redirect("login")
|
|
|
|
'''
|
|
Hauptansicht Statisik
|
|
'''
|
|
class AdmMain(TemplateView):
|
|
template_name = "adm/adm_main.html"
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
if(checkForStuffUser(self.request)):
|
|
return super().dispatch(*args, **kwargs)
|
|
else:
|
|
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
|
return redirect("login")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
context.update({'active_link' : "adm-statistic"})
|
|
|
|
context.update({'statistik' : MainStatistic.objects.all().order_by('staticdate')[:180] })
|
|
context.update({
|
|
"agencycount" : len(Agency.objects.all()),
|
|
"usercount" : len(User.objects.all().exclude(is_staff=True, is_superuser=True)),
|
|
"standardcount" : len(Standards.objects.all()),
|
|
"chatmessagescount" : len(ChatMessage.objects.all())
|
|
})
|
|
return context
|
|
|
|
'''
|
|
|
|
Gesatmübersicht aller Rechnungen
|
|
|
|
'''
|
|
class AdmBills(TemplateView):
|
|
|
|
template_name = "adm/adm_bills.html"
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
if(checkForStuffUser(self.request)):
|
|
return super().dispatch(*args, **kwargs)
|
|
else:
|
|
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
|
return redirect("login")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
context.update({'active_link' : "adm-bills"})
|
|
context.update({'bills' : AgencyBills.objects.all()})
|
|
return context
|
|
|
|
|
|
'''
|
|
Erstellen einer neuen Rechnung
|
|
'''
|
|
class AdmAddBill(CreateView):
|
|
template_name = "adm/adm_addbill.html"
|
|
model = AgencyBills
|
|
success_url = reverse_lazy('adm-bills')
|
|
form_class = AgencyBillForm
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
if(checkForStuffUser(self.request)):
|
|
return super().dispatch(*args, **kwargs)
|
|
else:
|
|
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
|
return redirect("login")
|
|
|
|
def form_valid(self, form):
|
|
|
|
today = date.today()
|
|
|
|
agency = form.cleaned_data['agency']
|
|
|
|
# USERCOUNT BERECHNEN
|
|
usercount = len(User.objects.filter(profile__agency=agency))
|
|
|
|
if(usercount < 4):
|
|
usercount = 0
|
|
else:
|
|
usercount = usercount - 3
|
|
|
|
# HEADERS CURL
|
|
headers = {
|
|
'Authorization': 'Bearer ' + settings.LEX_API,
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
}
|
|
|
|
plan = 1
|
|
|
|
start_date = form.cleaned_data["start"]
|
|
start_date_string = start_date.strftime("%d.%m.%Y")
|
|
end_date = start_date + relativedelta(days=30)
|
|
end_date_string= end_date.strftime("%d.%m.%Y")
|
|
|
|
# Rechnungsdatum passt ja
|
|
voucher_date_today = date.today().strftime("%Y-%m-%d")
|
|
|
|
monthword = "Monat"
|
|
|
|
lexdata = {
|
|
"voucherDate": voucher_date_today + "T00:00:00.000+00:00",
|
|
"address" : {
|
|
"name" : agency.name,
|
|
"street": agency.street,
|
|
"zip": agency.plz,
|
|
"city": agency.city,
|
|
"countryCode" : "DE"
|
|
},
|
|
"totalPrice" : {
|
|
"currency" : "EUR",
|
|
},
|
|
"lineItems" : [
|
|
{
|
|
"type" : "custom",
|
|
"name" : "Digitale Agentur: Grundbetrag für " + str(plan) + " " + monthword,
|
|
"quantity" : 1,
|
|
"unitName" : "Stück",
|
|
"description" : "Zeitraum " + start_date_string + " - " + end_date_string,
|
|
"unitPrice" :
|
|
{
|
|
"currency" : "EUR",
|
|
"netAmount" : 21.00,
|
|
"taxRatePercentage" : 19
|
|
},
|
|
},
|
|
{
|
|
"type" : "custom",
|
|
"name" : "Digitale Agentur: Zusätzliche Nutzer",
|
|
"description" : "Zeitraum " + start_date_string + " - " + end_date_string,
|
|
"quantity" : usercount,
|
|
"unitName" : "Stück",
|
|
"unitPrice" :
|
|
{
|
|
"currency" : "EUR",
|
|
"netAmount" : 3,
|
|
"taxRatePercentage" : 19
|
|
},
|
|
}
|
|
],
|
|
"taxConditions": {
|
|
"taxType": "net"
|
|
},
|
|
#"paymentConditions": {
|
|
# "paymentTermLabel": "Bitte zahlen Sie innerhalb von 14 Tagen.",
|
|
# "paymentTermDuration": 14,
|
|
#},
|
|
"shippingConditions": {
|
|
#"shippingDate": voucher_date_today + "T00:00:00.000+00:00",
|
|
"shippingType": "none"
|
|
}
|
|
}
|
|
json_data = json.dumps(lexdata)
|
|
# WIEDER RAUSNEHMEN
|
|
# NEUE RECHNUNG ALs ENTWURF
|
|
|
|
#r = requests.post("https://api.lexoffice.io/v1/invoices/", data=json_data, headers=headers)
|
|
# RICHTIGE RECHNUNG
|
|
r = requests.post("https://api.lexoffice.io/v1/invoices/?finalize=true", data=json_data, headers=headers)
|
|
|
|
if(r.status_code == 201):
|
|
|
|
response_text = json.loads(r.text)
|
|
newbill_id = response_text["id"]
|
|
|
|
# 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)
|
|
|
|
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, usercount=usercount)
|
|
newbill.save()
|
|
|
|
mail_to_send = ""
|
|
if(agency.payment_address == None):
|
|
mail_to_send = agency.agency_email
|
|
else:
|
|
mail_to_send = agency.payment_address
|
|
|
|
|
|
|
|
# BCC Mail with Object - NICHT DEN IMPORT VERGESSEN!!!
|
|
email = EmailMultiAlternatives(
|
|
'Digitale Agentur | Rechnung ' + str(response_text["voucherNumber"]),
|
|
'Sehr geehrte Nutzer, hiermit erhalten Sie eine neue Rechnung für die Digitale Agentur. Ihr Team der Digitalen Agentur',
|
|
'noreply@digitale-agentur.com',
|
|
[mail_to_send],
|
|
['info@digitale-agentur.com'],
|
|
headers={},
|
|
)
|
|
|
|
headers = {
|
|
'Authorization': 'Bearer ' + settings.LEX_API,
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
}
|
|
|
|
lexdata = {
|
|
"renderType" : "pdf"
|
|
}
|
|
|
|
json_data = json.dumps(lexdata)
|
|
|
|
r_final = requests.get("https://api.lexoffice.io/v1/invoices/"+newbill_id+"/document", data=json_data, headers=headers)
|
|
json.loads(r_final.text)
|
|
|
|
base64String = requests.get("https://api.lexoffice.io/v1/files/"+json.loads(r_final.text)["documentFileId"]+"/", data=json_data, headers=headers)
|
|
|
|
content = base64.b64decode(base64String.text)
|
|
|
|
msg_html = render_to_string('users/newbill_mail.html', {})
|
|
email.attach_alternative(msg_html, "text/html")
|
|
email.attach('Rechnung_' + str(response_text["voucherNumber"]) + '.pdf', content, "application/pdf")
|
|
email.send()
|
|
|
|
return super(AdmAddBill, self).form_valid(form)
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
context.update({'active_link' : "adm-agencys"})
|
|
|
|
#context.update({'agencys' : Agency.objects.all()})
|
|
|
|
return context
|
|
|
|
|
|
'''
|
|
Gesamtansicht der Agenturen
|
|
'''
|
|
class AdmAgencys(TemplateView):
|
|
template_name = "adm/adm_agencys.html"
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
if(checkForStuffUser(self.request)):
|
|
return super().dispatch(*args, **kwargs)
|
|
else:
|
|
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
|
return redirect("login")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
context.update({'active_link' : "adm-agencys"})
|
|
|
|
context.update({'agencys' : Agency.objects.all()})
|
|
|
|
return context
|
|
|
|
|
|
class AdmUsers(TemplateView):
|
|
template_name = "adm/adm_users.html"
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
if(checkForStuffUser(self.request)):
|
|
return super().dispatch(*args, **kwargs)
|
|
else:
|
|
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
|
return redirect("login")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
context.update({'active_link' : "adm-users"})
|
|
|
|
context.update({'users' : User.objects.all().exclude(is_staff=True, is_superuser=True)})
|
|
|
|
return context
|
|
|
|
'''
|
|
Einzelansicht der Agenturen
|
|
'''
|
|
class AdmAgencySingle(TemplateView):
|
|
template_name = "adm/adm_agency_single.html"
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
if(checkForStuffUser(self.request)):
|
|
return super().dispatch(*args, **kwargs)
|
|
else:
|
|
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
|
return redirect("login")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context.update({'active_link' : "adm-agencys"})
|
|
context.update({'agency' : Agency.objects.get(pk=kwargs['agpk'])})
|
|
context.update({'bills' : AgencyBills.objects.filter(agency=Agency.objects.get(pk=kwargs['agpk'])).order_by('-billdate')[:3]})
|
|
context.update({'users_of_agency' : User.objects.filter(profile__agency=Agency.objects.get(pk=kwargs['agpk'])).order_by('-last_name')})
|
|
return context
|
|
|
|
class AdmUserSingle(TemplateView):
|
|
template_name = "adm/adm_user_single.html"
|
|
|
|
def dispatch(self, *args, **kwargs):
|
|
if(checkForStuffUser(self.request)):
|
|
return super().dispatch(*args, **kwargs)
|
|
else:
|
|
messages.warning(self.request, f'Sie benötigen einen Mitarbeiter-Account, um diese Seiten aufzurufen!')
|
|
return redirect("login")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
userrequested = User.objects.get(pk=kwargs['uspk'])
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
context.update({'active_link' : "adm-users"})
|
|
context.update({'userdata' : userrequested})
|
|
|
|
# Loading Logindata
|
|
logdata = LogEntry.objects.filter(object_pk=kwargs['uspk'])[:50]
|
|
|
|
logdata_logins = []
|
|
|
|
for ele in reversed(logdata):
|
|
try:
|
|
datestring = json.loads(ele.changes)["last_login"][1]
|
|
|
|
datestring = datestring.split(".")[0]
|
|
logdata_logins.append(datetime.strptime(datestring, '%Y-%m-%d %H:%M:%S'))
|
|
except:
|
|
pass
|
|
|
|
context.update({'logdata' : logdata_logins})
|
|
|
|
context.update({'workdays' : Workday.objects.filter(user=userrequested)})
|
|
context.update({'absences' : Absence.objects.filter(user=userrequested)})
|
|
context.update({'yearinfo' : UserYearAbsenceInfo.objects.filter(user=userrequested)})
|
|
context.update({'usertimedata' : UserTime.objects.get(user=userrequested)})
|
|
return context
|
|
|
|
|
|
|
|
# CRONJOB, um die Statistik zu füllen!
|
|
def statisticCronJob(request, code):
|
|
data = {}
|
|
if(code == settings.CRONAPIKEY_STATSTIC):
|
|
print("STATISTIC is running...")
|
|
newMainS = MainStatistic(agencys=len(Agency.objects.all()),users=len(User.objects.all().exclude(is_staff=True, is_superuser=True)),standards=len(Standards.objects.all()),chatmessages=len(ChatMessage.objects.all()))
|
|
newMainS.save()
|
|
data.update({"status" : "success"})
|
|
else:
|
|
print("API STATISTIC CODE FAILED")
|
|
data.update({"status" : "failed"})
|
|
return JsonResponse(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|