8
0

Anlage des Repos

This commit is contained in:
2024-01-24 16:42:38 +01:00
commit 38d6a271c4
1785 changed files with 3051496 additions and 0 deletions

View File

@@ -0,0 +1,468 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Digital Data - Zeiterfassung
# ----------------------------------------------------------------------------
# Python-Script zur Buchung von Zeiten via QR/Barcode-Scanner inkl. Anbindung
# an die Mesonic WinLine. Per tkinter-Bibliothek wird eine GUI erzeugt.
# Via Webservice-Calls erfolgen verschiedene Abfragen.
#
# ----------------------------------------------------------------------------
# Copyright (c) 2021 by Digital Data GmbH
#
# Digital Data GmbH • Ludwig-Rinn-Strasse 16 • D-35452 Heuchelheim
# Tel.: 0641/202360 • E-Mail: info-flow@digitaldata.works
# ----------------------------------------------------------------------------
# Creation Date / Author: 15.09.2021 / MD
# Version Date / Editor: 04.11.2021 / MD
# Version Number: 1.0.1.1
####################################
# # Import # #
####################################
import tkinter as tk
from datetime import datetime
import cv2
import numpy as np
from pyzbar.pyzbar import decode
import requests
import configparser
import cryptocode
from tkinter.messagebox import showerror
import logging
from logging.handlers import TimedRotatingFileHandler
from logging import Formatter
#####################################
# # Server-Options # #
# # In config.in bearbeitbar # #
#####################################
config = configparser.ConfigParser()
config.sections()
config.read('config.ini')
WebServiceURL = config['WEBSERVICE']['WebServiceURL']
WebServiceBenutzerName = config['WEBSERVICE']['WebServiceBenutzerName']
WebServiceBenutzerPasswort = config['WEBSERVICE']['WebServiceBenutzerPasswort']
WinLineMandant = config['WEBSERVICE']['WinLineMandant']
WebServiceTemplateSTART = config['WEBSERVICE']['WebServiceTemplateSTART']
WebServiceTemplateSTOP = config['WEBSERVICE']['WebServiceTemplateSTOP']
WebServiceType = config['WEBSERVICE']['WebServiceType']
Fehlzeitenstamm = config['WEBSERVICE']['Fehlzeitenstamm']
WeekRule = config['PAUSEKEYRULE']['WeekRule']
WebServiceActioncode = "1"
dePW = cryptocode.decrypt(WebServiceBenutzerPasswort, "Zeiterfassung")
class App(tk.Tk):
def showError(self, exc, val, tb):
#showerror("Error", message=str(val))
self.logger.error('')
self.logger.error(exc)
self.logger.error(val)
self.logger.error(tb)
############################################
# # Frame # #
# Erstellt die GUI inkl. Button und Labels #
############################################
def __init__(self):
super().__init__()
# LOG-File-Generator
self.logger = logging.getLogger('mylogger')
self.handler = TimedRotatingFileHandler(filename='log/Zeiterfassung.log', when='D', interval=1, backupCount=30, encoding='utf-8', delay=False)
# logging.basicConfig(format='%(asctime)s|%(levelname)s|%(message)s', level=logging.DEBUG, filename='Zeiterfassung2.log')
formatter = Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
self.handler.setFormatter(formatter)
self.logger.addHandler(self.handler)
self.logger.setLevel(logging.DEBUG)
self.configure(bg="white")
self.title("DD-Zeiterfassung")
self.geometry("1024x768")
#self.attributes("-topmost", True) -- tkinter gui immer im vordergrund
#self.wm_overrideredirect(True) -- tkinter gui ohne Titlezeile
self.wm_attributes('-type', 'splash') # -- tkinter gui Titelzeile klappt sich ein
self.start_button = tk.Button(self, font=('Arial', 12), text="Arbeitstag\n beginnen", height =15, width=15, fg="white", bg="green", activebackground='blue', command=self.Startbutton_action)
self.stop_button = tk.Button(self, font=('Arial', 12), text="Arbeitstag\n beenden ", height =15, width=15, fg="white", bg="red", activebackground='blue', command=self.Stopbutton_action)
self.pause_button = tk.Button(self, font=('Arial', 12), text="Pause\n beginnen", height=15, width=15, fg="white", bg="#b47a0e", activebackground='blue', command=self.PauseStartbutton_action)
self.pause_end_button = tk.Button(self, font=('Arial', 12), text="Pause\n beenden", height=15, width=15, fg="white", bg="#b47a0e", activebackground='blue', command=self.PauseStopbutton_action)
self.anweisungs_label = tk.Label(self, font=('Arial', 12), text="Wählen Sie eine Buchungsart\n")
self.anweisungs_label2 = tk.Label(self, font=('Arial', 12), bg="white", fg="black")
self.labelUhr = tk.Label(text="", font=('Arial', 12), fg='red')
self.update_clock()
self.labelUhr.grid(row=0,column=4)
self.anweisungs_label.grid(row=0, column=2, pady=20, padx=10, sticky='ew')
self.anweisungs_label2.grid(row=1, column=2, pady=20, padx=10, sticky='ew')
self.start_button.grid(row=2, column=1, pady=20, padx=10, sticky='ew')
self.stop_button.grid(row=2, column=2, pady=20, padx=10, sticky='ew')
self.pause_button.grid(row=2, column=3, pady=20, padx=10, sticky='ew')
self.pause_end_button.grid(row=2, column=4, pady=20, padx=10, sticky='ew')
self.report_callback_exception = self.showError
self.logger.info("Initialisierung abgeschlossen!")
########################################
# # Button-Action # #
# # Legende # #
# RequestTyp = 1 = Arbeitstag beginnen #
# RequestTyp = 2 = Arbeitstag beenden #
# RequestTyp = 3 = Pause beginnen #
# RequestTyp = 4 = Pause beenden #
########################################
# # Different-Buttons # #
########################################
def update_clock(self):
now = datetime.now()
clock = now.strftime('%H:%M:%S')
self.labelUhr.configure(text=clock)
self.after(1000, self.update_clock)
def disableButtons(self):
self.start_button['state'] = tk.DISABLED
self.stop_button['state'] = tk.DISABLED
self.pause_button['state'] = tk.DISABLED
self.pause_end_button['state'] = tk.DISABLED
def enableButtons(self):
self.start_button['state'] = tk.NORMAL
self.stop_button['state'] = tk.NORMAL
self.pause_button['state'] = tk.NORMAL
self.pause_end_button['state'] = tk.NORMAL
def Startbutton_action(self):
RequestTyp = 1
self.Button_action(RequestTyp)
######################################
def Stopbutton_action(self):
RequestTyp = 2
self.Button_action(RequestTyp)
######################################
def PauseStartbutton_action(self):
RequestTyp = 3
self.Button_action(RequestTyp)
######################################
def PauseStopbutton_action(self):
RequestTyp = 4
self.Button_action(RequestTyp)
######################################
def Button_action(self, RequestTyp):
myData = Scanner(self)
#myDataListe = myData.split("-")
now = datetime.now()
actDateTime = now.strftime('%Y-%m-%d') + "T" + now.strftime('%H:%M:%S')
MakeWinLineRequest(self, RequestTyp, myData, actDateTime, now)
######################################
# # Reset der GUI # #
######################################
def LabelReset(self):
anweisungs_label = tk.Label(font=('Arial', 12), text="Wählen Sie eine Buchungsart\n")
anweisungs_label.grid(row=0, column=2, sticky='ew')
anweisungs_label2 = tk.Label(font=('Arial', 12), bg="white", text="")
anweisungs_label2.grid(row=1, column=2, sticky='ew')
self.configure(bg="white")
app.event_generate('<Motion>', warp=True, x=1, y=1) # Set the Mouse-Position to x/y
self.enableButtons(self)
######################################
# # Build Start-XML # #
######################################
def BuildXMLStart(RequestTyp, myData, Datumvon):
if RequestTyp == 1:
ArbeitsZeitPause = "0"
Fehlzeitenstamm =config['WEBSERVICE']['Fehlzeitenstamm']
else:
ArbeitsZeitPause = "1"
if WeekRule == 'on':
Weekday = datetime.today().isoweekday()
Fehlzeitenstamm = config['PAUSEKEYRULE']['Weekday' + str(Weekday)]
else:
Fehlzeitenstamm = "1"
myDataListe = myData.split("-")
AN_Gruppe_Ressource = myDataListe[0]
XML_Start = ""
XML_Start = XML_Start + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
XML_Start = XML_Start + "<MESOWebService TemplateType=\"" + WebServiceType + "\"" " Template=\"" + WebServiceTemplateSTART + "\">"
XML_Start = XML_Start + "<" + WebServiceTemplateSTART + ">"
#Location for WinLine fields
XML_Start = XML_Start + "<Datumvon>" + Datumvon + "</Datumvon>"
XML_Start = XML_Start + "<Fehlzeitenstamm>" + Fehlzeitenstamm + "</Fehlzeitenstamm>"
XML_Start = XML_Start + "<ANGruppeRessource>" + AN_Gruppe_Ressource + "</ANGruppeRessource>"
XML_Start = XML_Start + "<TypZeitartPause>" + ArbeitsZeitPause + "</TypZeitartPause>"
XML_Start = XML_Start + "</" + WebServiceTemplateSTART + ">"
XML_Start = XML_Start + "</MESOWebService>"
return XML_Start
######################################
# # Build Start-URL # #
######################################
def BuildURLStart(XML_Start):
URL_Start = "http://%SERVER%/ewlservice/import?User=%USER%&Password=%PASSWORD%&Company=%COMPANY%&Type=%TYPE%&Vorlage=%VORLAGE%&Actioncode=%ACTIONCODE%&byref=0&Data=%DATA%"
URL_Start = URL_Start.replace("%SERVER%", WebServiceURL)
URL_Start = URL_Start.replace("%USER%", WebServiceBenutzerName)
URL_Start = URL_Start.replace("%PASSWORD%", dePW)
URL_Start = URL_Start.replace("%COMPANY%", WinLineMandant)
URL_Start = URL_Start.replace("%TYPE%", WebServiceType)
URL_Start = URL_Start.replace("%VORLAGE%", WebServiceTemplateSTART)
URL_Start = URL_Start.replace("%ACTIONCODE%", WebServiceActioncode)
URL_Start = URL_Start.replace("%DATA%", XML_Start)
return URL_Start
####################################
# # Build Export-URL # #
####################################
def BuildURLExport(myData,RequestTyp):
myDataListe = myData.split("-")
Arbeitnehmernummer = myDataListe[0]
if RequestTyp == 1:
WebServiceTemplateExport = "Export"
Filter = "FilterTest-" + Arbeitnehmernummer
elif RequestTyp == 2:
WebServiceTemplateExport = "Export"
Filter = "FilterTest-" + Arbeitnehmernummer
elif RequestTyp == 3:
WebServiceTemplateExport = "ExportPause"
Filter = "FilterTestP-" + Arbeitnehmernummer
elif RequestTyp == 4:
WebServiceTemplateExport = "ExportPause"
Filter = "FilterTestP-" + Arbeitnehmernummer
XMLExport = Filter
URL_Export = "http://%SERVER%/ewlservice/export?User=%USER%&Password=%PASSWORD%&Company=%COMPANY%&Type=%TYPE%&Vorlage=%VORLAGE%&Actioncode=%ACTIONCODE%&byref=0&Key=%KEY%"
URL_Export = URL_Export.replace("%SERVER%", WebServiceURL)
URL_Export = URL_Export.replace("%USER%", WebServiceBenutzerName)
URL_Export = URL_Export.replace("%PASSWORD%", dePW)
URL_Export = URL_Export.replace("%COMPANY%", WinLineMandant)
URL_Export = URL_Export.replace("%TYPE%", WebServiceType)
URL_Export = URL_Export.replace("%VORLAGE%", WebServiceTemplateExport)
URL_Export = URL_Export.replace("%ACTIONCODE%", WebServiceActioncode)
URL_Export = URL_Export.replace("%KEY%", XMLExport)
URL_Export = URL_Export.replace("%FILTER%", Filter)
print("URL_Export = " + URL_Export)
HTTPRequest_Export = requests.post(URL_Export)
IndexVonDatum = HTTPRequest_Export.text.find("<Datumvon>")
v1 = IndexVonDatum + len("<Datumvon>")
v2 = v1 + 19
Datumvon = HTTPRequest_Export.text[v1:v2]
return Datumvon
######################################
# # Build End-XML # #
######################################
def BuildXMLEnde(RequestTyp, myData, OrgDateTime, ActDateTime):
print(RequestTyp)
if RequestTyp == 2:
ArbeitsZeitPause = "0"
Fehlzeitenstamm =config['WEBSERVICE']['Fehlzeitenstamm']
else:
ArbeitsZeitPause = "1"
if WeekRule == 'on':
Weekday = datetime.today().isoweekday()
Fehlzeitenstamm = config['PAUSEKEYRULE']['Weekday' + str(Weekday)]
else:
Fehlzeitenstamm = "1"
myDataListe = myData.split("-")
AN_Gruppe_Ressource = myDataListe[0]
XML_Ende = ""
XML_Ende = XML_Ende + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
XML_Ende = XML_Ende + "<MESOWebService TemplateType=\"" + WebServiceType + "\"" " Template=\"" + WebServiceTemplateSTOP + "\">"
XML_Ende = XML_Ende + "<" + WebServiceTemplateSTOP + ">"
XML_Ende = XML_Ende + "<Datumvon>" + OrgDateTime + "</Datumvon>"
XML_Ende = XML_Ende + "<Datumbis>" + ActDateTime + "</Datumbis>"
XML_Ende = XML_Ende + "<Fehlzeitenstamm>" + Fehlzeitenstamm + "</Fehlzeitenstamm>"
XML_Ende = XML_Ende + "<ANGruppeRessource>" + AN_Gruppe_Ressource + "</ANGruppeRessource>"
XML_Ende = XML_Ende + "<TypZeitartPause>" + ArbeitsZeitPause + "</TypZeitartPause>"
XML_Ende = XML_Ende + "<Importoption>" + "1" + "</Importoption>"
XML_Ende = XML_Ende + "</" + WebServiceTemplateSTOP + ">"
XML_Ende = XML_Ende + "</MESOWebService>"
return XML_Ende
######################################
# # Build End-URL # #
######################################
def BuildURLEnde(XML_Ende):
URL_Ende = "http://%SERVER%/ewlservice/import?User=%USER%&Password=%PASSWORD%&Company=%COMPANY%&Type=%TYPE%&Vorlage=%VORLAGE%&Actioncode=%ACTIONCODE%&byref=0&Data=%DATA%"
URL_Ende = URL_Ende.replace("%SERVER%", WebServiceURL)
URL_Ende = URL_Ende.replace("%USER%", WebServiceBenutzerName)
URL_Ende = URL_Ende.replace("%PASSWORD%", dePW)
URL_Ende = URL_Ende.replace("%COMPANY%", WinLineMandant)
URL_Ende = URL_Ende.replace("%TYPE%", WebServiceType)
URL_Ende = URL_Ende.replace("%VORLAGE%", WebServiceTemplateSTOP)
URL_Ende = URL_Ende.replace("%ACTIONCODE%", WebServiceActioncode)
URL_Ende = URL_Ende.replace("%DATA%", XML_Ende)
return URL_Ende
######################################
# WinLine Requests # #
######################################
def MakeWinLineRequest(self, RequestTyp, myData, actDateTime, now):
myDataListe = myData.split("-")
name = myDataListe[1]
TimeWithoutsec = now.strftime('%H:%M:%S')
#######################################
if RequestTyp == 1:
CheckStatus = BuildURLExport(myData, RequestTyp)
if CheckStatus == "sion=\"1.0\" encoding":
XMLStart = BuildXMLStart(RequestTyp, myData, actDateTime)
URLStart = BuildURLStart(XMLStart)
HTTPRequest_Start = requests.post(URLStart)
print(HTTPRequest_Start.text)
self.anweisungs_label = tk.Label(font=('Arial', 12), text="Hallo,\n " + str(name))
self.anweisungs_label.grid(row=0, column=2, sticky='ew')
self.anweisungs_label2 = tk.Label(font=('Arial', 12), text="Es ist " + str(TimeWithoutsec) + " Uhr ")
self.anweisungs_label2.grid(row=1, column=2, sticky='ew')
self.configure(bg="green")
self.after(5000, LabelReset, self)
else:
self.anweisungs_label = tk.Label(font=('Arial', 12), text= "Sie sind bereits eingeloggt\n")
self.anweisungs_label.grid(row=0, column=2, sticky='ew')
self.configure(bg="red")
self.after(5000, LabelReset, self)
###################################
elif RequestTyp == 2:
OrgDateTime = BuildURLExport(myData, RequestTyp)
Weekday = datetime.today().isoweekday()
if OrgDateTime == "sion=\"1.0\" encoding":
self.anweisungs_label = tk.Label(font=('Arial', 12), text="Sie sind nicht eingeloggt\n")
self.anweisungs_label.grid(row=0, column=2, sticky='ew')
self.configure(bg="red")
self.after(5000, LabelReset, self)
else:
XMLEnde = BuildXMLEnde(RequestTyp, myData, OrgDateTime, actDateTime)
URLEnde = BuildURLEnde(XMLEnde)
HTTPRequest_Ende = requests.post(URLEnde)
print(HTTPRequest_Ende.text)
self.anweisungs_label = tk.Label(font=('Arial', 12), text="Auf Wiedersehen,\n " + str(name))
self.anweisungs_label.grid(row=0, column=2, sticky='ew')
self.anweisungs_label2 = tk.Label(font=('Arial', 12), text="Es ist " + str(TimeWithoutsec) + " Uhr ")
self.anweisungs_label2.grid(row=1, column=2, sticky='ew')
self.configure(bg="green")
self.after(5000, LabelReset, self)
####################################
elif RequestTyp == 3:
CheckStatus = BuildURLExport(myData, RequestTyp)
if CheckStatus == "sion=\"1.0\" encoding":
XMLStart = BuildXMLStart(RequestTyp, myData, actDateTime)
URLStart = BuildURLStart(XMLStart)
HTTPRequest_Start = requests.post(URLStart)
print(HTTPRequest_Start.text)
self.anweisungs_label = tk.Label(font=('Arial', 12), text=u"Eine schöne Pause,\n " + str(name))
self.anweisungs_label.grid(row=0, column=2, sticky='ew')
self.anweisungs_label2 = tk.Label(font=('Arial', 12), text="Es ist " + str(TimeWithoutsec) + " Uhr ")
self.anweisungs_label2.grid(row=1, column=2, sticky='ew')
self.configure(bg="green")
self.after(5000, LabelReset, self)
else:
self.anweisungs_label = tk.Label(font=('Arial', 12), text="Sie sind bereits in Pause\n")
self.anweisungs_label.grid(row=0, column=2, sticky='ew')
self.configure(bg="red")
self.after(5000, LabelReset, self)
#######################################
elif RequestTyp == 4:
OrgDateTime = BuildURLExport(myData, RequestTyp)
if OrgDateTime == "sion=\"1.0\" encoding":
self.anweisungs_label = tk.Label(font=('Arial', 12), text="Sie sind nicht in Pause\n")
self.anweisungs_label.grid(row=0, column=2, sticky='ew')
self.configure(bg="red")
self.after(5000, LabelReset, self)
else:
XMLEnde = BuildXMLEnde(RequestTyp, myData, OrgDateTime, actDateTime)
URLEnde = BuildURLEnde(XMLEnde)
HTTPRequest_Ende = requests.post(URLEnde)
print(HTTPRequest_Ende.text)
self.anweisungs_label = tk.Label(font=('Arial', 12), text="Willkommen zurück,\n " + str(name))
self.anweisungs_label.grid(row=0, column=2, sticky='ew')
self.anweisungs_label2 = tk.Label(font=('Arial', 12), text="Es ist " + str(TimeWithoutsec) + " Uhr ")
self.anweisungs_label2.grid(row=1, column=2, sticky='ew')
self.configure(bg="green")
self.after(5000, LabelReset, self)
######################################
# # Scanner # #
######################################
def Scanner(self):
app.event_generate('<Motion>', warp=True, x=1, y=1)
self.anweisungs_label = tk.Label(font=('Arial', 12), text="Wählen Sie eine Buchungsart\n")
cap = cv2.VideoCapture(0)
cap.set(3, 160) # vorher 640
cap.set(4, 120) # vorher 480
cv2.namedWindow('Result')
cv2.moveWindow('Result', 2, 2)
myData = None
#Abbruch = False
for x in range(0, 100):
success, img = cap.read()
for barcode in decode(img):
myData = barcode.data.decode('utf-8')
rotated_img = np.rot90(img, k=3)
cv2.imshow('Result', rotated_img)
cv2.waitKey(1)
if myData is not None:
cap.release()
cv2.destroyAllWindows()
return myData
else:
self.after(100)
cap.release()
cv2.destroyAllWindows()
LabelReset(self)
######################################
# # Main # #
######################################
if __name__ == "__main__":
app = App()
app.mainloop()