From 80bd2c9be242b85a52a1f126237d82d9e016f6fbc87b23dce3ef2d240b1fc7c5 Mon Sep 17 00:00:00 2001 From: linuxero Date: Thu, 13 Feb 2025 09:11:26 +0100 Subject: [PATCH] Employee and applicant frontend and backend --- Gui/AddApplicant.qml | 9 ++++--- Gui/EmployeesTable.qml | 52 ++++++++++++++++++++++++++---------- lib/DB/BusinessDAO.py | 1 + lib/DB/BusinessModel.py | 1 + lib/DB/EmployeeDAO.py | 56 ++++++++++++++++++++++++++++++++++++--- lib/DB/EmployeeModel.py | 58 ++++++++++++++++++++++++++++++++++++++--- lib/PyqcrmFlags.py | 5 ++++ main.py | 8 ++++-- 8 files changed, 165 insertions(+), 25 deletions(-) diff --git a/Gui/AddApplicant.qml b/Gui/AddApplicant.qml index 3f9e848..142275f 100644 --- a/Gui/AddApplicant.qml +++ b/Gui/AddApplicant.qml @@ -103,18 +103,21 @@ ColumnLayout var new_applicant if (radio.children[0].checked) { + // Ein Bewerber new_applicant = JsLib.parseForm(personalData) - // business_model.addApplicant(new_business, 0) + employee_model.addEmployee(new_applicant, false) // appLoader.source = "EmployeeTable.qml" - console.log(JSON.stringify (new_applicant)) + // console.log(JSON.stringify (new_applicant)) } else { + // Ein Mitarbeiter // console.log(personalData, bankAccount, nationalInsurance, applicantVarious) new_applicant = JsLib.parseForm(personalData, bankAccount, nationalInsurance, applicantVarious) + employee_model.addEmployee(new_applicant, true) // var new_contact = JsLib.addApplicant(addContactLayout) // contact_model.addContact(new_contact) - console.log(JSON.stringify (new_applicant)) + // console.log(JSON.stringify (new_applicant)) } } } diff --git a/Gui/EmployeesTable.qml b/Gui/EmployeesTable.qml index 5cb3cac..e96b34c 100644 --- a/Gui/EmployeesTable.qml +++ b/Gui/EmployeesTable.qml @@ -71,40 +71,56 @@ Item { id: horizontalHeader Layout.fillWidth: true - syncView: testTable + syncView: appliEmpTable + implicitHeight: 40 + visible: false + movableColumns: true //@disable-check M16 } TableView { - id: testTable + id: appliEmpTable Layout.fillHeight: true Layout.fillWidth: true columnSpacing: 1 rowSpacing: 2 - model: business_model + model: employee_model selectionBehavior: TableView.SelectRows + + ScrollBar.vertical: ScrollBar + { + policy: appliEmpTable.contentHeight > appliEmpTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff + } + selectionModel: ItemSelectionModel - - - { - id: selModel - model: testTable.model - } + { + id: selModel + model: appliEmpTable.model + } delegate:Rectangle { required property bool selected required property bool current - implicitWidth: 200 + //implicitWidth: 200 implicitHeight: 25 - color: selected? "lightblue": palette.base + color: selected + ? palette.highlight //palette.highlight + : (objectTable.alternatingRows && row % 2 !== 0 + ? palette.base // palette.base + : palette.alternateBase) //palette.alternateBase) Text { - Layout.fillWidth: true - text: model.display? model.display: "" + text: model.display === null? "": model.display + elide: Text.ElideRight + width: parent.width + height: parent.height + verticalAlignment: Text.AlignVCenter + leftPadding: 9 //@d isable-check M16 + color: palette.text } @@ -116,16 +132,24 @@ Item anchors.fill: parent hoverEnabled: true - onDoubleClicked: { employeesStack.push("EmployeeDetails.qml", {selectedEmployee: row}); } + onEntered: + { + appliEmpTable.selectionModel.select(appliEmpTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows) + } + } } } + Item + { + Layout.fillWidth: true + } } Component.onCompleted: employeesStack.pop() diff --git a/lib/DB/BusinessDAO.py b/lib/DB/BusinessDAO.py index 5dbf439..ee6d73f 100644 --- a/lib/DB/BusinessDAO.py +++ b/lib/DB/BusinessDAO.py @@ -8,6 +8,7 @@ class BusinessDAO(QObject): newBusinessAdded = Signal() __cur = None + __all_cols = None def __init__(self): #print(f"*** File: {__file__}, init()") diff --git a/lib/DB/BusinessModel.py b/lib/DB/BusinessModel.py index da793b0..3cd908d 100644 --- a/lib/DB/BusinessModel.py +++ b/lib/DB/BusinessModel.py @@ -63,6 +63,7 @@ from ..ConfigLoader import ConfigLoader class BusinessModel(QAbstractTableModel): __visible_index = {} + __visible_columns = None __col_name = "" __business_dao = None __business = None diff --git a/lib/DB/EmployeeDAO.py b/lib/DB/EmployeeDAO.py index 92d8d72..263ddeb 100644 --- a/lib/DB/EmployeeDAO.py +++ b/lib/DB/EmployeeDAO.py @@ -1,6 +1,56 @@ -# This Python file uses the following encoding: utf-8 +from .DbManager import DbManager +import json +import mariadb +from PySide6.QtCore import QObject, Signal +from ..PyqcrmFlags import PyqcrmAppliEmpyFlags -class EmployeeDAO: +class EmployeeDAO(QObject): + newEmployeeAdded = Signal() + + __cur = None + __all_cols = None + def __init__(self): - pass + super().__init__() + self.__con = DbManager().getConnection() + if self.__con: + self.__cur = self.__con.cursor() + + def getEmployees(self, enc_key, criterion = "Alle", appli_emp = 0, processed = False): + ''' + appli_emp: + 0 = applicants and employees + 1 = applicants only + 2 = employees only + ''' + try: + if self.__cur: + self.__cur.callproc("getEmployeesView", (appli_emp, processed, criterion, enc_key, )) + self.__all_cols = [desc[0] for desc in self.__cur.description] + return self.__cur.fetchall(), self.__all_cols + else: + return None, None + except mariadb.Error as e: + print(str(e)) + + def getEmployee(self, employee_id, enc_key = None): + try: + if self.__cur: + self.__cur.callproc("getEmployee", (employee_id, enc_key,)) + #self.__all_cols = [desc[0] for desc in self.__cur.description] + return self.__cur.fetchall() #, self.__all_cols + else: + return None #, None + except mariadb.Error as e: + print(str(e)) + + def addEmployee(self, data, enc_key, employee = False): + try: + if self.__cur: + self.__cur.callproc("addApplicant", (json.dumps(data), employee, enc_key,)) + self.__con.commit() + self.newEmployeeAdded.emit() + + except mariadb.Error as e: + print(str(e)) diff --git a/lib/DB/EmployeeModel.py b/lib/DB/EmployeeModel.py index 786c139..696b47b 100644 --- a/lib/DB/EmployeeModel.py +++ b/lib/DB/EmployeeModel.py @@ -1,6 +1,58 @@ -# This Python file uses the following encoding: utf-8 +from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt, Slot, Signal +from .EmployeeDAO import EmployeeDAO +from ..PyqcrmFlags import PyqcrmFlags, PyqcrmAppliEmpyFlags +from ..ConfigLoader import ConfigLoader -class EmployeeModel: +class EmployeeModel(QAbstractTableModel): + __data = None + __employee_dao = None + __visible_index = None + __visible_columns = None + __col_name = "" + __employee_dao = None + def __init__(self): - pass + super().__init__() + self.__employee_dao = EmployeeDAO() + self.__employee_dao.newEmployeeAdded.connect(self.__refreshView) + self.__conf = ConfigLoader().getConfig() + self.__key = self.__conf['pyqcrm']['ENCRYPTION_KEY'] + self.__getData() + + @Slot(dict, bool) + def addEmployee(self, new_employee, employee = False): + print(new_employee) + self.__employee_dao.addEmployee(new_employee, self.__key, employee) + + @Slot(str) + def viewCriterion(self, criterion): + self.__getData(criterion) + + @Slot() + def __refreshView(self): + self.__getData() + + def __getData(self, criterion = "Alle", processed = False): + self.beginResetModel() + rows, self.__visible_columns = self.__employee_dao.getEmployees(self.__key, criterion, 0, processed) + self.__data = rows + self.endResetModel() + + def rowCount(self, parent= QModelIndex()): + return len (self.__data) + + def columnCount(self, parent= QModelIndex()): + return len(self.__visible_columns) - 2 + + def data(self, index, role= Qt.DisplayRole): + if role == Qt.DisplayRole: + row = self.__data[index.row()] + return row[index.column() + 2] + return None + + def headerData(self, section, orientation, role= Qt.DisplayRole): + if orientation == Qt.Horizontal and role ==Qt.DisplayRole: + self.__col_name = self.__visible_columns[section + 2] + return self.__col_name + return super().headerData(section, orientation, role) diff --git a/lib/PyqcrmFlags.py b/lib/PyqcrmFlags.py index 1c5ac80..fd643d2 100644 --- a/lib/PyqcrmFlags.py +++ b/lib/PyqcrmFlags.py @@ -5,4 +5,9 @@ class PyqcrmFlags(IntFlag): ADMIN = 1 USER = 2 +class PyqcrmAppliEmpyFlags(IntFlag): + ALL = 0 + APPLICANT = 1 + EMPLOYEE = 2 + diff --git a/main.py b/main.py index d4f396f..70b63a1 100644 --- a/main.py +++ b/main.py @@ -14,6 +14,7 @@ from lib.DB.UserManager import UserManager from lib.DB.AddressModel import AddressModel from lib.DB.BTypeModel import BTypeModel from lib.DB.ContactModel import ContactModel +from lib.DB.EmployeeModel import EmployeeModel from lib.Printers import Printers @@ -37,12 +38,13 @@ address_model = None business_model = None business_type = None contact_model = None +employee_model = None printers = None user = None def initializeProgram(): #print(f"In {__file__} file, initializeProgram()") - global address_model, bad_config, business_model, user, business_type, contact_model, db_con, printers + global address_model, bad_config, business_model, user, business_type, contact_model, employee_model, db_con, printers if not bad_config: dbconf = config.getConfig()['database'] DbManager(dbconf) @@ -54,17 +56,19 @@ def initializeProgram(): address_model = AddressModel() business_type = BTypeModel() contact_model = ContactModel() + employee_model = EmployeeModel() publishContext() bad_config = False def publishContext(): # print(f"In {__file__} file, publishContext()") - global engine, address_model, bad_config, business_model, user, business_type, contact_model, printers + global engine, address_model, bad_config, business_model, user, business_type, contact_model, employee_model, printers engine.rootContext().setContextProperty("loggedin_user", user) engine.rootContext().setContextProperty("business_model", business_model) engine.rootContext().setContextProperty("address_model", address_model) engine.rootContext().setContextProperty("business_type", business_type) engine.rootContext().setContextProperty("contact_model", contact_model) + engine.rootContext().setContextProperty("employee_model", employee_model) if __name__ == "__main__":