diff --git a/main.py b/main.py index 1d2aae4..1bce9d3 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ -hello_world = lambda: "Hello, World!" +from src.ui.main_ui import launch -print(hello_world()) +if __name__ == "__main__": + launch() diff --git a/src/logic/__init__.py b/src/logic/__init__.py index fc1efde..d9dd733 100644 --- a/src/logic/__init__.py +++ b/src/logic/__init__.py @@ -1,3 +1,4 @@ __help__ = "This package contains the logic of the application." from .database import Database -from .catalogue import Catalogue \ No newline at end of file +from .catalogue import Catalogue +from .backup import Backup \ No newline at end of file diff --git a/src/logic/catalogue.py b/src/logic/catalogue.py index c1451e7..a29756b 100644 --- a/src/logic/catalogue.py +++ b/src/logic/catalogue.py @@ -3,7 +3,7 @@ from bs4 import BeautifulSoup from src import config from src.schemas import Book -URL = "https://rds.ibs-bw.de/phfreiburg/opac/RDSIndex/Search?lookfor={}+&type=AllFields&limit=10&sort=py+desc%2C+title" +URL = 'https://rds.ibs-bw.de/phfreiburg/opac/RDSIndex/Search?lookfor="{}"+&type=AllFields&limit=10&sort=py+desc%2C+title' BASE = "https://rds.ibs-bw.de" diff --git a/src/logic/database.py b/src/logic/database.py index 066ddde..0815f0e 100644 --- a/src/logic/database.py +++ b/src/logic/database.py @@ -3,7 +3,7 @@ import os from src import config from pathlib import Path from src.schemas import USERS, MEDIA, LOANS, User, Book - +from src.utils.stringtodate import stringToDate class Database: def __init__(self, db_path: str = None): @@ -143,6 +143,32 @@ class Database: self.close_connection(conn) return cursor.lastrowid + def getMediaSimilarSignatureByID(self, media_id) -> list[Book]: + query = f"SELECT * FROM media WHERE id = '{media_id}'" + conn = self.connect() + cursor = conn.cursor() + cursor.execute(query) + result = cursor.fetchone() + signature = result[1] + print(signature) + query = f"SELECT * FROM media WHERE signature LIKE '%{signature}%'" + cursor.execute(query) + result = cursor.fetchall() + + self.close_connection(conn) + data = [] + for res in result: + data.append( + Book( + signature=res[1], + isbn=res[2], + ppn=res[3], + title=res[4], + database_id=res[0], + ) + ) + return data + def getMedia(self, media_id): query = f"SELECT * FROM media WHERE id = '{media_id}'" conn = self.connect() @@ -159,6 +185,25 @@ class Database: ) return res + def getAllMedia(self, user_id): + # get all books that have the user id in the loans table + query = f"SELECT * FROM loans WHERE user_id = '{user_id}'" + conn = self.connect() + cursor = conn.cursor() + cursor.execute(query) + result = cursor.fetchall() + self.close_connection(conn) + books = [] + for res in result: + book = self.getMedia(res[2]) + book.loan_from = res[3] + book.loan_to = res[4] + book.returned = res[5] + book.returned_date = res[6] + books.append(book) + print(book) + return books + def checkMediaExists(self, media): conn = self.connect() cursor = conn.cursor() @@ -182,8 +227,8 @@ class Database: self.close_connection(conn) return result - def returnMedia(self, media_id): - query = f"UPDATE loans SET returned = 1 WHERE media_id = '{media_id}'" + def returnMedia(self, media_id, returndate): + query = f"UPDATE loans SET returned = 1, returned_date = '{returndate}' WHERE media_id = '{media_id}' AND returned = 0" conn = self.connect() cursor = conn.cursor() cursor.execute(query) @@ -222,3 +267,12 @@ class Database: self.close_connection(conn) if result is not None: return result[0] + + def extendLoanDuration(self, signature, newDate): + book_id = self.checkMediaExists(Book(signature=signature)) + query = f"UPDATE loans SET return_date = '{newDate}' WHERE media_id = '{book_id[0]}' AND returned = 0" + conn = self.connect() + cursor = conn.cursor() + cursor.execute(query) + conn.commit() + self.close_connection(conn) diff --git a/src/schemas/book.py b/src/schemas/book.py index 1e8e292..6e9a904 100644 --- a/src/schemas/book.py +++ b/src/schemas/book.py @@ -10,3 +10,7 @@ class Book: link: str | None = None database_id: int | None = None link: str | None = None + loan_from: str | None = None + loan_to: str | None = None + returned: int | None = None + returned_date: str | None = None diff --git a/src/schemas/database.py b/src/schemas/database.py index 614e947..0a1dabb 100644 --- a/src/schemas/database.py +++ b/src/schemas/database.py @@ -9,7 +9,7 @@ signature TEXT NOT NULL, isbn TEXT NOT NULL, ppn TEXT NOT NULL, title TEXT NOT NULL, -link TEXT NOT NULL,); +link TEXT NOT NULL); """ LOANS = """CREATE TABLE IF NOT EXISTS loans ( @@ -19,6 +19,7 @@ media_id INTEGER NOT NULL, loan_date TEXT NOT NULL, return_date TEXT NOT NULL, returned INTEGER DEFAULT 0, +returned_date TEXT, FOREIGN KEY (user_id) REFERENCES users(id), FOREIGN KEY (media_id) REFERENCES media(id)); """ diff --git a/src/ui/extendLoan.py b/src/ui/extendLoan.py new file mode 100644 index 0000000..5977a29 --- /dev/null +++ b/src/ui/extendLoan.py @@ -0,0 +1,31 @@ +from .sources.Ui_dialog_extendLoanDuration import Ui_Dialog +from PyQt6 import QtWidgets, QtCore + + +class ExtendLoan(QtWidgets.QDialog, Ui_Dialog): + def __init__(self, user, media): + super(ExtendLoan, self).__init__() + self.setupUi(self) + self.user = user + self.media = media + self.currentDate = QtCore.QDate.currentDate().addDays(1) + self.extendDate = None + self.extenduntil.setMinimumDate(self.currentDate) + self.show() + self.buttonBox.accepted.connect(self.extendLoan) + + def extendLoan(self): + print("Extend Loan") + selectedDate = self.extenduntil.selectedDate() + print(selectedDate) + self.extendDate = selectedDate + self.close() + pass + + +def launch(user, media): + import sys + + app = QtWidgets.QApplication(sys.argv) + window = ExtendLoan(user, media) + sys.exit(app.exec()) diff --git a/src/ui/main_ui.py b/src/ui/main_ui.py index 844b7fd..51f53b4 100644 --- a/src/ui/main_ui.py +++ b/src/ui/main_ui.py @@ -4,9 +4,10 @@ from .user import UserUI from .createUser import CreateUser from .multiUserInfo import MultiUserFound from .newentry import NewEntry +from .settings import Settings from src import config from src.logic import Database, Catalogue, Backup -from src.utils import stringToDate +from src.utils import stringToDate, Icon from src.schemas import User, Book from PyQt6 import QtCore, QtGui, QtWidgets import sys @@ -18,6 +19,8 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super(MainUI, self).__init__() self.setupUi(self) + self.setWindowTitle("Handbibliotheksleihsystem") + self.setWindowIcon(Icon("main").icon) self.db = Database() self.currentDate = QtCore.QDate.currentDate() self.label_7.hide() @@ -29,7 +32,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): # hotkeys self.actionRueckgabemodus.triggered.connect(self.changeMode) self.actionNutzer.triggered.connect(self.showUser) - + self.actionEinstellungen.triggered.connect(self.showSettings) #Buttons self.btn_show_lentmedia.clicked.connect(self.showUser) @@ -40,7 +43,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): self.input_username.returnPressed.connect( lambda: self.checkUser("username", self.input_username.text()) ) - self.input_file_ident.returnPressed.connect(self.addMedia) + self.input_file_ident.returnPressed.connect(self.handleLineInput) self.input_userno.setValidator(QtGui.QIntValidator()) # TableWidget @@ -52,29 +55,29 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): self.show() + def showSettings(self): + settings = Settings() + settings.exec() + def changeMode(self): - current = self.mode.text() - if current == "Ausleihe": - self.mode.setText("Rückgabe") - self.input_username.clear() - self.input_userno.clear() - self.userdata.clear() - self.btn_show_lentmedia.setText("") - self.label_7.hide() - self.nextReturnDate.hide() - if current == "Rückgabe": - self.input_username.clear() - self.input_userno.clear() - self.userdata.clear() - self.mediaOverview.setRowCount(0) - self.btn_show_lentmedia.setText("") - self.input_file_ident.clear() - self.nextReturnDate.hide() - self.label_7.hide() + self.mode.setText("Rückgabe") + self.input_username.clear() + self.input_userno.clear() + self.userdata.clear() + self.btn_show_lentmedia.setText("") + self.input_file_ident.clear() + self.label_7.hide() + self.nextReturnDate.hide() def showUser(self): if self.activeUser is None: # create warning dialog + dialog = QtWidgets.QMessageBox() + dialog.setWindowTitle("Kein Nutzer ausgewählt") + dialog.setIcon(QtWidgets.QMessageBox.Icon.Warning) + dialog.setWindowIcon(Icon("warning").overwriteColor("#EA3323")) + dialog.setText("Kein Nutzer ausgewählt") + dialog.exec() return self.user_ui = UserUI( @@ -123,7 +126,18 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): def moveToLine(self, line): line.setFocus() + def handleLineInput(self): + value = self.input_file_ident.text().strip() + if len(value) <= 2: + self.callShortcut(value) + else: + if self.mode.text() == "Rückgabe": + self.returnMedia(value) + else: + self.mediaAdd(value) + def mediaAdd(self, identifier): + self.clearStatusTip print("Adding Media", identifier) self.setStatusTip("") self.input_file_ident.clear() @@ -138,13 +152,33 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): if book_id: if len(book_id) > 1: print("Multiple Books found") + # TODO: implement book selection dialog return else: # check if book is already loaned loaned = self.db.checkLoanState(book_id[0]) if loaned: print("Book already loaned") - self.setStatusTip("Book already loaned") + self.setStatusTipMessage("Buch bereits entliehen") + # dialog with yes no to create new entry + dialog = QtWidgets.QMessageBox() + dialog.setText( + "Buch bereits entliehen, soll ein neues hinzugefügt werden?" + ) + dialog.setStandardButtons( + QtWidgets.QMessageBox.StandardButton.Yes + | QtWidgets.QMessageBox.StandardButton.No + ) + dialog.setDefaultButton(QtWidgets.QMessageBox.StandardButton.No) + dialog.exec() + result = dialog.result() + if result == QtWidgets.QMessageBox.StandardButton.No: + return + newentry = NewEntry([book_id[0]]) + newentry.exec() + self.setStatusTipMessage("Neues Exemplar hinzugefügt") + created_ids = newentry.newIds + print(created_ids) self.input_file_ident.setEnabled(True) return @@ -189,14 +223,6 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): sysem_shortcuts = None print(sysem_shortcuts) - def addMedia(self): - mode = self.mode.text() - value = self.input_file_ident.text() - # if vaule is string, call shortcut, else mediaAdd - if mode == "Rückgabe": - self.returnMedia(value) - else: - self.lendMedia(value) def returnMedia(self, identifier): print("Returning Media", identifier) @@ -232,15 +258,12 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow): else: print("Book not found") - def lendMedia(self, value): - value = value.strip() - if value.isnumeric(): - self.mediaAdd(value) - else: - if len(value) <= 2: - self.callShortcut(value) - else: - self.mediaAdd(value) + def setStatusTipMessage(self, message): + self.setStatusTip(message) + + @property + def clearStatusTip(self): + self.setStatusTip("") def exit_handler(): print("Exiting") @@ -258,6 +281,6 @@ def exit_handler(): def launch(): app = QtWidgets.QApplication(sys.argv) main_ui = MainUI() - atexit.register(exit_handler) + # atexit.register(exit_handler) sys.exit(app.exec()) # sys.exit(app.exec()) diff --git a/src/ui/newentry.py b/src/ui/newentry.py index 155f0b3..2c6a2e6 100644 --- a/src/ui/newentry.py +++ b/src/ui/newentry.py @@ -2,18 +2,20 @@ from .sources.Ui_dialog_addNewTitleEntry import Ui_Dialog from PyQt6 import QtWidgets, QtCore, QtGui from src.logic import Database from src.schemas import Book - +from src.utils import Icon class NewEntry(QtWidgets.QDialog, Ui_Dialog): - def __init__(self, title): + def __init__(self, title_id: list[int]): super(NewEntry, self).__init__() self.setupUi(self) self.setWindowTitle("Neues Exemplar hinzufügen") + self.setWindowIcon(Icon("newentry").overwriteColor("#ffffff")) self.tableWidget.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.ResizeMode.Stretch ) self.db = Database() - self.titles = title + self.titles = title_id + self.newIds = [] self.populateTable() self.btn_addNewBook.clicked.connect(self.addEntry) self.buttonBox.accepted.connect(self.insertEntry) @@ -26,16 +28,30 @@ class NewEntry(QtWidgets.QDialog, Ui_Dialog): self.tableWidget.setItem( row, i, QtWidgets.QTableWidgetItem(self.tableWidget.item(row - 1, i)) ) - + if i == 2 and "+" in self.tableWidget.item(row, i).text(): + entry = self.tableWidget.item(row, i).text().split("+")[1] + entry = str(int(entry) + 1) + self.tableWidget.setItem( + row, + i, + QtWidgets.QTableWidgetItem( + self.tableWidget.item(row, i).text().split("+")[0] + "+" + entry + ), + ) def populateTable(self): for title in self.titles: print(title) - entry = self.db.getMedia(title) - self.tableWidget.insertRow(0) - self.tableWidget.setItem(0, 0, QtWidgets.QTableWidgetItem(entry.isbn)) - self.tableWidget.setItem(0, 1, QtWidgets.QTableWidgetItem(entry.title)) - self.tableWidget.setItem(0, 2, QtWidgets.QTableWidgetItem(entry.signature)) - self.tableWidget.setItem(0, 3, QtWidgets.QTableWidgetItem(entry.ppn)) + entries = self.db.getMediaSimilarSignatureByID(title) + # sort by signature + entries.sort(key=lambda x: x.signature, reverse=True) + for entry in entries: + self.tableWidget.insertRow(0) + self.tableWidget.setItem(0, 0, QtWidgets.QTableWidgetItem(entry.isbn)) + self.tableWidget.setItem(0, 1, QtWidgets.QTableWidgetItem(entry.title)) + self.tableWidget.setItem( + 0, 2, QtWidgets.QTableWidgetItem(entry.signature) + ) + self.tableWidget.setItem(0, 3, QtWidgets.QTableWidgetItem(entry.ppn)) def insertEntry(self): # get all rows, convert them to Book and insert into database @@ -52,7 +68,8 @@ class NewEntry(QtWidgets.QDialog, Ui_Dialog): ) print(book) if not self.db.checkMediaExists(book): - self.db.insertMedia(book) + newBookId = self.db.insertMedia(book) + self.newIds.append(newBookId) def launch(): diff --git a/src/ui/settings.py b/src/ui/settings.py new file mode 100644 index 0000000..d3d79c6 --- /dev/null +++ b/src/ui/settings.py @@ -0,0 +1,137 @@ +from .sources.Ui_dialog_settings import Ui_Dialog +from PyQt6 import QtWidgets, QtCore +from src.utils import Icon +from src import config +from omegaconf import OmegaConf + + +class Settings(QtWidgets.QDialog, Ui_Dialog): + def __init__(self): + super(Settings, self).__init__() + self.setupUi(self) + self.setWindowTitle("Einstellungen") + self.setWindowIcon(Icon("settings").icon) + self.originalSettings = config + + # lineedits + self.institution_name.textChanged.connect(self.enableButtonBox) + self.default_loan_duration.textChanged.connect(self.enableButtonBox) + self.database_backupLocation.textChanged.connect(self.enableButtonBox) + self.database_path.textChanged.connect(self.enableButtonBox) + self.database_name.textChanged.connect(self.enableButtonBox) + self.database_name.textChanged.connect(self.enableButtonBox) + + # buttonbox + self.buttonBox.accepted.connect(self.saveSettings) + self.buttonBox.rejected.connect(self.close) + self.loadSettings() + self.buttonBox.button( + QtWidgets.QDialogButtonBox.StandardButton.Discard + ).clicked.connect(self.DiscardSettings) + self.buttonBox.button( + QtWidgets.QDialogButtonBox.StandardButton.Discard + ).setEnabled(False) + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setEnabled( + False + ) + + # buttons + self.btn_select_database_backupLocation.clicked.connect( + self.selectBackupLocation + ) + self.btn_select_database_path.clicked.connect(self.selectDatabasePath) + self.btn_select_database_name.clicked.connect(self.selectDatabaseName) + + def enableButtonBox(self): + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setEnabled( + True + ) + self.buttonBox.button( + QtWidgets.QDialogButtonBox.StandardButton.Discard + ).setEnabled(True) + + def selectBackupLocation(self): + backupLocation = QtWidgets.QFileDialog.getExistingDirectory( + self, + "Select Backup Location", + self.originalSettings.database.backupLocation, + ) + self.database_backupLocation.setText(backupLocation) + self.buttonBox.button( + QtWidgets.QDialogButtonBox.StandardButton.Discard + ).setEnabled(True) + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setEnabled( + True + ) + + def selectDatabasePath(self): + databasePath = QtWidgets.QFileDialog.getExistingDirectory( + self, "Select Database Path", self.originalSettings.database.path + ) + self.database_path.setText(databasePath) + self.buttonBox.button( + QtWidgets.QDialogButtonBox.StandardButton.Discard + ).setEnabled(True) + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setEnabled( + True + ) + + def selectDatabaseName(self): + # filepicker with filter to select only .db files if a file is selected, set name to the lineedit and set database_path + databaseName = QtWidgets.QFileDialog.getOpenFileName( + self, + "Select Database", + self.originalSettings.database.path, + "Database Files (*.db)", + ) + self.database_name.setText(databaseName[0]) + self.database_path.setText(databaseName[0].rsplit("/", 1)[0]) + self.buttonBox.button( + QtWidgets.QDialogButtonBox.StandardButton.Discard + ).setEnabled(True) + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setEnabled( + True + ) + + def saveSettings(self): + # save settings to config file + institution_name = self.institution_name.text() + default_loan_duration = int(self.default_loan_duration.text()) + database_backupLocation = self.database_backupLocation.text() + database_path = self.database_path.text() + database_name = self.database_name.text() + # overwrite the original settings + self.originalSettings.institution_name = institution_name + self.originalSettings.default_loan_duration = default_loan_duration + self.originalSettings.database.backupLocation = database_backupLocation + self.originalSettings.database.path = database_path + self.originalSettings.database.name = database_name + # save the new settings + OmegaConf.save(self.originalSettings, "config/settings.yaml") + + self.close() + + def DiscardSettings(self): + self.loadSettings() + pass + + def loadSettings(self): + self.institution_name.setText(self.originalSettings.institution_name) + self.default_loan_duration.setText( + str(self.originalSettings.default_loan_duration) + ) + self.database_backupLocation.setText( + self.originalSettings.database.backupLocation + ) + self.database_path.setText(self.originalSettings.database.path) + self.database_name.setText(self.originalSettings.database.name) + pass + + +def launch(): + import sys + + app = QtWidgets.QApplication([]) + settings = Settings() + settings.show() + sys.exit(app.exec()) diff --git a/src/ui/sources/Ui_dialog_settings.py b/src/ui/sources/Ui_dialog_settings.py new file mode 100644 index 0000000..c2745db --- /dev/null +++ b/src/ui/sources/Ui_dialog_settings.py @@ -0,0 +1,92 @@ +# Form implementation generated from reading ui file 'c:\Users\aky547\GitHub\LibrarySystem\src\ui\sources\dialog_settings.ui' +# +# Created by: PyQt6 UI code generator 6.6.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(377, 206) + self.formLayout = QtWidgets.QFormLayout(Dialog) + self.formLayout.setObjectName("formLayout") + self.label = QtWidgets.QLabel(parent=Dialog) + self.label.setObjectName("label") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label) + self.institution_name = QtWidgets.QLineEdit(parent=Dialog) + self.institution_name.setObjectName("institution_name") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.institution_name) + self.label_2 = QtWidgets.QLabel(parent=Dialog) + self.label_2.setObjectName("label_2") + self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_2) + self.default_loan_duration = QtWidgets.QLineEdit(parent=Dialog) + self.default_loan_duration.setObjectName("default_loan_duration") + self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.default_loan_duration) + self.label_3 = QtWidgets.QLabel(parent=Dialog) + self.label_3.setObjectName("label_3") + self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_3) + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + self.database_name = QtWidgets.QLineEdit(parent=Dialog) + self.database_name.setObjectName("database_name") + self.gridLayout.addWidget(self.database_name, 1, 1, 1, 1) + self.label_4 = QtWidgets.QLabel(parent=Dialog) + self.label_4.setObjectName("label_4") + self.gridLayout.addWidget(self.label_4, 0, 0, 1, 1) + self.label_6 = QtWidgets.QLabel(parent=Dialog) + self.label_6.setObjectName("label_6") + self.gridLayout.addWidget(self.label_6, 2, 0, 1, 1) + self.database_path = QtWidgets.QLineEdit(parent=Dialog) + self.database_path.setObjectName("database_path") + self.gridLayout.addWidget(self.database_path, 0, 1, 1, 1) + self.database_backupLocation = QtWidgets.QLineEdit(parent=Dialog) + self.database_backupLocation.setObjectName("database_backupLocation") + self.gridLayout.addWidget(self.database_backupLocation, 2, 1, 1, 1) + self.label_5 = QtWidgets.QLabel(parent=Dialog) + self.label_5.setObjectName("label_5") + self.gridLayout.addWidget(self.label_5, 1, 0, 1, 1) + self.btn_select_database_path = QtWidgets.QToolButton(parent=Dialog) + self.btn_select_database_path.setObjectName("btn_select_database_path") + self.gridLayout.addWidget(self.btn_select_database_path, 0, 2, 1, 1) + self.btn_select_database_name = QtWidgets.QToolButton(parent=Dialog) + self.btn_select_database_name.setObjectName("btn_select_database_name") + self.gridLayout.addWidget(self.btn_select_database_name, 1, 2, 1, 1) + self.btn_select_database_backupLocation = QtWidgets.QToolButton(parent=Dialog) + self.btn_select_database_backupLocation.setObjectName("btn_select_database_backupLocation") + self.gridLayout.addWidget(self.btn_select_database_backupLocation, 2, 2, 1, 1) + self.formLayout.setLayout(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.gridLayout) + self.buttonBox = QtWidgets.QDialogButtonBox(parent=Dialog) + self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Discard|QtWidgets.QDialogButtonBox.StandardButton.Ok) + self.buttonBox.setObjectName("buttonBox") + self.formLayout.setWidget(3, QtWidgets.QFormLayout.ItemRole.FieldRole, self.buttonBox) + + self.retranslateUi(Dialog) + self.buttonBox.accepted.connect(Dialog.accept) # type: ignore + self.buttonBox.rejected.connect(Dialog.reject) # type: ignore + QtCore.QMetaObject.connectSlotsByName(Dialog) + Dialog.setTabOrder(self.institution_name, self.default_loan_duration) + Dialog.setTabOrder(self.default_loan_duration, self.database_path) + Dialog.setTabOrder(self.database_path, self.database_name) + Dialog.setTabOrder(self.database_name, self.database_backupLocation) + Dialog.setTabOrder(self.database_backupLocation, self.btn_select_database_path) + Dialog.setTabOrder(self.btn_select_database_path, self.btn_select_database_name) + Dialog.setTabOrder(self.btn_select_database_name, self.btn_select_database_backupLocation) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Dialog")) + self.label.setText(_translate("Dialog", "Name der Einrichtung")) + self.label_2.setText(_translate("Dialog", "Leihdauer in Tagen")) + self.label_3.setText(_translate("Dialog", "Datenbank")) + self.label_4.setText(_translate("Dialog", "Speicherort")) + self.label_6.setText(_translate("Dialog", "Sicherungspfad")) + self.label_5.setText(_translate("Dialog", "Datenbankname")) + self.btn_select_database_path.setText(_translate("Dialog", "...")) + self.btn_select_database_name.setText(_translate("Dialog", "...")) + self.btn_select_database_backupLocation.setText(_translate("Dialog", "...")) diff --git a/src/ui/sources/dialog_settings.ui b/src/ui/sources/dialog_settings.ui new file mode 100644 index 0000000..cf70450 --- /dev/null +++ b/src/ui/sources/dialog_settings.ui @@ -0,0 +1,156 @@ + + + Dialog + + + + 0 + 0 + 377 + 206 + + + + Dialog + + + + + + Name der Einrichtung + + + + + + + + + + Leihdauer in Tagen + + + + + + + + + + Datenbank + + + + + + + + + + + + Speicherort + + + + + + + Sicherungspfad + + + + + + + + + + + + + Datenbankname + + + + + + + ... + + + + + + + ... + + + + + + + ... + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Discard|QDialogButtonBox::Ok + + + + + + + institution_name + default_loan_duration + database_path + database_name + database_backupLocation + btn_select_database_path + btn_select_database_name + btn_select_database_backupLocation + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/user.py b/src/ui/user.py index 2bdca97..e7aafbc 100644 --- a/src/ui/user.py +++ b/src/ui/user.py @@ -2,6 +2,8 @@ from .sources.Ui_main_userData import Ui_MainWindow from PyQt6 import QtCore, QtGui, QtWidgets from src.logic import Database from src.schemas import User +from .extendLoan import ExtendLoan +from src.utils.stringtodate import stringToDate class UserUI(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, u_name, u_no, u_mail): super(UserUI, self).__init__() @@ -11,12 +13,27 @@ class UserUI(QtWidgets.QMainWindow, Ui_MainWindow): self.userno = u_no self.usermail = u_mail self.setFields() + self.userMedia = [] + self.loadMedia() # Buttons self.btn_userChange_save.clicked.connect(self.saveChanges) self.btn_userchange_cancel.clicked.connect(self.discardChanges) + self.btn_extendSelectedMedia.clicked.connect(self.extendLoan) + + # radioButtons + self.radio_allLoanedMedia.clicked.connect(self.loadMedia) + self.radio_currentlyLoaned.clicked.connect(self.loadMedia) + self.radio_overdueLoans.clicked.connect(self.loadMedia) # frames self.frame.hide() + + # table + self.UserMediaTable.horizontalHeader().setSectionResizeMode( + QtWidgets.QHeaderView.ResizeMode.Stretch + ) + # if one or more rows is selected, enable btn + self.UserMediaTable.itemSelectionChanged.connect(self.userTableAction) # LineEdits # self.frame.hide() @@ -26,6 +43,32 @@ class UserUI(QtWidgets.QMainWindow, Ui_MainWindow): self.show() + def extendLoan(self): + extend = ExtendLoan(self.username, self.userMedia) + extend.exec() + extendDate = extend.extendDate.toString() + # print columns of selected rows + for item in self.UserMediaTable.selectedItems(): + if item.column() == 1: + signature = item.text() + print(signature) + self.db.extendLoanDuration(signature, extendDate) + self.userMedia = [] + break + self.UserMediaTable.setRowCount(0) + self.loadMedia() + + def userTableAction(self): + if self.UserMediaTable.selectedItems(): + # if any selected item has a value in column 5, disable btn + for item in self.UserMediaTable.selectedItems(): + if item.column() == 5 and item.text() != "": + self.btn_extendSelectedMedia.setEnabled(False) + return + self.btn_extendSelectedMedia.setEnabled(True) + else: + self.btn_extendSelectedMedia.setEnabled(False) + def showFrame(self): self.frame.show() @@ -39,4 +82,68 @@ class UserUI(QtWidgets.QMainWindow, Ui_MainWindow): def discardChanges(self): self.setFields() - self.frame.hide() \ No newline at end of file + self.frame.hide() + + def loadMedia(self): + mode = ( + "all" + if self.radio_allLoanedMedia.isChecked() + else "current" + if self.radio_currentlyLoaned.isChecked() + else "overdue" + ) + print(mode) + if self.userMedia == []: + books = self.db.getAllMedia(self.userno) + for book in books: + self.userMedia.append(book) + print(self.userMedia) + self.UserMediaTable.setRowCount(0) + + for book in self.userMedia: + # fromdate = stringToDate(book.loan_from) + todate = stringToDate(book.loan_to) + if mode == "current": + # book not returned + if book.returned == 0: + self.addBookToTable(book) + elif mode == "overdue": + # book not returned and todays date is greater than todate + if ( + book.returned == 0 + and QtCore.QDate.fromString(todate) > QtCore.QDate.currentDate() + ): + self.addBookToTable(book) + else: + self.addBookToTable(book) + + def addBookToTable(self, book): + self.UserMediaTable.insertRow(0) + # item0 = isbn + # item1 = signature + # item2 = title + # item3 = loan date + # item4 = return date + # item5 = returned_date + self.UserMediaTable.setItem( + 0, + 0, + QtWidgets.QTableWidgetItem(book.isbn if book.isbn != "None" else ""), + ) + self.UserMediaTable.setItem(0, 1, QtWidgets.QTableWidgetItem(book.signature)) + self.UserMediaTable.setItem(0, 2, QtWidgets.QTableWidgetItem(book.title)) + self.UserMediaTable.setItem(0, 3, QtWidgets.QTableWidgetItem(book.loan_from)) + self.UserMediaTable.setItem(0, 4, QtWidgets.QTableWidgetItem(book.loan_to)) + self.UserMediaTable.setItem( + 0, 5, QtWidgets.QTableWidgetItem(book.returned_date) + ) + + +def launch(): + import sys + + app = QtWidgets.QApplication(sys.argv) + + window = UserUI("Test", "132", "sdf@f.de") + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/src/utils/__init__.py b/src/utils/__init__.py new file mode 100644 index 0000000..afc91ca --- /dev/null +++ b/src/utils/__init__.py @@ -0,0 +1,2 @@ +from .stringtodate import stringToDate +from .icon import Icon