From 949603e89678eb098926d53335b7bd19bc66412f Mon Sep 17 00:00:00 2001 From: Md Bayazid Bostame Date: Tue, 8 Oct 2024 18:49:36 +0200 Subject: [PATCH] Final Onboarding processes --- .vscode/settings.json | 3 + email_text/dritich_email.txt | 16 ++ email_text/minuth_email.txt | 16 ++ env/.env | 19 ++ main.py | 276 +++++++++++++++++++++++++++++ templates/onboarding_template.html | 204 +++++++++++++++++++++ templates/templates.pdf | Bin 0 -> 33315 bytes 7 files changed, 534 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 email_text/dritich_email.txt create mode 100644 email_text/minuth_email.txt create mode 100644 env/.env create mode 100644 main.py create mode 100644 templates/onboarding_template.html create mode 100644 templates/templates.pdf diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c6fe762 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "livePreview.defaultPreviewPath": "/templates/onboarding_template.html" +} \ No newline at end of file diff --git a/email_text/dritich_email.txt b/email_text/dritich_email.txt new file mode 100644 index 0000000..e17dc01 --- /dev/null +++ b/email_text/dritich_email.txt @@ -0,0 +1,16 @@ +Subject: HR Works Access Request for New Employee + +Hello Dritich, + +A new employee requires access to the HR system (HR Works) for their onboarding process. + +Please proceed with creating the HR Works account for the following employee: + +Employee Name: {{VORNAME}} {{NACHNAME}} +Department: {{ABTEILUNG}} +Start Date: {{VERTRAGSBEGINN}} + +If you require any additional information, please let us know. + +Best regards, +The Onboarding Team diff --git a/email_text/minuth_email.txt b/email_text/minuth_email.txt new file mode 100644 index 0000000..2e67c5d --- /dev/null +++ b/email_text/minuth_email.txt @@ -0,0 +1,16 @@ +Subject: New Key Request for Onboarding Employee + +Hello Minuth, + +We have a new employee who requires a key (Schlüssel) as part of their onboarding process. + +Please proceed with creating and providing the necessary key for the following employee: + +Employee Name: {{VORNAME}} {{NACHNAME}} +Department: {{ABTEILUNG}} +Start Date: {{VERTRAGSBEGINN}} + +If you have any questions or need further details, feel free to reach out. + +Best regards, +The Onboarding Team diff --git a/env/.env b/env/.env new file mode 100644 index 0000000..c50b5e4 --- /dev/null +++ b/env/.env @@ -0,0 +1,19 @@ +# Email Server Configuration +IMAP_SERVER=mxe839.netcup.net +SMTP_SERVER=mxe839.netcup.net +EMAIL_PORT=465 # Port for SSL/TLS (Port 465) +EMAIL_ACCOUNT=onboarding@bostame.de +PASSWORD= +MAILBOX=INBOX + +# Recipients for notification emails +MINUTH_EMAIL=minuth@bostame.de +DRITICH_EMAIL=dittrich@bostame.de + +# Additional directories or paths +TEMPLATES_DIR=templates +ATTACHMENTS_DIR=attachments +ONBOARDED_DIR=onboarded_person +TEMP_PDF_DIR=temp_pdf +EMAIL_TEXT_DIR=email_text + diff --git a/main.py b/main.py new file mode 100644 index 0000000..bc8e9ed --- /dev/null +++ b/main.py @@ -0,0 +1,276 @@ +import imaplib +import email +import os +import pandas as pd +import pdfkit +from jinja2 import Template +from PyPDF2 import PdfWriter, PdfReader, PageObject +from datetime import datetime +from email.header import decode_header +import time +from pathlib import Path +from dotenv import load_dotenv +import uuid +import smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +import re + +# Load environment variables from .env file +load_dotenv(dotenv_path=Path(__file__).parent / 'env' / '.env') + +# Retrieve secret credentials and directories from environment variables +IMAP_SERVER = os.getenv('IMAP_SERVER') +SMTP_SERVER = os.getenv('SMTP_SERVER') +EMAIL_PORT = int(os.getenv('EMAIL_PORT')) +EMAIL_ACCOUNT = os.getenv('EMAIL_ACCOUNT') +PASSWORD = os.getenv('PASSWORD') +MAILBOX = os.getenv('MAILBOX') + +# Recipients from .env file +MINUTH_EMAIL = os.getenv('MINUTH_EMAIL') +DRITICH_EMAIL = os.getenv('DRITICH_EMAIL') + +# Retrieve directory paths from environment variables +TEMPLATES_DIR = Path(os.getenv('TEMPLATES_DIR')) +ATTACHMENTS_DIR = Path(os.getenv('ATTACHMENTS_DIR')) +ONBOARDED_DIR = Path(os.getenv('ONBOARDED_DIR')) +TEMP_PDF_DIR = Path(os.getenv('TEMP_PDF_DIR')) +EMAIL_TEXT_DIR = Path(os.getenv('EMAIL_TEXT_DIR')) + +# Ensure directories exist +for directory in [ATTACHMENTS_DIR, TEMPLATES_DIR, ONBOARDED_DIR, TEMP_PDF_DIR, EMAIL_TEXT_DIR]: + directory.mkdir(parents=True, exist_ok=True) + +# Configure path to wkhtmltopdf +path_to_wkhtmltopdf = Path(r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe') +config = pdfkit.configuration(wkhtmltopdf=str(path_to_wkhtmltopdf)) +options = { + 'enable-local-file-access': None, + 'page-size': 'A4', + 'margin-top': '50mm', + 'margin-bottom': '20mm', + 'margin-left': '20mm', + 'margin-right': '20mm' +} + +# Function to send an email with dynamic content +def send_email_notification(to_email, subject, template_file, context): + try: + # Load the email content from the text file and render the template + with open(template_file, 'r', encoding='utf-8') as file: + template_content = file.read() + + # Render the email content with the context (employee data) + template = Template(template_content) + rendered_content = template.render(context) + + msg = MIMEMultipart() + msg['From'] = EMAIL_ACCOUNT + msg['To'] = to_email + msg['Subject'] = subject + + # Attach the rendered email body + msg.attach(MIMEText(rendered_content, 'plain')) + + # Send the email via SMTP over SSL + print(f"Attempting to connect to SMTP server {SMTP_SERVER} on port {EMAIL_PORT} using SSL...") + with smtplib.SMTP_SSL(SMTP_SERVER, EMAIL_PORT) as server: + print(f"Connected to SMTP server {SMTP_SERVER}, attempting to login...") + server.login(EMAIL_ACCOUNT, PASSWORD) + print(f"Logged in successfully, sending email to {to_email}...") + server.send_message(msg) + print(f"Email sent to {to_email}") + except Exception as e: + print(f"Failed to send email to {to_email}: {e}") + finally: + # Introduce a small delay between emails to avoid potential throttling issues + time.sleep(5) + +# Helper function to split a list into chunks of a specified size and format it in title case +def chunk_list(data_list, chunk_size=4): + title_case_list = [item.title() for item in data_list] + for i in range(0, len(title_case_list), chunk_size): + yield title_case_list[i:i + chunk_size] + +# Function to generate PDF from HTML +def generate_pdf_from_html(html_content, output_pdf): + try: + pdfkit.from_string(html_content, output_pdf, configuration=config, options=options) + print(f"Generated PDF: {output_pdf}") + except Exception as e: + print(f"Error generating PDF {output_pdf}: {e}") + +# Overlay generated PDF content onto the letterhead +def overlay_content_on_letterhead(content_pdf, letterhead_pdf, output_pdf): + try: + letterhead_reader = PdfReader(letterhead_pdf) + content_reader = PdfReader(content_pdf) + + writer = PdfWriter() + letterhead_page = letterhead_reader.pages[0] + + for page_num in range(len(content_reader.pages)): + content_page = content_reader.pages[page_num] + overlay_page = PageObject.create_blank_page(width=letterhead_page.mediabox.width, height=letterhead_page.mediabox.height) + overlay_page.merge_page(letterhead_page) + overlay_page.merge_page(content_page) + writer.add_page(overlay_page) + + with open(output_pdf, 'wb') as output_file: + writer.write(output_file) + print(f"Final PDF saved to: {output_pdf}") + + except Exception as e: + print(f"Error overlaying content on letterhead: {e}") + +# Function to process CSV and generate PDF with email feature +def process_csv_and_generate_pdf(csv_file): + try: + print(f"Processing CSV file: {csv_file}") + + # Load CSV data + data = pd.read_csv(csv_file) + print(f"CSV Data loaded successfully for {csv_file}") + + # Load the HTML template from the templates directory + with open(TEMPLATES_DIR / 'onboarding_template.html', 'r', encoding='utf-8') as file: + html_template = file.read() + print("HTML template loaded successfully") + + for index, row in data.iterrows(): + try: + print(f"Processing row {index}") + + # Split "Vorname und Nachname" into first and last name + name_parts = row['Vorname und Nachname'].split() + vorname = name_parts[0] + nachname = " ".join(name_parts[1:]) + + # Chunk the multiline fields into formatted lists + arbeitsegeraete_list = list(chunk_list(row.get('Der Mitarbeiter Benötigt Folgende Arbeitsgeräte', '').split('\n'))) + zugaenge_list = list(chunk_list(row.get('Die Folgenden Zugänge und Rollen Sollen Zu Workspace Eingerichtet Werden', '').split('\n'))) + software_list = list(chunk_list(row.get('Darüber Hinaus Benötigt Er Folgende Software', '').split('\n'))) + account_list = list(chunk_list(row.get('Zugänge, Die Standardmäßig Eingerichtet Werden Sollen, Bitte Benennen', '').split('\n'))) + standard_zugaenge_list = row.get('Zugänge, Die Standardmäßig Eingerichtet Werden Sollen, Bitte Benennen', '').split('\n') + printer_list = list(chunk_list(row.get('Ressourcen, Die Standardmäßig Eingerichtet Werden Sollen, Bitte Benennen', '').split('\n'))) + telephone = row.get('TUBS-Telefon-Direktwahl-Nr. 030 447202 (10-89)', None) + + + + # Prepare the context with employee data + context = { + 'VORNAME': vorname, + 'NACHNAME': nachname, + 'BERUFSBEZEICHNUNG': row.get('Berufsbezeichnung', 'N/A'), + 'ABTEILUNG': row.get('Abteilung', 'N/A'), + 'EMAIL': row.get('Gewünschte Dienstliche E-Mail-Adresse', 'N/A'), + 'VERTRAGSBEGINN': row.get('Vertragsbeginn', 'N/A'), + 'UEBERGABEDATUM': row.get('Gewünschtes Übergabedatum der Geräte', 'N/A'), + 'GRUPPENPOSTFAECHER_ERFORDERLICH': row.get('Gruppenpostfächer Erforderlich?', 'N/A'), + 'ZUGAENGE_LIST': zugaenge_list, + 'ARBEITSGERÄTE_LIST': arbeitsegeraete_list, + 'SOFTWARE_LIST': software_list, + 'ACCOUNT_LIST': account_list, # Pass Standard-Zugänge data + 'STANDARD_ZUGAENGE': row.get('Zugänge, Die Standardmäßig Eingerichtet Werden Sollen, Bitte Benennen', ''), + 'SOFTWAREWUNSCH': row.get('Haben Sie Einen Zusätzlichen Softwarewunsch?', ''), + 'STANDARD_RESSOURCEN': printer_list, + 'TELEFONNUMMER': telephone, + 'BEMERKUNGEN': row.get('Haben Wir Irgendetwas Übersehen? Schreiben Sie Uns Hier.', 'nan'), + 'VEREINBARUNG': row.get('Vereinbarung', ''), + 'UNTERSCHRIFT': row.get('Unterschrift', ''), + } + + # Fill the template with data + html_content = Template(html_template).render(context) + + # Generate content PDF and save to temp_pdf directory + content_pdf_path = TEMP_PDF_DIR / f'temp_content_{vorname}_{nachname}.pdf' + print(f"Generating content PDF at: {content_pdf_path}") + generate_pdf_from_html(html_content, str(content_pdf_path)) + + # Define output PDF filename and save to onboarded_person directory + output_pdf_path = ONBOARDED_DIR / f'onboarding_letter_{vorname}_{nachname}.pdf'.replace(" ", "_") + + # Overlay content on letterhead and save final PDF + letterhead_pdf = TEMPLATES_DIR / 'templates.pdf' + print(f"Overlaying content on letterhead: {letterhead_pdf}") + overlay_content_on_letterhead(str(content_pdf_path), letterhead_pdf, output_pdf_path) + + print(f"Final PDF generated and saved at: {output_pdf_path}") + + # Email notifications based on conditions + # Check for "Schlüssel" in ARBEITSGERÄTE_LIST and send email + if any("Schlüssel".lower() in s.lower() for sublist in arbeitsegeraete_list for s in sublist if isinstance(s, str)): + print(f"'Schlüssel' found for {vorname} {nachname}") + send_email_notification(MINUTH_EMAIL, 'Schlüssel Required', EMAIL_TEXT_DIR / 'minuth_email.txt', context) + + # Check for "HR Works" in STANDARD_ZUGAENGE_LIST and send email + if any("HR Works".lower() in s.lower() for s in standard_zugaenge_list if isinstance(s, str)): + print(f"'HR Works' found for {vorname} {nachname}") + send_email_notification(DRITICH_EMAIL, 'HR Works Access Required', EMAIL_TEXT_DIR / 'dritich_email.txt', context) + + except Exception as e: + print(f"Error processing row {index}: {e}") + + except Exception as e: + print(f"Error processing CSV {csv_file}: {e}") + + +# Function to check email for CSV attachments +def check_email_for_csv(): + try: + # Connect to the email server + mail = imaplib.IMAP4_SSL(IMAP_SERVER) + mail.login(EMAIL_ACCOUNT, PASSWORD) + mail.select(MAILBOX) + + # Search for all unread emails + status, messages = mail.search(None, '(UNSEEN)') + email_ids = messages[0].split() + + for e_id in email_ids: + res, msg = mail.fetch(e_id, "(RFC822)") + for response_part in msg: + if isinstance(response_part, tuple): + msg = email.message_from_bytes(response_part[1]) + subject, encoding = decode_header(msg["Subject"])[0] + + if isinstance(subject, bytes): + subject = subject.decode(encoding or "utf-8") + + print(f"Processing email: {subject}") + + # Loop through email parts to find attachments + if msg.is_multipart(): + for part in msg.walk(): + content_disposition = str(part.get("Content-Disposition")) + if "attachment" in content_disposition: + filename = part.get_filename() + + if filename.endswith(".csv"): + # Save the CSV attachment with a unique name + unique_filename = f"{filename.split('.')[0]}_{uuid.uuid4().hex}.csv" + filepath = ATTACHMENTS_DIR / unique_filename + with open(filepath, "wb") as f: + f.write(part.get_payload(decode=True)) + print(f"CSV file saved as {filepath}") + + # Process CSV and generate PDF + process_csv_and_generate_pdf(filepath) + + mail.logout() + except Exception as e: + print(f"Failed to check email: {e}") + +# Countdown timer for 30 seconds before checking again +def countdown_timer(seconds): + for i in range(seconds, 0, -1): + print(f"Waiting {i} seconds...", end="\r") + time.sleep(1) + print("Checking emails now...") + +# Continuously check for new emails every 30 seconds +while True: + check_email_for_csv() + countdown_timer(30) diff --git a/templates/onboarding_template.html b/templates/onboarding_template.html new file mode 100644 index 0000000..931e13a --- /dev/null +++ b/templates/onboarding_template.html @@ -0,0 +1,204 @@ + + + + + + Onboarding Letter + + + +
+

