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.profile.rd_login = None 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.profile.rd_login = None 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 Zwei Jahre 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() # FREEDAYS LADEN DIese Jahr if len(FreeDays.objects.filter(agency=user.profile.agency, year=today.year+1)) == 0: tempdays = loadingFreeDays(user.profile.agency.plz, today.year+1) 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+1).save() # CHECK FOR YEARS # FREEDAYS LADEN LETZTES JAHR if len(FreeDays.objects.filter(agency=user.profile.agency, year=today.year-1)) == 0: tempdays = loadingFreeDays(user.profile.agency.plz, today.year-1) 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-1).save() # FREEDAYS LADEN if len(FreeDays.objects.filter(agency=user.profile.agency, year=today.year)) == 0: tempdays = loadingFreeDays(user.profile.agency.plz, today.year) 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).save() # 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)