digitaleagenturnc/users/signals.py

909 lines
39 KiB
Python

from django.db.models.signals import post_save, pre_delete, m2m_changed, pre_save
from django.contrib.auth.models import User, Group
from django.dispatch import receiver
from .models import Profile, Agency, AgencyGroup, AgencyNetworkPreperation, UserYearAbsenceInfo, UserTime, UserNotifications
from news.models import News
from django.contrib.auth.models import Permission
from notificsys.models import UserNotification
from django.core.mail import send_mail
from django.template.loader import render_to_string
from tasks.models import Tasks
from cloud.models import DataFile, DataDir
import os
from django.conf import settings
from django.utils import timezone
from standards.models import Standards
from django.contrib.auth.signals import user_logged_in, user_logged_out
from timemanagement.models import Workday, Breaks, AbsenceReason, FreeDays, Absence
from datetime import date
import datetime, json
from django.utils import timezone
import requests, csv, os
from django.templatetags.static import static
from django.conf import settings
from datetime import date
import channels.layers
from asgiref.sync import async_to_sync
from django.contrib.auth.decorators import login_required
from datetime import timedelta
from django.core.signals import request_started
from channels_presence.models import Room
from channels_presence.models import Presence
from channels_presence.signals import presence_changed
from organizer.models import *
from chat.models import ChatMessage
def loadingFreeDays(plz, year):
# Getting land
file_path = os.path.join(settings.STATIC_ROOT, 'users/extra/plz_short.csv')
land = False
with open(file_path, 'rt') as csvfile:
filecsv = csv.reader(csvfile, delimiter=';')
for row in filecsv:
if str(row[1] == str(plz)):
land = row[6]
break;
if(land != False):
URL = "https://feiertage-api.de/api/"
PARAMS = {'jahr':year,'nur_land':land}
r = requests.get(url = URL, params = PARAMS)
return r.json()
else:
return False
# CHECK SOMETHING WHEN USER LOGGED IN
@receiver(signal=user_logged_out, sender=User)
def checkForFreeDays(sender, user, request, **kwargs):
user.profile.onlinestatus = 3
user.save()
# CHECK SOMETHING WHEN USER LOGGED IN
@receiver(signal=user_logged_in, sender=User)
def checkDefaultAbsenceReasons(sender, user, request, **kwargs):
user.profile.onlinestatus = 0
user.save()
ar = AbsenceReason.objects.filter(agency=user.profile.agency)
if(len(ar) == 0):
new_ar_holidays = AbsenceReason(agency=user.profile.agency, name="Urlaub", color="#0099BC", need_confirm=True, need_rep=True, is_holiday=True)
new_ar_holidays.save()
new_ar_specialholidays = AbsenceReason(agency=user.profile.agency, name="Sonderurlaub", need_confirm=True, need_rep=True, is_holiday=False, color="#F39C12")
new_ar_specialholidays.save()
new_ar_ill = AbsenceReason(agency=user.profile.agency, name="Krankheit", color="#E74C3C", need_confirm=False, need_rep=False, is_holiday=False)
new_ar_ill.save()
new_ar_school = AbsenceReason(agency=user.profile.agency, name="Berufsschule", color="#16A085", need_confirm=False, need_rep=False, is_holiday=False)
new_ar_school.save()
new_ar_education = AbsenceReason(agency=user.profile.agency, name="Fortbildung", color="#2ECC71", need_confirm=True, need_rep=True, is_holiday=False)
new_ar_education.save()
new_ar_time = AbsenceReason(agency=user.profile.agency, name="Gleitzeit", color="#9B59B6", need_confirm=True, need_rep=False, is_holiday=False)
new_ar_time.save()
today = date.today()
# FREEDAYS LADEN
if len(FreeDays.objects.filter(agency=user.profile.agency, year=today.year+2)) == 0:
tempdays = loadingFreeDays(user.profile.agency.plz, today.year+2)
if(tempdays != False):
for k in tempdays.keys():
tempdate = tempdays[k]["datum"].split("-")
FreeDays(agency=user.profile.agency, name=k, day=datetime.datetime(int(tempdate[0]),int(tempdate[1]),int(tempdate[2])), year=date.today().year+2).save()
# CHECK FOR YEARS
# NO YEARS FOUND
if len(UserYearAbsenceInfo.objects.filter(agency=user.profile.agency)) == 0:
# CREATE DATA FOR EVERY USER
uina = User.objects.filter(profile__agency=user.profile.agency)
for u in uina:
UserYearAbsenceInfo(agency=user.profile.agency, user=u, year=today.year).save()
UserYearAbsenceInfo(agency=user.profile.agency, user=u, year=today.year+1).save()
UserYearAbsenceInfo(agency=user.profile.agency, user=u, year=today.year+2).save()
pass
# CREATE DATE FOR YEAR PLUS 2
elif len(UserYearAbsenceInfo.objects.filter(agency=user.profile.agency, year=today.year+2)) == 0:
uina = User.objects.filter(profile__agency=user.profile.agency)
for u in uina:
UserYearAbsenceInfo(agency=user.profile.agency, user=u, year=today.year+2).save()
'''
FUNKTION ZUM SENDEN VON MAILS AUS EINEM SIGNAL
'''
def sendMailNoti(notificationtext, user_touched, linktarget=""):
username = user_touched.first_name + " " + user_touched.last_name
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext, 'linktarget' : linktarget})
send_mail(
'Agentur-Benachrichtigung',
'Hallo ' + user_touched.first_name + ' ' + user_touched.last_name + '! ' + notificationtext,
'noreply@digitale-agentur.com',
[user_touched.email],
html_message=msg_html,
fail_silently=True
)
# Deletes all Notifications added to to delete news
@receiver(pre_delete, sender=News)
def del_news_notifications(sender, instance, **kwargs):
UserNotification.objects.filter(elementid=instance.pk).delete()
#USER SIGNAL
@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
# SIGNALS FOR GROUPS
# Signal für das Ändern von Gruppenrechten
@receiver(signal=m2m_changed, sender=Group.permissions.through)
def adjust_group_notifications_permission(instance, action, reverse, model, pk_set, using, *args, **kwargs):
group_touched = AgencyGroup.objects.get(group=instance)
# Rechte wurden hinzugefügt
if(action == "post_add"):
users_in_group = instance.user_set.all()
for user in users_in_group:
if(user.usernotifications.group_rights_mail):
notificationtext = "Die Gruppe " + group_touched.agencygroupname + " hat neue Rechte erhalten."
sendMailNoti(notificationtext, user)
if(user.usernotifications.group_rights_push):
newnotification = UserNotification(touser=user, notificationtext="Die Gruppe " + group_touched.agencygroupname + " hat neue Rechte erhalten.", notificationtype="groupchanges")
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Die Gruppe " + group_touched.agencygroupname + " hat neue Rechte erhalten."})
# Rechte wurden entfernt
elif(action == "post_remove"):
users_in_group = instance.user_set.all()
for user in users_in_group:
if(user.usernotifications.group_rights_mail):
notificationtext = "Der Gruppe " + group_touched.agencygroupname + " wurden Rechte entzogen."
sendMailNoti(notificationtext, user)
if(user.usernotifications.group_rights_push):
newnotification = UserNotification(touser=user, notificationtext="Der Gruppe " + group_touched.agencygroupname + " wurden Rechte entzogen.", notificationtype="groupchanges")
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Der Gruppe " + group_touched.agencygroupname + " wurden Rechte entzogen."})
# Signal, wenn ein Nutzer aus der Gruppe entfernt/hinzugefügt wird
@receiver(signal=m2m_changed, sender=User.groups.through)
def adjust_group_notifications(instance, action, reverse, model, pk_set, using, *args, **kwargs):
if isinstance(instance, Group):
group_touched = AgencyGroup.objects.get(group=instance)
userid = list(pk_set)[0]
user_touched = User.objects.get(pk=userid)
# PUSH NOTIFICATION FOR GROUOPCHANGES AND WEBSOCKET
if(user_touched.usernotifications.group_activity_push):
if(action == 'post_remove'):
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden aus der Gruppe " + group_touched.agencygroupname + " entfernt.", notificationtype="groupchanges")
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Sie wurden aus der Gruppe " + group_touched.agencygroupname + " entfernt."})
# A USER WAS ADDED TO A GROUP
elif(action == 'post_add'):
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden zur Gruppe " + group_touched.agencygroupname + " hinzugefügt.", notificationtype="groupchanges")
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Sie wurden zur Gruppe " + group_touched.agencygroupname + " hinzugefügt."})
# E-MAILNOTIFICATIONS FOR GROUPCHANGES
if(user_touched.usernotifications.group_activity_mail):
notificationtext = ""
if(action == 'post_remove'):
notificationtext = "Sie wurden aus der Gruppe " + group_touched.agencygroupname + " entfernt."
username = user_touched.first_name + " " + user_touched.last_name
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext})
send_mail(
'Agentur-Benachrichtigung',
'Hallo ' + user_touched.first_name + ' ' + user_touched.last_name + '! ' + notificationtext,
'noreply@digitale-agentur.com',
[user_touched.email],
html_message=msg_html,
fail_silently=True
)
# A USER WAS ADDED TO A GROUP
elif(action == 'post_add'):
notificationtext = "Sie wurden zur Gruppe " + group_touched.agencygroupname + " hinzugefügt."
username = user_touched.first_name + " " + user_touched.last_name
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext})
send_mail(
'Agentur-Benachrichtigung',
'Hallo ' + user_touched.first_name + ' ' + user_touched.last_name + '! ' + notificationtext,
'noreply@digitale-agentur.com',
[user_touched.email],
html_message=msg_html,
fail_silently=True
)
# SIGNALS FOR STANDARDS
# DELETE
@receiver(pre_delete, sender=Standards)
def delete_standard(sender, instance, **kwargs):
newNotifiyPush(2, instance, " es wurde ein neuer Agenturstandard gelöscht: ", "Agenturstandard gelöscht: ", "Standards | ", "", "")
# SAVE AND UPDATE
@receiver(post_save, sender=Standards)
def save_standard(sender, instance, **kwargs):
targeturl = settings.BASE_URL + "standards/standard/" + str(instance.pk) + "/single"
# NEW STANDARD
if(kwargs["created"] and len(instance.name) > 0):
if(instance.public):
newNotifiyPush(0, instance, " es wurde ein neuer Agenturstandard erstellt: ", "Neuer Agenturstandard: ", "Standards | ", "newstandard", targeturl)
else:
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
for user in usersofagency:
if(user.has_perm("users.standardmanager") and user.usernotifications.standard_created_unpub_push):
newnotification = UserNotification(touser=user, notificationtext="Neuer unveröffentlichter Agenturstandard: " + instance.name, notificationtype="newstandard", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Standards | Neuer unveröffentlichter Agenturstandard: " + instance.name})
if(user.has_perm("users.standardmanager") and user.usernotifications.standard_created_unpub_mail):
notificationtext = " es wurde ein neuer unveröffentlichter Agenturstandard erstellt: " + instance.name
sendMailNoti(notificationtext, user)
# Standard wurde aktualisiert
else:
newNotifiyPush(1, instance, " es wurde ein neuer Agenturstandard aktualisiert: ", "Agenturstandard aktualisiert: ", "Standards | ", "newstandard", targeturl)
# SIGNAL FOR NEWS
@receiver(post_save, sender=News)
def save_news(sender, instance, **kwargs):
if(kwargs["created"]):
targeturl = settings.BASE_URL + "news/news/" + str(instance.pk) + "/single"
# Prüfung, ob die News SOFORT online geht oder später
if(instance.go_online_on < timezone.now() and instance.agnotify):
newNotifiyPush(0, instance, " es gibt neue Agenturnews: ", "Neue Agenturnews: ", "News | ", "", targeturl)
else:
instance.agnotify = False
instance.save()
# SIGNALS FOR TASK
@receiver(signal=m2m_changed, sender=Tasks.usersfield.through)
def adjust_group_notifications_task(instance, action, reverse, model, pk_set, using, *args, **kwargs):
# A USER WAS TOUCHED ATT HIS TASKS
user_touched = User.objects.get(pk=list(pk_set)[0])
taskname = instance.name
# PUSH NOTIFICATION FOR GROUOPCHANGES
if(user_touched.usernotifications.task_activity_push):
if(action == 'post_remove'):
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden von der Tätigkeit " + taskname + " entfernt.", notificationtype="taskchange")
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Tätigkeitsbereich | Sie wurden von der Tätigkeitn " + instance.name + " entfernt."})
# A USER WAS ADDED TO A GROUP
elif(action == 'post_add'):
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden der Tätigkeit " + taskname + " zugeordnet.", notificationtype="taskchange")
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Tätigkeitsbereich | Sie wurden der Tätigkeitn " + instance.name + " zugeordnet."})
# E-MAILNOTIFICATIONS FOR GROUPCHANGES
if(user_touched.usernotifications.task_activity_mail):
notificationtext = ""
if(action == 'post_remove'):
notificationtext = "Sie wurden von der Tätigkeit " + taskname + " entfernt."
sendMailNoti(notificationtext, user_touched)
# A USER WAS ADDED TO A GROUP
elif(action == 'post_add'):
notificationtext = "Sie wurden der Tätigkeit " + taskname + " zugeordnet."
sendMailNoti(notificationtext, user_touched)
'''
newNotifiyPush
@param:
instance - Objekt des Signals
mode - Modus 0 --> CREATED, 1 --> UPDATE, 3 --> DELETE
mailtext - Text in der Benachrichtigung
zB " es gibt neue Ordner: "
notifytext - Text in der PUSH-Nachricht
zB "Neuer Ordner: "
pushtext - Typ bei PUSH (hinter pushnotification__)
zB "Ordner | " + notifytext
notifytype - Typ für Verlinkung
targeturl - URL für Verlinkung, Default = ""
'''
def newNotifiyPush(mode, instance, mailtext, notifytext, pushtext, notifytype, targeturl=""):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
# CREATED
for user in usersofagency:
# LOAD USERNOTIFICATIONS
created_mail = False
created_push = False
update_mail = False
update_push = False
delete_mail = False
delete_push = False
if isinstance(instance, Standards):
created_mail = user.usernotifications.standard_created_mail
created_push = user.usernotifications.standard_created_push
update_mail = user.usernotifications.standard_update_mail
update_push = user.usernotifications.standard_update_push
delete_mail = user.usernotifications.standard_delete_mail
delete_push = user.usernotifications.standard_delete_push
elif isinstance(instance, News):
created_mail = user.usernotifications.news_created_mail
created_push = user.usernotifications.news_created_push
elif isinstance(instance, DataFile) or isinstance(instance, DataDir):
created_mail = user.usernotifications.filedir_created_mail
created_push = user.usernotifications.filedir_created_push
update_mail = user.usernotifications.filedir_update_mail
update_push = user.usernotifications.filedir_update_push
delete_mail = user.usernotifications.filedir_delete_mail
delete_push = user.usernotifications.filedir_delete_push
elif isinstance(instance, QuickLinks):
created_mail = user.usernotifications.ql_created_mail
created_push = user.usernotifications.ql_created_push
update_mail = user.usernotifications.ql_update_mail
update_push = user.usernotifications.ql_update_push
delete_mail = user.usernotifications.ql_delete_mail
delete_push = user.usernotifications.ql_delete_push
elif isinstance(instance, AGContacts):
created_mail = user.usernotifications.contact_created_mail
created_push = user.usernotifications.contact_created_push
update_mail = user.usernotifications.contact_update_mail
update_push = user.usernotifications.contact_update_push
delete_mail = user.usernotifications.contact_delete_mail
delete_push = user.usernotifications.contact_delete_push
elif isinstance(instance, AGPassword):
created_mail = user.usernotifications.password_created_mail
created_push = user.usernotifications.password_created_push
update_mail = user.usernotifications.password_update_mail
update_push = user.usernotifications.password_update_push
delete_mail = user.usernotifications.password_delete_mail
delete_push = user.usernotifications.password_delete_push
elif isinstance(instance, Message):
created_mail = user.usernotifications.message_received_mail
created_push = user.usernotifications.message_received_push
if(mode == 0):
if(created_mail):
notificationtext = mailtext + instance.name
sendMailNoti(notificationtext, user, targeturl)
if(created_push):
newnotification = UserNotification(touser=user, notificationtext=notifytext + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__"+ pushtext + notifytext + instance.name})
# UPDATED
elif(mode == 1):
if(update_mail):
notificationtext = mailtext + instance.name
sendMailNoti(notificationtext, user, targeturl)
if(update_push):
newnotification = UserNotification(touser=user, notificationtext=notifytext + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__" + pushtext + notifytext + instance.name})
#DELETE
elif(mode == 2):
if(delete_mail):
notificationtext = mailtext + instance.name
sendMailNoti(notificationtext, user, targeturl)
if(delete_push):
newnotification = UserNotification(touser=user, notificationtext=notifytext + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__" + pushtext + notifytext + instance.name})
# DIRS
@receiver(post_save, sender=DataDir)
def save_dir(sender, instance, **kwargs):
if(kwargs["created"] and len(instance.name) > 0):
newNotifiyPush(0, instance, " es gibt neue Ordner: ", "Neuer Ordner: ", "Ordner | ", "", "")
elif(len(instance.name) > 0):
newNotifiyPush(1, instance, " Ordner wurden aktualisiert: ", "Aktualisierter Ordner: ", "Ordner | ", "", "")
@receiver(pre_delete, sender=DataDir)
def del_dir(sender, instance, **kwargs):
newNotifiyPush(2, instance, " ein Ordner wurde gelöscht: ", "Ordner gelöscht: ", "Ordner | ", "", "")
# Signals for FILES
@receiver(post_save, sender=DataFile)
def save_file(sender, instance, **kwargs):
if(kwargs["created"] and len(instance.name) > 0):
newNotifiyPush(0, instance, " es gibt eine neue Datei: ", "Neue Datei: ", "Dateien | ", "", "")
elif(len(instance.name) > 0):
newNotifiyPush(1, instance, " Datei wurde aktualisiert: ", "Aktualisierter Datei: ", "Dateien | ", "", "")
@receiver(pre_delete, sender=DataFile)
def del_file(sender, instance, **kwargs):
newNotifiyPush(2, instance, " eine Datei wurde gelöscht: ", "Datei gelöscht: ", "Dateien | ", "", "")
# QUICKLINKS
@receiver(post_save, sender=QuickLinks)
def save_ql(sender, instance, **kwargs):
if(kwargs["created"] and len(instance.name) > 0):
newNotifiyPush(0, instance, " es gibt einen neuen Quicklink: ", "Neuer Quicklink: ", "Quicklinks | ", "", "")
elif(len(instance.name) > 0):
newNotifiyPush(1, instance, " Quicklink wurde aktualisiert: ", "Aktualisierter Quicklink: ", "Quicklinks | ", "", "")
@receiver(pre_delete, sender=QuickLinks)
def del_ql(sender, instance, **kwargs):
newNotifiyPush(2, instance, " ein Quicklink wurde gelöscht: ", "Quicklink gelöscht: ", "Quicklinks | ", "", "")
# CONTACTS
@receiver(post_save, sender=AGContacts)
def save_contact(sender, instance, **kwargs):
if(kwargs["created"] and len(instance.name) > 0):
newNotifiyPush(0, instance, " es gibt einen neuen Kontakt: ", "Neuer Kontakt: ", "Kontakte | ", "", "")
elif(len(instance.name) > 0):
newNotifiyPush(1, instance, " Kontakt wurde aktualisiert: ", "Aktualisierter Kontakt: ", "Kontakte | ", "", "")
@receiver(pre_delete, sender=AGContacts)
def del_contact(sender, instance, **kwargs):
newNotifiyPush(2, instance, " ein Kontakt wurde gelöscht: ", "Kontakt gelöscht: ", "Kontakte | ", "", "")
# PASSWORDS
@receiver(post_save, sender=AGPassword)
def save_password(sender, instance, **kwargs):
if(kwargs["created"] and len(instance.name) > 0):
newNotifiyPush(0, instance, " es gibt ein neues Passwort: ", "Neues Passwort: ", "Passwörter | ", "", "")
elif(len(instance.name) > 0):
newNotifiyPush(1, instance, " Passwort wurde aktualisiert: ", "Aktualisiertes Passwort: ", "Passwörter | ", "", "")
@receiver(pre_delete, sender=AGPassword)
def del_password(sender, instance, **kwargs):
newNotifiyPush(2, instance, " ein Passwort wurde gelöscht: ", "Passwort gelöscht: ", "Passwörter | ", "", "")
# Join eines Agenturverbunds
@receiver(signal=post_save, sender=AgencyNetworkPreperation)
def save_agjoin_prep(sender, instance, **kwargs):
newnotification = UserNotification(touser=instance.target_network.creator, notificationtext="Eine Agentur möchte Ihrem Verbund beitreten.", notificationtype="wantedag", elementid=instance.pk)
newnotification.save()
# REQUEST MAIN STUFF
@receiver(signal=request_started)
def receiver_function(sender, **kwargs):
# DELETES ALL PRESENCE-OBJECTS LOWER THAN 15 MINUTES
now_minus = datetime.datetime.now() - datetime.timedelta(minutes=2)
Presence.objects.filter(last_seen__lt=now_minus).delete()
users = User.objects.all()
for user in users:
user_notification = []
try:
user_notification = UserNotifications.objects.get(user=user)
except:
if(len(user_notification) == 0):
user_notification = UserNotifications(user=user)
user_notification.save()
# PRESENCE CHANGED
@receiver(signal=presence_changed)
def update_presence_live(sender, **kwargs):
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(str(kwargs["room"]), {'type' : 'update_presence_live'})
'''
ABWESENHEIT BERECHNUNG UND SPEICHERUNG DER NEUEN URLAUBSTAGE - VERWEIS AUF timemenagement.views
'''
@receiver(signal=post_save, sender=Absence)
def save_newabsence(sender, instance, **kwargs):
post_save.disconnect(save_newabsence, sender=sender)
if(instance.reason.is_holiday):
newdata = getFinalHolidayData(instance)
abinfo = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.start.year))[0]
abinfo_lastyear = ""
abinfo_nextyear = ""
is_lastyear = False
abinfo_lastyear = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.start.year-1))
if(len(abinfo_lastyear) > 0):
is_lastyear = True
abinfo_lastyear = abinfo_lastyear[0]
is_nextyear = False
abinfo_nextyear = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.start.year+1))
if(len(abinfo_nextyear) > 0):
is_nextyear = True
abinfo_nextyear = abinfo_nextyear[0]
multiple_info_needays = False
if(hasattr(newdata[3], "__len__")):
multiple_info_needays = True
# Gleiches Jahr MIT Rest
if(multiple_info_needays and newdata[3][2] == False):
# Rest ist positiv, daher bleibt rest übrig, rest wird in absence gespeichert und vom rest des Jahres-Restes abgezogen
# Rest ist positiv, damit bleibt Rest übrig
if(newdata[3][0] > 0):
instance.holidays_rest = abinfo.restdays - newdata[3][0]
instance.save()
abinfo.restdays = newdata[3][0]
abinfo.save()
# Rest ist negativ
elif(newdata[3][0] < 0):
instance.holidays_rest = (abinfo.restdays - newdata[3][0]) - newdata[3][0]*(-1)
instance.holidays_normal = newdata[3][0]*(-1)
instance.save()
abinfo.restdays = 0
abinfo.days_inuse = abinfo.days_inuse + newdata[3][0]*(-1)
abinfo.save()
# Rest ist Urlaubsdauer
else:
instance.holidays_rest = abinfo.restdays
instance.save()
#abinfo.days_inuse = abinfo.days_inuse + abinfo.restdays
abinfo.restdays = 0
abinfo.save()
# Gleiches Jahr ohne Rest
elif(not multiple_info_needays):
abinfo.days_inuse = abinfo.days_inuse + newdata[3]
abinfo.save()
instance.holidays_normal = newdata[3]
instance.save()
# Mehrere Jahre
elif(multiple_info_needays and newdata[3][2] == True):
abinfo.days_inuse = abinfo.days_inuse + newdata[3][0]
abinfo.save()
abinfo_nextyear.days_inuse = abinfo_nextyear.days_inuse + newdata[3][1]
abinfo_nextyear.restdays = abinfo_nextyear.restdays - newdata[3][3]
abinfo_nextyear.save()
# Hier werden alle benötigten Tage von Vor- und Nächstem Jahr gespeichert
instance.holidays_normal = newdata[3][0]
instance.holidays_rest = 0
instance.holidays_normal_next = newdata[3][1]
instance.holidays_rest_next = newdata[3][3]
instance.save()
# NEUE ABWESENHEIT ERSTELLT
if(kwargs["created"]):
usersofagency = User.objects.filter(profile__agency=instance.user.profile.agency)
for user in usersofagency:
# Benutzer erhält Benachrichtigung bei Abwesenheit, wenn er Rechte hat
if(user.has_perm("users.absencemanager")):
if(user.usernotifications.absence_created_mail):
sendMailNoti(" es wurde eine neue Abwesenheit für den Mitarbeiter " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!", user)
if(user.usernotifications.absence_created_push):
newnotification = UserNotification(touser=user, notificationtext="Neue Abwesenheit!", notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Neue Abwesenheit für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"})
# Benutzer ist Vertreter
if(user == instance.representator):
if(user.usernotifications.absence_user_is_rep_mail):
sendMailNoti(" Sie wurden als Vertreter bei einer Abwesenheit von " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!", user)
if(user.usernotifications.absence_user_is_rep_push):
newnotification = UserNotification(touser=user, notificationtext="Neue Abwesenheitsvertretung!", notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Sie wurden als Vertreter für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"})
# ABWESENHEIT GEÄNDERT
else:
usersofagency = User.objects.filter(profile__agency=instance.user.profile.agency)
for user in usersofagency:
# Benutzer erhält Benachrichtigung bei Abwesenheit, wenn er Rechte hat
if(user.has_perm("users.absencemanager")):
if(user.usernotifications.time_data_changed_mail):
sendMailNoti(" es wurde eine Abwesenheit für den Mitarbeiter " + instance.user.first_name + " " + instance.user.last_name + " aktualisiert!", user)
if(user.usernotifications.time_data_changed_push):
newnotification = UserNotification(touser=user, notificationtext="Aktualisierte Abwesenheit!", notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Abwesenheit für " + instance.user.first_name + " " + instance.user.last_name + " wurde aktualisiert!"})
# Benutzer ist Vertreter
if(user == instance.representator):
if(user.usernotifications.absence_user_is_rep_mail):
sendMailNoti(" Sie wurden als Vertreter bei einer Abwesenheit von " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!", user)
if(user.usernotifications.absence_user_is_rep_push):
newnotification = UserNotification(touser=user, notificationtext="Neue Abwesenheitsvertretung!", notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Sie wurden als Vertreter für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"})
else:
print("Absence-Object is no holiday...")
post_save.connect(save_newabsence, sender=sender)
# Neue Chatnachricht wurde verschickt - Hier Reaktion NUR auf PUSH!
@receiver(signal=post_save, sender=ChatMessage)
def new_chat_message(sender, instance, **kwargs):
# GRUPPENCHAT
if instance.room.chatroomtype == 1:
sended_users = []
for u in instance.room.chatmembers.all():
if u != instance.author:
if u.usernotifications.chat_received_push and u not in sended_users:
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(u.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Chat | Neue Nachricht im Gruppenchat " + instance.room.roomname + " von " + instance.author.first_name + " " + instance.author.last_name + ": " + instance.content})
sended_users.append(u)
for u in instance.room.chatmembers_admin.all():
if u != instance.author:
if u.usernotifications.chat_received_push and u not in sended_users:
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(u.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Chat | Neue Nachricht im Gruppenchat " + instance.room.roomname + " von " + instance.author.first_name + " " + instance.author.last_name + ": " + instance.content})
sended_users.append(u)
elif instance.room.chatroomtype == 0:
u = instance.room.chatmember_single
if u.usernotifications.chat_received_push and u != instance.author:
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(u.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Chat | Neue Nachricht von " + instance.author.first_name + " " + instance.author.last_name + ": " + instance.content})
@receiver(signal=pre_delete, sender=Absence)
def delete_absence(sender, instance, **kwargs):
if(instance.reason.is_holiday):
newdata = getFinalHolidayData(instance)
abinfo = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.start.year))[0]
abinfo_lastyear = ""
abinfo_nextyear = ""
is_lastyear = False
abinfo_lastyear = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.start.year-1))
if(len(abinfo_lastyear) > 0):
is_lastyear = True
abinfo_lastyear = abinfo_lastyear[0]
is_nextyear = False
abinfo_nextyear = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.start.year+1))
if(len(abinfo_nextyear) > 0):
is_nextyear = True
abinfo_nextyear = abinfo_nextyear[0]
multiple_info_needays = False
if(hasattr(newdata[3], "__len__")):
multiple_info_needays = True
# Mehrere Jahre oder nicht
if(instance.start.year != instance.end.year):
abinfo.days_inuse = abinfo.days_inuse - instance.holidays_normal
abinfo.save()
abinfo_nextyear.days_inuse = abinfo_nextyear.days_inuse - instance.holidays_normal_next
abinfo_nextyear.restdays = abinfo_nextyear.restdays + instance.holidays_rest_next
abinfo_nextyear.save()
else:
# Gleiches Jahr MIT Rest
abinfo.days_inuse = abinfo.days_inuse - instance.holidays_normal
abinfo.restdays = abinfo.restdays + instance.holidays_rest
abinfo.save()
else:
print("Absence-Object is no holiday...")
def getFinalHolidayData(abscence):
user = abscence.user
usertimedata = UserTime.objects.get(user=user)
today = date.today()
start_day_obj = abscence.start
end_day_obj = abscence.end
try:
holidayloose_date = datetime.date(start_day_obj.year, int(usertimedata.loose_holidedate.split(".")[1]), int(usertimedata.loose_holidedate.split(".")[0]))
except:
holidayloose_date = datetime.date(2020, int(usertimedata.loose_holidedate.split(".")[1]), int(usertimedata.loose_holidedate.split(".")[0]))
#start_half = abscence.start_ishalf
#end_half = abscence.end_ishalf
start_half = False
if abscence.startday_info == "1" or abscence.startday_info == "2":
start_half = True
end_half = False
if abscence.endday_info == "1" or abscence.endday_info == "2":
end_half = True
choosenyear = abscence.start.year
yeardata = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency, year=choosenyear))[0]
holiday_thisyear = 0
holiday_lastyear = yeardata.restdays
holiday_nextyear = 0
try:
holiday_nextyear = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency,
year=choosenyear+1))[0].days - list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency,
year=choosenyear+1))[0].days_inuse
holiday_nextyear_rest = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency,
year=choosenyear+1))[0].restdays
except:
holiday_nextyear = yeardata.days
# Urlaub innerhalb eines Jahres inkl. Prüfung auf Resturlaubsanspruch
if(end_day_obj.year == start_day_obj.year):
# Startt des Urlaubs NACH Verfallsdatum - nur aktuelles JAhr und die Zahl interessiert
if(start_day_obj > holidayloose_date):
need_days = (calculateHolidays(user, start_day_obj, end_day_obj, start_half, end_half))*(-1)
holiday_thisyear = yeardata.days - yeardata.days_inuse - need_days
else:
need_days = (calculateHolidays(user, start_day_obj, end_day_obj, start_half, end_half))*(-1)
# Kein Resturlaub
if(yeardata.restdays == 0.0):
holiday_thisyear = yeardata.days - yeardata.days_inuse - need_days
# Resturlaub vorhanden, berechne mit Resturlaub
else:
holiday_lastyear = yeardata.restdays
holiday_thisyear = yeardata.days - yeardata.days_inuse
temp_holiday = holiday_lastyear - need_days
if(temp_holiday < 0):
holiday_lastyear = 0
holiday_thisyear = yeardata.days - yeardata.days_inuse + temp_holiday
need_days = [temp_holiday, holiday_thisyear, False]
else:
holiday_lastyear = yeardata.restdays - need_days
need_days = [temp_holiday, holiday_lastyear, False]
# Urlaub geht über das nächstes Jahr hinweg
else:
two_years = True
holiday_lastyear = yeardata.restdays
date_splitter = datetime.date(end_day_obj.year, 1, 1)
need_days_this = (calculateHolidays(user, start_day_obj, date_splitter, start_half, False))*(-1)
need_days_next = (calculateHolidays(user, date_splitter, end_day_obj, False, end_half))*(-1)
need_days = (calculateHolidays(user, start_day_obj, date_splitter, start_half, False))*(-1) + (calculateHolidays(user, date_splitter, end_day_obj, False, end_half))*(-1)
holiday_thisyear = yeardata.days - yeardata.days_inuse - need_days_this
days_nextyear_normal = 0
days_nextyear_rest = 0
# Urlaub nächstes Jahr MIT und OHNE Rest
if(holiday_nextyear_rest == 0.0):
holiday_nextyear = holiday_nextyear - (calculateHolidays(user, date_splitter, end_day_obj, False, end_half))*(-1)
else:
temprest = holiday_nextyear_rest - need_days_next
# Rest reicht!
if(temprest >= 0):
holiday_nextyear_rest = temprest
days_nextyear_normal = 0
days_nextyear_rest = need_days_next
# Rest reicht nicht
else:
holiday_nextyear_rest = 0
holiday_nextyear += temprest
days_nextyear_rest = need_days_next + temprest
days_nextyear_normal = temprest * -1
# TAGE NORMAL, TAGE NEXT NORMAL, TRUE für 2jahre, TAGE NEXT REST
need_days = [need_days_this, days_nextyear_normal, True, days_nextyear_rest]
data = [ holiday_thisyear, holiday_lastyear, holiday_nextyear, need_days ]
return data
def calculateHolidays(user, start, end, start_half, end_half):
restdays = 0
allfreedays = FreeDays.objects.filter(agency=user.profile.agency)
if(end == start):
if(start_half):
return restdays - 0.5
else:
return restdays - 1
else:
if(end < start):
return False
else:
counter = 0
if(start_half):
counter -= 0.5
if(end_half):
counter -= 0.5
weekdays = []
freedaycounter = 0
for dt in daterange(start, end):
if dt.isoweekday() not in weekdays:
counter += 1
for freeday in allfreedays.all():
if(dt == freeday.day):
freedaycounter += 1
if(dt.isoweekday() == 1):
if user.usertime.wd_mo == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 2):
if user.usertime.wd_tu == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 3):
if user.usertime.wd_we == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 4):
if user.usertime.wd_th == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 5):
if user.usertime.wd_fr == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 6):
if user.usertime.wd_sa == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 7):
if user.usertime.wd_so == 0.0:
freedaycounter += 1
return restdays - counter + freedaycounter
# Gibt die Woche als Wochentage zurück
def daterange(date1, date2):
for n in range(int ((date2 - date1).days)+1):
yield date1 + timedelta(n)