"Willkommen im Team! Wir sind begeistert, Sie auf dieser spannenden Reise an unserer Seite zu haben."

+ + +

Sehr geehrte/r {{VORNAME}} {{NACHNAME}},

+ +

Wir freuen uns riesig, Sie als unsere/n neue/n {{BERUFSBEZEICHNUNG}} in der Abteilung {{ABTEILUNG}} begrüßen zu dürfen. Ihr Arbeitsvertrag beginnt am {{VERTRAGSBEGINN}}. Der Termin für die Übergabe der benötigten Arbeitsmittel ist für den {{UEBERGABEDATUM}} vorgesehen. Ihre dienstliche E-Mail-Adresse lautet: {{EMAIL}}

+ +

Mit Ihnen gemeinsam werden wir großartige Dinge erreichen!

+ +

Ihre Arbeitsgeräte

+ + + + + + + + {% for row in ARBEITSGERÄTE_LIST %} + + {% for cell in row %} + + {% endfor %} + + {% endfor %} + +
Arbeitsgerät
{{ cell }}
+ +

Zugänge und Rollen

+ + + + + + + + {% for row in ZUGAENGE_LIST %} + + {% for cell in row %} + + {% endfor %} + + {% endfor %} + +
Zugang
{{ cell }}
+ +

Benötigte Software

+ + + + + + + + {% for row in SOFTWARE_LIST %} + + {% for cell in row %} + + {% endfor %} + + {% endfor %} + +
Software
{{ cell }}
+ +

Liste der Konten

+ + + + + + + + {% for row in ACCOUNT_LIST %} + + {% for cell in row %} + + {% endfor %} + + {% endfor %} + +
Konten
{{ cell }}
+ +

Drucker im Büro

+ + + + + + + + {% for row in STANDARD_RESSOURCEN %} + + {% for cell in row %} + + {% endfor %} + + {% endfor %} + +
Drucker
{{ cell }}
+ +

TUBS-Telefon

+ + + + + + + + {% for row in TELEFONNUMMER %} + + {% for cell in row %} + + {% endfor %} + + {% endfor %} + +
Direktwahl-Nr.
{{ cell }}
+ + +

Unterschrift:

+ Unterschrift + + +
+ + diff --git a/templates/templates.pdf b/templates/templates.pdf new file mode 100644 index 0000000000000000000000000000000000000000..76b07df9bf6dc8068cd8e7e4361a67f2d8629de8 GIT binary patch literal 33315 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 literal 0 HcmV?d00001