digitaleagenturnc/users/models.py

543 lines
19 KiB
Python

from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from PIL import Image
from django.utils import timezone
# MAKE EMAIL UNIQUE
from django.contrib.auth.models import User, Group, Permission
from django.contrib.contenttypes.models import ContentType
import datetime
from simple_history.models import HistoricalRecords
# UNIQUE and NO BLANK fields while user-registration
User._meta.get_field('email')._unique = True
User._meta.get_field('email').blank = False
User._meta.get_field('first_name').blank = False
User._meta.get_field('last_name').blank = False
# PATH FOR AGENCYPIC
def picturepath_agency(instance, filename):
# file will be uploaded to MEDIA_URL/agency_<id>/<subdirs>/<filename>
return 'agencydata/agency_{0}/agencystats/{1}'.format(instance.pk, filename)
# PATH FOR PROFILEPICS
def picturepath_user(instance, filename):
return 'agencydata/agency_{0}/agencystats/profilepics/{1}'.format(instance.agency.pk, filename)
'''
Class AgencyNetworkPreperation
Regelt den Join-Prozess einer Agentur in einen Verbund, um Anfrage und Status der Anfrage zu prüfen.
Kommt nur zum tragen, wenn ein AgenturVerbund auf publicjoin=False ist!
'''
class AgencyNetworkPreperation(models.Model):
target_network = models.ForeignKey("AgencyNetwork", on_delete=models.CASCADE)
wanted_agency = models.ForeignKey("Agency", on_delete=models.CASCADE, blank=True)
status = models.IntegerField()
'''
Class AgencyNetwork
Bildet einen Agenturverbund ab
'''
class AgencyNetwork(models.Model):
name = models.CharField(default="", max_length=200)
adminagencys = models.ManyToManyField("Agency", related_name="AdministrationAgencys")
creator = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
creator_agency = models.ForeignKey("Agency", on_delete=models.SET_NULL, blank=True, null=True)
created_on = models.DateTimeField(default=timezone.now)
lastactivity = models.DateTimeField(default=timezone.now)
members = models.ManyToManyField("Agency", related_name="MemberAgencys", blank=True)
sharemembers = models.ManyToManyField("Agency", related_name="ShareMemberAgencys", blank=True)
publicjoin = models.BooleanField(default=False)
networkid = models.CharField(default="", max_length=30)
standards = models.ManyToManyField("standards.Standards", related_name="sharedstandards", blank=True)
def __str__(self):
return f'{self.name}'
'''
Class Agency
Speichert alle Infos für die Agency, darunter später auch die Aufgaben und Bereiche
Bezug normale User: Erhalten bei Erstellung durch den Administrator automatisch die aktuelle agency:
request.user.profile.agency
--> Dahinter ist das Agency-Objekt!
'''
class Agency(models.Model):
name = models.CharField(default="", max_length=200)
inhaber = models.CharField(default="", max_length=200, blank=True)
street = models.CharField(default="", max_length=200, blank=True)
city = models.CharField(default="", max_length=200, blank=True)
plz = models.CharField(default="", max_length=5, blank=True)
agency_email = models.EmailField(default="", blank=True)
phone = models.CharField(default="", max_length=50, blank=True)
agencypic = models.ImageField(default='ag_default.jpg', upload_to=picturepath_agency, blank=True)
agencycalurl = models.CharField(default="", blank=True, max_length=1000)
agencycalurl_all = models.CharField(default="", blank=True, max_length=1000)
# Gibt an, welche Schnittstellen für Kalenderlinks offen sind
# 0 = Nur Kalenderdaten per Authenzifizierung
# 1 = Kalenderdaten per Authentifizierung UND OHNE (für Google-Kalender)
agencycal_publicstatus = models.IntegerField(default=0)
# MONEY
#balance = models.FloatField(default=0.0, max_length=9, blank=True)
#nextdebiting = models.DateTimeField(default=timezone.now, blank=True)
#monthlyprice = models.FloatField(default=25.0, max_length=9, blank=True)
# Payment-Status
# 0 = Normal, Agentur muss ganz normal bezahlen
# 1 = Agentur ist kostenlos dabei!
paymentstatus = models.IntegerField(default=0, null=True)
# ID für die Verbindung mit Lexoffice
lexofficeid = models.CharField(default="", max_length=200, blank=True)
# Bezahlplan 1,3,6,12 Monate
#0 = Kein Bezahkplan ausgewählt
paymentplan = models.IntegerField(default=0, null=True, blank=True)
# Registrierdatum der Agentur
registerdate = models.DateField(default=timezone.now, null=True)
payment_address = models.EmailField(default=None, blank=True, null=True)
#
agb = models.BooleanField(default=False)
contract = models.BooleanField(default=False)
# MODULEEINSTELLUNGEN FÜR DIE AGENTUR
module_news = models.BooleanField(default=True)
module_organizer = models.BooleanField(default=True)
module_files = models.BooleanField(default=True)
module_organigramm = models.BooleanField(default=True)
# Steckbrief dynamisch aus Standard
dynamicprofile = models.BooleanField(default=True)
module_messages = models.BooleanField(default=True)
# TASK: Modul Chat standardmäßig deaktiviert
module_chat = models.BooleanField(default=False)
# KOSTENPFLICHTIGE MODULE
# Abwesenheits- und Zeiterfassung
# Modul aktiv/deaktiviert
module_timemanagement = models.BooleanField(default=True)
module_timemanagement_price = models.FloatField(default=10.0, max_length=9, blank=True)
# Zeiterfassung Ja/Nein
#module_timemanagement_ze = models.BooleanField(default=False)
vve = models.CharField(default="", max_length=200, blank=True)
# RECOVERDIR
module_recoverdir = models.BooleanField(default=False)
def __str__(self):
return f'{self.name}'
# Hier wird definiert, welche Parameter in der URL übertragen werden inkl. Bezeichner
#def get_absolute_url(self):
# return reverse('agency-update', kwargs={'pk':self.pk})
@property
def get_photo_url(self):
if self.agencypic and hasattr(self.agencypic, 'url'):
return self.agencypic.url
else:
return settings.MEDIA_URL + "ag_default.jpg"
# Speichern der Rechnungs-ID von LexOffice
class AgencyBills(models.Model):
lexid = models.CharField(max_length=200, default="", null=True, blank=True)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
billtype = models.CharField(default="", max_length=200)
billdate = models.DateField(default=timezone.now)
billnumber = models.CharField(default="", max_length=200)
billstatus = models.CharField(default="", max_length=200, null=True, blank=True)
start = models.DateField(default=timezone.now)
end = models.DateField(default=timezone.now)
plan = models.CharField(default="", max_length=20)
usercount = models.IntegerField(default=0)
def __str__(self):
return f'{self.lexid}'
'''
Class AgencyJob
'''
class AgencyJob(models.Model):
name = models.CharField(default="", max_length=80)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
def __str__(self):
return f'{self.name}'
'''
Class Profile
Klasse für die Zusatzinfos eines Nutzers.
- Vorname
- Nachname
- Email
- Bild
- Telefonnummer
- Fest
- Mobil
- Funktion
- Auswahlfelder
- Außendienst/Innendienst/Azubi
- Rollen
- Bereiche
- Aufgaben
'''
class Profile(models.Model):
# Wenn der User gelöscht wird, wird auch das Profil gelöscht
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True, default=None)
parent = models.ForeignKey(User, on_delete=models.PROTECT, blank=True, null=True, related_name='parent_user')
phoneland = models.CharField(max_length=60, blank=True)
phonemobile = models.CharField(max_length=60, blank=True)
phone_public = models.BooleanField(default=False)
# Wenn die Funktion gelöscht wird, wird die FUNC auf NULL gesetzt
func = models.ForeignKey("AgencyJob", blank=True, null=True, default=None, on_delete=models.SET_NULL)
# Wenn dieses Profil gelöscht wird, wird NICHT die Agency geslöscht
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to=picturepath_user, blank=True)
compfunc = models.CharField(max_length=60, blank=True)
visible = models.BooleanField(default=True)
persnumber = models.CharField(default="", max_length=50, blank=True)
# TOOLTIPPS
showtooltips = models.BooleanField(default=True)
# NOTIFICATIONS
#NEWS
# Mitteilung bei neuen News innerhalb der Agentur
news_mail = models.BooleanField(default=True)
news_push = models.BooleanField(default=True)
#STANDARDS
# Benutzerstandard wurde veröffentlicht
user_standard_public_mail = models.BooleanField(default=False)
user_standard_public_push = models.BooleanField(default=True)
#STANDARDS
# Neue Standards
agency_new_standard_mail = models.BooleanField(default=False)
agency_new_standard_push = models.BooleanField(default=True)
# GROUPS
# Neuer Gruppe zugeordnet
add_new_group_mail = models.BooleanField(default=False)
add_new_group_push = models.BooleanField(default=True)
# TASKS
# Einer neuen Tätigkeit zugewiesen
add_task_mail = models.BooleanField(default=False)
add_task_push = models.BooleanField(default=True)
# MESSAGES
# Mitteilungen
user_messages_mail = models.BooleanField(default=True)
user_messages_push = models.BooleanField(default=True)
# ONLINESTATUS
'''
0 = ONLINE - green
1 = BESCHAFTIGT - red
2 = ABWESEND - orange
3 = OFFLINE - grey
'''
onlinestatus = models.IntegerField(default=0)
# RECOVER DIR LAST LOGIN FIELD - AFTER LOGIN SET TO NONE
rd_login = models.DateTimeField(null=True, blank=True, default=None)
def __str__(self):
if(self.user != None):
return f'{self.user.last_name}'
else:
return f'Nicht vergeben'
# Hier Path für Templates des Models mit Parametern
def get_absolute_url(self):
return reverse('users-update', kwargs={'pk':self.pk})
# Erst Oberklasse speichern, dann Bild verkleinern
'''
def save(self, **kwargs):
super().save()
if self.image:
img = Image.open(self.image.path)
# Bildspeichergröße
if(img.height > 300 or img.width > 300):
output_size = (300,300)
img.thumbnail(output_size)
img.save(self.image.path)
baseheight = 560
hpercent = (baseheight / float(img.size[1]))
wsize = int((float(img.size[0]) * float(hpercent)))
img = img.resize((wsize, baseheight), Image.ANTIALIAS)
img.save(self.image.path)
'''
@property
def get_photo_url(self):
if self.image and hasattr(self.image, 'url'):
return self.image.url
else:
return settings.MEDIA_URL + "default.jpg"
class UserTime(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True, default=None)
# TIME ELEMENTS
wd_mo = models.FloatField(default=0.0)
wd_tu = models.FloatField(default=0.0)
wd_we = models.FloatField(default=0.0)
wd_th = models.FloatField(default=0.0)
wd_fr = models.FloatField(default=0.0)
wd_sa = models.FloatField(default=0.0)
wd_so = models.FloatField(default=0.0)
loose_holidedate = models.CharField(default="31.03.", max_length=6)
startdate = models.DateField(default=None, blank=True, null=True)
startcount = models.FloatField(default=0.0)
usetime = models.BooleanField(default=False)
usetime_start = models.DateField(default=None, blank=True, null=True)
'''
UserNotifications
Beherbergt alle Benachrichtigungseinstellungen für die User. Ehemals direkt im
User-Model gepflegt, aber da es zu viele sind hierher umgezogen
'''
class UserNotifications(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True, default=None)
# NOTIFICATIONS
# STANDARDS
standard_created_mail = models.BooleanField(default=False)
standard_created_push = models.BooleanField(default=True)
standard_update_mail = models.BooleanField(default=False)
standard_update_push = models.BooleanField(default=True)
standard_delete_mail = models.BooleanField(default=False)
standard_delete_push = models.BooleanField(default=True)
# Wenn neue Standards erstellt wurden, erhalten alle User mit entsprechenden Recht eine Info, dass neue, unveröffentlichte Standards vorhanden sind
standard_created_unpub_mail = models.BooleanField(default=False)
standard_created_unpub_push = models.BooleanField(default=True)
# NEWS
news_created_mail = models.BooleanField(default=True)
news_created_push = models.BooleanField(default=True)
# FILES
filedir_created_mail = models.BooleanField(default=False)
filedir_created_push = models.BooleanField(default=True)
filedir_update_mail = models.BooleanField(default=False)
filedir_update_push = models.BooleanField(default=True)
filedir_delete_mail = models.BooleanField(default=False)
filedir_delete_push = models.BooleanField(default=True)
# Quicklinks
ql_created_mail = models.BooleanField(default=False)
ql_created_push = models.BooleanField(default=True)
ql_update_mail = models.BooleanField(default=False)
ql_update_push = models.BooleanField(default=True)
ql_delete_mail = models.BooleanField(default=False)
ql_delete_push = models.BooleanField(default=True)
# Contacts
contact_created_mail = models.BooleanField(default=False)
contact_created_push = models.BooleanField(default=True)
contact_update_mail = models.BooleanField(default=False)
contact_update_push = models.BooleanField(default=True)
contact_delete_mail = models.BooleanField(default=False)
contact_delete_push = models.BooleanField(default=True)
# Password
password_created_mail = models.BooleanField(default=False)
password_created_push = models.BooleanField(default=True)
password_update_mail = models.BooleanField(default=False)
password_update_push = models.BooleanField(default=True)
password_delete_mail = models.BooleanField(default=False)
password_delete_push = models.BooleanField(default=True)
# MESSAGES
message_received_mail = models.BooleanField(default=False)
message_received_push = models.BooleanField(default=True)
# TASKS
task_activity_mail = models.BooleanField(default=False)
task_activity_push = models.BooleanField(default=True)
# CHAT
# Diese Einstellung sorgt dafür, dass User eine Mail/Push erhalten, wenn neue Chatnachrichten vorhanden sind.
chat_received_mail = models.BooleanField(default=False)
chat_received_push = models.BooleanField(default=True)
# Benachrichtigunge, wenn es Raumaktivitäten gab
chat_room_activity_mail = models.BooleanField(default=False)
chat_room_activity_push = models.BooleanField(default=True)
# TIMEMANAGEMENT
# Wenn neue Abwesenheitsanfragen kommen, Rechte werden gecheckt und dann wird gesendet
absence_created_mail = models.BooleanField(default=True)
absence_created_push = models.BooleanField(default=True)
# Info, ob ein Nutzer als Vertreter eingesetzt worden ist.
absence_user_is_rep_mail = models.BooleanField(default=True)
absence_user_is_rep_push = models.BooleanField(default=True)
# Info, ob ein Nutzer als Vertreter eingesetzt worden ist REMINDER CronJob zwei Tage vorher
absence_user_is_rep_reminder_mail = models.BooleanField(default=True)
absence_user_is_rep_reminder_push = models.BooleanField(default=True)
# Info an den User, wenn seine Zeitdaten verändert wurden
time_data_changed_mail = models.BooleanField(default=True)
time_data_changed_push = models.BooleanField(default=True)
# GRUPPEN
group_activity_mail = models.BooleanField(default=False)
group_activity_push = models.BooleanField(default=True)
group_rights_mail = models.BooleanField(default=False)
group_rights_push = models.BooleanField(default=True)
# AGENCYNETWORK
# Neuer Standard im Verbund
agn_standard_created_mail = models.BooleanField(default=False)
agn_standard_created_push = models.BooleanField(default=True)
# Neuer Agenturstandard wurde von anderer Agentur übernommen
agn_standard_copied_mail = models.BooleanField(default=False)
agn_standard_copied_push = models.BooleanField(default=True)
# Neuer Kommentar zu einem Standard aus meinem Verbund
agn_standard_comment_mail = models.BooleanField(default=False)
agn_standard_comment_push = models.BooleanField(default=True)
# Reaktion auf einen Kommentar von mir
agn_standard_comment_react_mail = models.BooleanField(default=False)
agn_standard_comment_react_push = models.BooleanField(default=True)
# Änderungen eigener Mitgliedsanfragen in anderen Verbünden
agn_own_change_mail = models.BooleanField(default=False)
agn_own_change_push = models.BooleanField(default=True)
# Änderungen anderer Mitgliedschaften (Beitrittsanfragen!)
agn_other_change_mail = models.BooleanField(default=False)
agn_other_change_push = models.BooleanField(default=True)
class UserYearAbsenceInfo(models.Model):
agency = models.ForeignKey(Agency, on_delete=models.CASCADE, default=None)
user = models.ForeignKey(User, on_delete=models.CASCADE)
year = models.IntegerField()
days_inuse = models.FloatField(default=0.0)
days = models.FloatField(default=0.0)
restdays = models.FloatField(default=0.0)
'''
CLASS AgencyGroup
Hier werden die Gruppen mit der Agency verbunden
'''
class AgencyGroup(models.Model):
group = models.OneToOneField(Group, on_delete=models.CASCADE)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
agencygroupname = models.CharField(max_length=60, blank=True)
savefordel = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
class Meta:
permissions = [
('agencyinfo', 'Agenturinformationen verändern'),
('agencynetwork', 'Agenturverbund bearbeiten'),
('usermanager', 'Mitarbeiter bearbeiten'),
('groupmanager', 'Gruppen bearbeiten'),
('structuremanager', 'Struktur bearbeiten'),
('standardmanager', 'Standards bearbeiten'),
('standardgopublic', 'Standards freischalten'),
('modulenews', 'News bearbeiten und veröffentlichen'),
('modulesconfig', 'Module verwalten'),
('moduleorganizer', 'Organizer bearbeiten'),
('filesmanager', 'Dateien bearbeiten'),
('filedirmanager', 'Ordner bearbeiten'),
('filesviewer', 'Dateien lesen'),
('absencemanager', 'Abwesenheiten verwalten'),
('timemanager', 'Zeiterfassung verwalten'),
('recoverdirmanager', 'Notfallhilfe verwalten')
]
class RegNotfallhilfe(models.Model):
mail = models.CharField(max_length=500, blank=True)
name = models.CharField(max_length=500, blank=True)
persnumber = models.CharField(max_length=500, blank=True)
mitgliedsnummer = models.CharField(max_length=500, blank=True)
plz = models.CharField(max_length=500, blank=True)
stadt = models.CharField(max_length=500, blank=True)
street = models.CharField(max_length=500, blank=True)
data_to_vh = models.BooleanField(default=True)
rabatt = models.BooleanField(default=False)
wassend = models.BooleanField(default=False)
orderdate = models.DateField(default=timezone.now, null=True)
# SUBCLASS
class UserFullName(User):
history = HistoricalRecords()
class Meta:
proxy = True
def __unicode__(self):
return "placeholder"
def __str__(self):
return f'{self.first_name + " " + self.last_name}'
# Hier Audit-Logeinträge einbauen für die versch. Models
#from django.utils.six import python_2_unicode_compatible
#from auditlog.registry import auditlog
#auditlog.register(User)
#auditlog.register(Agency)