2021-01-06 09:59:47 +00:00
from smtplib import SMTPException
2021-01-14 14:10:29 +00:00
import collections
2021-01-06 09:59:47 +00:00
2020-12-23 14:08:27 +00:00
from django . views . generic . edit import CreateView
2021-01-05 13:10:28 +00:00
from django . urls import reverse
2021-01-14 08:37:45 +00:00
from django . http import HttpResponse , HttpResponseRedirect
2021-01-06 09:59:47 +00:00
from django . core . mail import send_mail , BadHeaderError
from django . template . loader import get_template
2021-01-12 09:57:21 +00:00
from formtools . wizard . views import CookieWizardView
from django . shortcuts import render
2021-02-09 09:48:07 +00:00
from django . conf import settings
2021-03-11 13:49:29 +00:00
from django . contrib . auth . mixins import LoginRequiredMixin
2020-12-23 14:08:27 +00:00
2021-05-04 13:35:27 +00:00
from . models import Employee , DEPARTMENT_CHOICES , OS_CHOICES , VENDOR_CHOICES , \
2021-05-04 10:45:41 +00:00
LANG_CHOICES , ACCOUNT_CHOICES , TRANSPONDER_CHOICES , KEYBOARD_CHOICES
2021-02-02 09:30:00 +00:00
from . forms import PersonalForm , WorkingForm , ITForm , OfficeForm , DummyForm , \
2021-11-10 13:29:42 +00:00
ChangeForm , TYPE_CHOICES , OffboardingForm
2021-03-02 09:54:35 +00:00
from . settings import MAILS , EVA_MAIL , BASIC_DATA , ONLY_ONBOARDING
2020-12-23 10:42:57 +00:00
2021-01-05 13:10:28 +00:00
def success ( request ) :
2021-05-17 10:41:46 +00:00
return HttpResponse ( f " Vielen Dank! Du hast E.V.A. erfolgreich ausgefüllt. Die Mails an die Abteilungen wurden versendet. Kopien gehen an { request . user . email } . " )
2021-01-05 13:10:28 +00:00
2021-02-03 09:53:02 +00:00
def long_process ( wizard ) :
2021-02-04 11:30:46 +00:00
''' this method is called via urls.py to determine if a form is part of the IN-Process '''
2021-03-02 09:54:35 +00:00
if ONLY_ONBOARDING :
2021-02-03 13:42:55 +00:00
wizard . set_choice ( ' IN ' )
2021-02-03 09:53:02 +00:00
return True
else :
2021-03-02 09:54:35 +00:00
data = wizard . get_cleaned_data_for_step ( ' 0 ' ) or { }
2021-11-10 14:48:12 +00:00
# print(data)
if data . get ( ' choice ' ) == ' IN ' :
2021-03-02 09:54:35 +00:00
wizard . set_choice ( ' IN ' )
2021-11-10 14:48:12 +00:00
print ( ' PROZESS IN ' )
2021-03-02 09:54:35 +00:00
return True
else :
return False
2021-11-10 14:48:12 +00:00
#wizard.set_choice('CHANGE')
#print('PROZESS CHANGE')
#return False
2021-02-03 13:42:55 +00:00
2021-11-10 13:29:42 +00:00
def offboarding_process ( wizard ) :
''' this method is called via urls.py to determine if the form is part of the change process '''
print ( ' OFFBOARDING PROZESS ' )
2021-11-10 14:48:12 +00:00
if not ONLY_ONBOARDING :
data = wizard . get_cleaned_data_for_step ( ' 0 ' ) or { }
print ( data )
if data . get ( ' choice ' ) == ' OUT ' :
#print("PPPPPPPPPPPPPPP")
wizard . set_choice ( ' OUT ' )
return True
# wizard.set_choice('IN')
return False
2021-11-10 13:29:42 +00:00
2021-02-03 13:42:55 +00:00
def change_process ( wizard ) :
2021-02-04 11:30:46 +00:00
''' this method is called via urls.py to determine if the form is part of the change process '''
2021-02-03 13:42:55 +00:00
print ( ' CHANGE PROZESS ' )
return not long_process ( wizard )
2021-02-03 09:53:02 +00:00
2021-01-06 09:20:06 +00:00
2021-03-11 13:49:29 +00:00
class EvaFormView ( LoginRequiredMixin , CookieWizardView ) :
2021-01-12 09:57:21 +00:00
template_name = ' evapp/employee_form.html '
2021-11-10 13:29:42 +00:00
form_list = [ PersonalForm , WorkingForm , ITForm , OfficeForm , OffboardingForm , DummyForm ]
2021-01-13 08:51:13 +00:00
instance = None
2021-02-02 10:31:40 +00:00
choice = ' IN '
2021-02-03 13:42:55 +00:00
# maybe we dont need this, if *_process() would be class methods,
# but unsure if this would work fine with the entries in urls.py
def set_choice ( self , c ) :
self . choice = c
2021-05-04 09:54:27 +00:00
def generate_email ( self , data ) :
2021-05-04 10:45:41 +00:00
( first , * _ ) = data [ ' firstname ' ] . split ( maxsplit = 1 )
( last , * _ ) = data [ ' lastname ' ] . split ( maxsplit = 1 )
2021-05-04 09:54:27 +00:00
name = first + ' . ' + last
2021-05-26 13:09:40 +00:00
#if not data['intern']:
# mail = name + '_ext@wikimedia.de'
#else:
mail = name + ' @wikimedia.de '
2021-05-04 09:54:27 +00:00
data [ ' email ' ] = mail
2021-02-04 11:30:46 +00:00
2021-02-02 10:31:40 +00:00
def get_all_cleaned_data ( self ) :
2021-02-08 12:13:44 +00:00
''' this method deletes data which is only used temporary and is not in the modell,
it also changes the mail adress of the employee in some circumstances '''
2021-02-04 11:30:46 +00:00
2021-02-02 10:31:40 +00:00
data = super ( ) . get_all_cleaned_data ( )
2021-05-04 09:54:27 +00:00
self . generate_email ( data )
2021-02-08 12:13:44 +00:00
2021-09-14 09:58:22 +00:00
# print("delete CHOICE FROM DATA")
2021-02-03 13:42:55 +00:00
if ' choice ' in data :
del data [ ' choice ' ]
2021-02-02 10:31:40 +00:00
return data
2021-01-05 13:10:28 +00:00
2021-02-04 11:30:46 +00:00
2021-01-14 11:44:04 +00:00
def get_context_data ( self , form , * * kwargs ) :
2021-02-04 11:30:46 +00:00
''' this method is called to give context data to the template '''
#print('GETCONTEXT')
2021-01-14 11:44:04 +00:00
context = super ( ) . get_context_data ( form = form , * * kwargs )
2021-09-15 11:41:21 +00:00
testmode = settings . DEBUG or settings . MAILTEST
2021-02-08 10:28:32 +00:00
context . update ( { ' choice ' : self . choice ,
2021-09-14 07:58:41 +00:00
' choice_string ' : TYPE_CHOICES [ self . choice ] ,
2021-09-15 11:41:21 +00:00
' TESTMODE ' : testmode } )
2021-02-08 10:28:32 +00:00
2021-03-02 09:54:35 +00:00
# deliver context for forms if we are in the last step
2021-02-04 11:59:23 +00:00
if ( self . steps . step1 == 5 or ( self . choice != ' IN ' and self . steps . step1 == 3 ) ) :
context . update ( { ' data ' : self . beautify_data ( self . get_all_cleaned_data ( ) ) ,
' datatable ' : True , } )
2021-01-14 11:44:04 +00:00
return context
2021-01-13 08:51:13 +00:00
def get_form_instance ( self , step ) :
2021-09-15 11:41:21 +00:00
''' this method assures, that we use the same model instance for all steps '''
2021-02-04 11:30:46 +00:00
2021-01-13 08:51:13 +00:00
if self . instance == None :
self . instance = Employee ( )
return self . instance
2021-02-08 12:13:44 +00:00
2021-01-12 09:57:21 +00:00
def done ( self , form_list , * * kwargs ) :
2021-02-04 11:30:46 +00:00
''' this method is called from CookieWizardView after all forms are filled '''
2021-01-13 08:51:13 +00:00
print ( ' INSTANCE_DICT ' )
print ( self . instance_dict )
2021-01-14 13:20:17 +00:00
2021-01-14 12:15:11 +00:00
# save data to database
2021-01-13 08:51:13 +00:00
for form in form_list :
form . save ( )
2021-01-14 13:20:17 +00:00
2021-01-14 12:15:11 +00:00
# send data to departments
2021-01-06 09:20:06 +00:00
for dep in MAILS :
2021-09-15 11:41:21 +00:00
response = self . send_mail_to_department ( dep )
2021-02-09 09:48:07 +00:00
if not settings . DEBUG :
self . instance . delete ( )
2021-03-02 09:54:35 +00:00
2021-09-15 11:41:21 +00:00
if response :
return response
else :
return HttpResponseRedirect ( ' success ' )
2021-01-06 09:20:06 +00:00
2021-02-04 11:30:46 +00:00
2021-01-14 12:15:11 +00:00
def send_mail_to_department ( self , department ) :
' send a mail to the given department with the nececcary notifications '
print ( f ' send mail to department { department } ... ' )
2021-05-18 07:42:00 +00:00
contact = self . request . user . email
2021-01-14 13:20:17 +00:00
data = self . get_all_cleaned_data ( )
2021-01-20 07:52:22 +00:00
# some data should be in every mail
newdata = { k : v for k , v in data . items ( ) if ( k in BASIC_DATA ) }
# only the relevant data should be in the context
newdata . update ( { k : v for k , v in data . items ( ) if ( k in MAILS [ department ] [ ' DATA ' ] ) } )
2021-01-14 14:10:29 +00:00
2021-05-18 07:42:00 +00:00
context = { ' data ' : self . beautify_data ( newdata ) , ' contact ' : contact }
2021-09-20 11:55:43 +00:00
firstname = data [ ' firstname ' ]
lastname = data [ ' lastname ' ]
2021-01-14 12:15:11 +00:00
try :
2021-01-20 08:18:18 +00:00
mail_template = get_template ( f ' evapp/department_mail.txt ' )
2021-03-25 09:09:27 +00:00
if settings . MAILTEST :
send_mail (
2021-09-20 11:55:43 +00:00
f ' EVA: Neuzugang { firstname } { lastname } (MAILTEST) ' ,
2021-03-25 09:09:27 +00:00
mail_template . render ( context ) ,
EVA_MAIL ,
2021-05-18 07:42:00 +00:00
[ EVA_MAIL , contact ] ,
2021-03-25 09:09:27 +00:00
fail_silently = False )
else :
send_mail (
2021-09-20 11:55:43 +00:00
f ' EVA: Neuzugang { firstname } { lastname } ' ,
2021-01-14 12:15:11 +00:00
mail_template . render ( context ) ,
EVA_MAIL ,
2021-05-18 07:42:00 +00:00
[ MAILS [ department ] [ ' MAIL ' ] , contact ] ,
2021-01-14 12:15:11 +00:00
fail_silently = False )
2021-09-15 11:41:21 +00:00
except BadHeaderError as error :
print ( error )
2021-01-14 13:20:17 +00:00
self . instance . delete ( )
2021-09-15 11:41:21 +00:00
return HttpResponse ( f ' { error } <p>Invalid header found. Data not saved! ' )
except SMTPException as error :
print ( error )
2021-01-14 12:15:11 +00:00
self . instance . delete ( )
2021-09-15 11:41:21 +00:00
return HttpResponse ( f ' { error } <p>Error in sending mails (propably wrong adress?). Data not saved! ' )
except Exception as error :
print ( error )
# self.instance.delete()
return HttpResponse ( f ' { error } <p>Error in sending mails. Data not saved! Please contact ' + EVA_MAIL )
return False
2021-01-14 14:10:29 +00:00
def beautify_data ( self , data ) :
2021-02-04 11:30:46 +00:00
''' # use long form for contextdata instead of short form if available
#
# ATTENTION!
# This implementation works only for unique keys over all of these dicts from model.py
#
'''
2021-01-19 08:08:59 +00:00
# update values in data dictionary with keys from *_CHOICES if present there
2021-05-04 13:35:27 +00:00
choices = { * * DEPARTMENT_CHOICES , * * TRANSPONDER_CHOICES ,
2021-05-04 10:45:41 +00:00
* * OS_CHOICES , * * LANG_CHOICES , * * VENDOR_CHOICES , * * KEYBOARD_CHOICES }
2021-01-18 11:34:45 +00:00
data . update ( { k : choices [ v ] for k , v in data . items ( ) \
2021-01-18 09:41:29 +00:00
if isinstance ( v , collections . abc . Hashable ) \
2021-01-18 11:34:45 +00:00
and v in choices } )
2021-01-18 09:41:29 +00:00
2021-01-19 09:06:29 +00:00
# replace values in accounts array from *_CHOICES
2021-01-19 09:32:31 +00:00
if ' accounts ' in data :
data [ ' accounts ' ] = [ ACCOUNT_CHOICES [ c ] for c in data [ ' accounts ' ] ]
2021-01-19 09:06:29 +00:00
2021-01-19 08:08:59 +00:00
# replace keys in data dictionary with verbose_name
2021-05-05 09:11:34 +00:00
# a bit ugly workaround here: we need to store 'email' away, because it es not in the modell
2021-05-04 10:16:01 +00:00
mail = ' '
if ' email ' in data :
mail = data . pop ( ' email ' )
2021-01-19 08:08:59 +00:00
newdata = { self . instance . _meta . get_field ( k ) . verbose_name . title ( ) : v for k , v in data . items ( ) }
2021-05-04 10:16:01 +00:00
if mail :
2021-05-04 12:51:21 +00:00
newdata [ ' Email ' ] = mail
2021-05-05 09:11:34 +00:00
# translate booleans
2021-05-04 12:51:21 +00:00
newdata . update ( { k : ' Ja ' for k , v in newdata . items ( ) if isinstance ( v , bool ) and v == True } )
newdata . update ( { k : ' Nein ' for k , v in newdata . items ( ) if isinstance ( v , bool ) and v == False } )
2021-05-05 09:11:34 +00:00
# handle some special data types
newdata . update ( { k : ' ' for k , v in newdata . items ( ) if v == None } )
newdata . update ( { k : ' ' for k , v in newdata . items ( ) if v == [ ] } )
2021-05-04 12:51:21 +00:00
2021-01-19 08:08:59 +00:00
return newdata