diff --git a/.gitignore b/.gitignore index 55d0973..188f5c9 100644 --- a/.gitignore +++ b/.gitignore @@ -53,4 +53,6 @@ compile_commands.json *_qmlcache.qrc -build/ \ No newline at end of file +build +debug +config.cfg \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 6015eb1..23498f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,5 +28,6 @@ target_link_libraries(EinsatzplanQT PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Sql fmt + pqxx stdc++fs ) diff --git a/README b/README new file mode 100644 index 0000000..316fe18 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +Code written with libpqxx-version 7.4.1 +install-guide: http://en.wiki.imlint.org/Pqxx_tutorial diff --git a/assets/account-box.png b/assets/account-box.png new file mode 100644 index 0000000..d911744 Binary files /dev/null and b/assets/account-box.png differ diff --git a/assets/resources.qrc b/assets/resources.qrc new file mode 100644 index 0000000..efe227b --- /dev/null +++ b/assets/resources.qrc @@ -0,0 +1,5 @@ + + + account-box.png + + diff --git a/script.sql b/script.sql new file mode 100644 index 0000000..dc2a8b4 --- /dev/null +++ b/script.sql @@ -0,0 +1,151 @@ + +DROP VIEW studenten_veranstalter; +DROP TABLE Veranstalter_Veranstaltung_Uhrzeit; +DROP TABLE Studenten; +DROP TABLE Veranstalter; +DROP TABLE Uhrzeit; +DROP TABLE veranstaltung; +DROP SEQUENCE global_id_seq; + + + + + +CREATE SEQUENCE global_id_seq; + +CREATE TABLE Studenten ( + matrikelnummer INTEGER PRIMARY KEY DEFAULT nextval('global_id_seq'), + name VARCHAR(30) NOT NULL, + email VARCHAR(30) NOT NULL, + passwort VARCHAR(30) NOT NULL +); + + +CREATE OR REPLACE FUNCTION random_between_two() +RETURNS VARCHAR AS $$ +BEGIN + IF random() < 0.5 THEN + RETURN 'A'; + ELSE + RETURN 'B'; + END IF; +END; +$$ LANGUAGE plpgsql; + + +CREATE TABLE Veranstalter ( + ID INTEGER PRIMARY KEY DEFAULT nextval('global_id_seq'), + name VARCHAR(30), + email VARCHAR(30), + passwort VARCHAR(30), + arbeitszeit INTEGER DEFAULT 0, + standort VARCHAR(30) DEFAULT random_between_two(), + krank BOOLEAN DEFAULT FALSE, + admin BOOLEAN NOT NULL DEFAULT FALSE +); + + + + + + CREATE VIEW studenten_veranstalter AS + SELECT matrikelnummer AS id, passwort, NULL AS admin FROM Studenten + UNION ALL + SELECT ID, passwort, admin FROM Veranstalter; + + + + CREATE TABLE Veranstaltung ( + ID SERIAL PRIMARY KEY, + ort VARCHAR(30) NOT NULL, + raum INTEGER NOT NULL, + name VARCHAR(90) NOT NULL, + dauer INTEGER NOT NULL + ); + + + + + CREATE TABLE Uhrzeit ( + ID SERIAL PRIMARY KEY, + anfangszeit TIME NOT NULL, + endzeit TIME NOT NULL ); + + + + INSERT INTO Uhrzeit (anfangszeit, endzeit) VALUES + ('08:00:00', '10:00:00'), + ('10:00:00', '12:00:00'), + ('12:00:00', '14:00:00'), + ('14:00:00', '16:00:00'), + ('16:00:00', '18:00:00'); + + + CREATE TABLE Veranstalter_Veranstaltung_Uhrzeit ( + uhrzeit_ID INTEGER REFERENCES Uhrzeit(ID), + tag INTEGER NOT NULL, + veranstalter_ID INTEGER REFERENCES Veranstalter(ID), + veranstaltung_ID INTEGER REFERENCES Veranstaltung(ID), + PRIMARY KEY(uhrzeit_ID, tag) + ); + + + INSERT INTO Veranstalter (name, email, passwort, admin) VALUES + ('tech_guru', 'admin@example.com', 'password123', TRUE), +('code_master', 'user1@example.com', 'password1', FALSE), +('binary_hero', 'user2@example.com', 'password2', FALSE), +('debug_ninja', 'user3@example.com', 'password3', FALSE), +('data_wizard', 'user4@example.com', 'password4', FALSE), +('script_samurai', 'user5@example.com', 'password5', FALSE), +('dev_genius', 'user6@example.com', 'password6', FALSE), +('cyber_maven', 'user7@example.com', 'password7', FALSE), +('net_knight', 'user8@example.com', 'password8', FALSE), +('bit_boss', 'user9@example.com', 'password9', FALSE), +('sys_sensei', 'user10@example.com', 'password10', FALSE), +('crypto_champ', 'user11@example.com', 'password11', FALSE); + + + INSERT INTO Veranstaltung (ort, raum, name, dauer) VALUES + ('A', '101', 'Grundlagen der Programmierung', 2), +('B', '202', 'Algorithmen und Datenstrukturen', 4), +('A', '103', 'Netzwerkgrundlagen', 2), +('B', '204', 'Betriebssystemkonzepte', 4), +('A', '105', 'Softwareentwicklung', 2), +('B', '206', 'Intelligente Systeme', 4), +('A', '107', 'Datenbanksysteme', 2), +('B', '208', 'Webtechnologien', 2), +('A', '109', 'Computergrafikgrundlagen', 2), +('B', '210', 'Maschinelles Lernen', 2); + + +INSERT INTO Veranstalter_Veranstaltung_Uhrzeit (uhrzeit_ID, tag, veranstaltung_ID) VALUES +(1, 1, 1), +(2, 1, 7), +(3, 1, 8), +(4, 1, 3), +(5, 1, 10), + +(1, 2, 4), +(2, 2, 4), +(3, 2, 5), +(4, 2, 6), +(5, 2, 6), + +(1, 3, 7), +(2, 3, 8), +(3, 3, 9), +(4, 3, 10), +(5, 3, 1), + +(1, 4, 2), +(2, 4, 2), +(3, 4, 3), +(4, 4, 4), +(5, 4, 4), + +(1, 5, 5), +(2, 5, 6), +(3, 5, 6), +(4, 5, 7), +(5, 5, 8); + diff --git a/src/Controller/EinsatzplanFrameController/EinsatzplanFrameController.cpp b/src/Controller/EinsatzplanFrameController/EinsatzplanFrameController.cpp new file mode 100644 index 0000000..4be13af --- /dev/null +++ b/src/Controller/EinsatzplanFrameController/EinsatzplanFrameController.cpp @@ -0,0 +1,36 @@ +# include "EinsatzplanFrameController.hpp" + +EinsatzplanFrameController::EinsatzplanFrameController(QString id, bool admin) + :m_id(id), + m_admin(admin) { + const std::map config = load_config("../config.cfg"); + + m_connectionString = fmt::format( + "host={} port={} dbname={} user={} password={}", + config.at("DB_HOST"), + config.at("DB_PORT"), + config.at("DB_NAME"), + config.at("DB_USER"), + config.at("DB_PASSWORD") + ); +} + +void EinsatzplanFrameController::deleteMember(QString id) { + DBPlan* db = new DBPlan(m_connectionString); + db->deleteVeranstalter(id.toStdString( )); +} + +void EinsatzplanFrameController::deleteVeranstaltung(QString veranstaltungsname) { + DBPlan* db = new DBPlan(m_connectionString); + db->deleteVeranstaltung(veranstaltungsname.toStdString( )); +} + +void EinsatzplanFrameController::createMember(QString name, QString email, QString passwort, bool admin) { + DBPlan* db = new DBPlan(m_connectionString); + db->hinzufuegenVeranstalter(email.toStdString( ), name.toStdString( ), passwort.toStdString( ), admin ? "TRUE" : "FALSE"); +} + +void EinsatzplanFrameController::createVeranstaltung(QString name, QString raum, QString campus, QString time) { + DBPlan* db = new DBPlan(m_connectionString); + db->hinzufuegenVeranstaltung(name.toStdString( ), time.toStdString( ), campus.toStdString( ), raum.toStdString( )); +} diff --git a/src/Controller/EinsatzplanFrameController/EinsatzplanFrameController.hpp b/src/Controller/EinsatzplanFrameController/EinsatzplanFrameController.hpp new file mode 100644 index 0000000..24adef1 --- /dev/null +++ b/src/Controller/EinsatzplanFrameController/EinsatzplanFrameController.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#include "../../Core/DBHandler/DBPlan/DBPlan.hpp" +#include "../../Core/config/config.hpp" + +class EinsatzplanFrameController { +private: + std::string m_connectionString; + +protected: + QString m_id; + bool m_admin; + +public: + EinsatzplanFrameController(QString id = "0000000", bool admin = true); + void deleteMember(QString id); + void deleteVeranstaltung(QString veranstaltungsname); + void createMember(QString name, QString email, QString passwort, bool admin); + void createVeranstaltung(QString name, QString raum, QString campus, QString time); +}; diff --git a/src/Controller/PlanGridController/PlanGridController.cpp b/src/Controller/PlanGridController/PlanGridController.cpp new file mode 100644 index 0000000..939991c --- /dev/null +++ b/src/Controller/PlanGridController/PlanGridController.cpp @@ -0,0 +1,70 @@ +#include "PlanGridController.hpp" + +PlanGridController::PlanGridController( ) { + weekdays[0] = "Montag"; + weekdays[1] = "Dienstag"; + weekdays[2] = "Mittwoch"; + weekdays[3] = "Donnerstag"; + weekdays[4] = "Freitag"; + + times[0] = "8:00 - 10:00"; + times[1] = "10:00 - 12:00"; + times[2] = "12:00 - 14:00"; + times[3] = "14:00 - 16:00"; + times[4] = "16:00 - 18:00"; + + planMap = new QMap, QLabel*>( ); + + const std::map config = load_config("../config.cfg"); + + m_connectionString = fmt::format( + "host={} port={} dbname={} user={} password={}", + config.at("DB_HOST"), + config.at("DB_PORT"), + config.at("DB_NAME"), + config.at("DB_USER"), + config.at("DB_PASSWORD") + ); +} + +QMap, QLabel*>* PlanGridController::getVeranstaltungen( ) { + DBPlan* db = new DBPlan(m_connectionString); + + // stringFormat = tag , anfangszeit , Ort , Veranstaltung , Mitarbeiter , mitarbeiterID + std::vector planData = db->getPlan( ); + + QString tag; + QString anfang; + QString ort; + QString name; + QString mitarbeiter; + QString mitarbeiterId; + std::string temp; + for (const auto& veranstaltung : planData) { + std::istringstream f(veranstaltung); + std::getline(f, temp, ','); + tag.fromStdString(temp); + std::getline(f, temp, ','); + anfang.fromStdString(temp); + std::getline(f, temp, ','); + ort.fromStdString(temp); + std::getline(f, temp, ','); + name.fromStdString(temp); + std::getline(f, temp, ','); + mitarbeiter.fromStdString(temp); + std::getline(f, temp, ','); + mitarbeiterId.fromStdString(temp); + + QLabel* temp = new QLabel(name + "\n" + mitarbeiter + "\n" + ort); + temp->setObjectName("temp"); + temp->setStyleSheet(R"( + #temp{ + + } + )"); + temp->setFixedSize(240, 100); + planMap->insert(qMakePair(tag, anfang), temp); + } + + return planMap; +} diff --git a/src/Controller/PlanGridController/PlanGridController.hpp b/src/Controller/PlanGridController/PlanGridController.hpp new file mode 100644 index 0000000..ffaa293 --- /dev/null +++ b/src/Controller/PlanGridController/PlanGridController.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +#include "../../Core/config/config.hpp" +#include "../../Core/DBHandler/DBPlan/DBPlan.hpp" + +class PlanGridController { +private: + std::string m_connectionString; + +protected: + QString weekdays[5]; + QString times[5]; + QMap, QLabel*>* planMap; + +public: + PlanGridController( ); + + QMap, QLabel*>* getVeranstaltungen( ); +}; diff --git a/src/Core/DBHandler/DBHandler/DBHandler.cpp b/src/Core/DBHandler/DBHandler/DBHandler.cpp new file mode 100644 index 0000000..dd9769b --- /dev/null +++ b/src/Core/DBHandler/DBHandler/DBHandler.cpp @@ -0,0 +1,14 @@ +#include "DBHandler.hpp" + +DBHandler::DBHandler(std::string connStr) : + connectionObject(connStr.c_str( )) { + try { + if (connectionObject.is_open( )) + fmt::print("Databased connected"); + else + fmt::print("Failed to connect to Databased"); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +}; diff --git a/src/Core/DBHandler/DBHandler/DBHandler.hpp b/src/Core/DBHandler/DBHandler/DBHandler.hpp new file mode 100644 index 0000000..6c7e0b1 --- /dev/null +++ b/src/Core/DBHandler/DBHandler/DBHandler.hpp @@ -0,0 +1,13 @@ +#pragma onc + +#include +#include +#include + +class DBHandler { +protected: + pqxx::connection connectionObject; + +public: + DBHandler(std::string connStr); +}; diff --git a/src/Core/DBHandler/DBLogin/DBLogin.cpp b/src/Core/DBHandler/DBLogin/DBLogin.cpp new file mode 100644 index 0000000..2b404c9 --- /dev/null +++ b/src/Core/DBHandler/DBLogin/DBLogin.cpp @@ -0,0 +1,26 @@ +#include "DBLogin.hpp" + +DBLogin::DBLogin(std::string connStr) : DBHandler(connStr) { }; + +int DBLogin::checkValidLogin(std::string id, std::string pw) { + try { + pqxx::work worker(connectionObject); + + std::string query = + "SELECT admin FROM studenten_veranstalter WHERE id = $1 AND passwort = $2"; + + pqxx::result response = worker.exec_params(query, id, pw); + + if (response.affected_rows( ) > 0) { + if (response[0][0].is_null( )) + return 0; + return response[0][0].as( ); + } + } + catch (const std::exception& e) { + fmt::printf("ERROR: %s", e.what( )); + } + + return -1; +} + diff --git a/src/Core/DBHandler/DBLogin/DBLogin.hpp b/src/Core/DBHandler/DBLogin/DBLogin.hpp new file mode 100644 index 0000000..cf1bd7c --- /dev/null +++ b/src/Core/DBHandler/DBLogin/DBLogin.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +#include "../DBHandler/DBHandler.hpp" + +class DBLogin : public DBHandler { +public: + DBLogin(std::string connStr); + + /** + * @brief Tries to login the user + * @param id user id + * @param pw user password + * @return returns 1 if admin and 0 if not + */ + int checkValidLogin(std::string id, std::string pw); +}; diff --git a/src/Core/DBHandler/DBPlan/DBPlan.cpp b/src/Core/DBHandler/DBPlan/DBPlan.cpp new file mode 100644 index 0000000..622da2f --- /dev/null +++ b/src/Core/DBHandler/DBPlan/DBPlan.cpp @@ -0,0 +1,376 @@ +#include "DBPlan.hpp" + +DBPlan::DBPlan(std::string connStr) : DBHandler(connStr) { }; + +void DBPlan::vertretung(std::string tag, std::string stunde, std::string dauer) { + try { + std::string prevStunde = std::to_string(std::stoi(stunde) - 1); + std::string cap = std::to_string(18 - std::stoi(dauer)); + std::string nextStunde; + std::string nextTag = tag; + std::string prevTag = tag; + if (dauer == "4") + nextStunde = std::to_string(std::stoi(stunde) + 2); + else + nextStunde = std::to_string(std::stoi(stunde) + 1); + fmt::print(nextStunde); + + if (prevStunde == "0") { + prevStunde = "5"; + prevTag = std::to_string(std::stoi(tag) - 1); + if (prevTag == "0") + prevTag = "5"; + } + + if (nextStunde == "6") { + nextStunde = "1"; + nextTag = std::to_string(std::stoi(tag) + 1); + if (nextTag == "6") + nextTag = "1"; + } + + pqxx::work worker(connectionObject); + + std::string query = R"( + UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = + (SELECT ID FROM Veranstalter WHERE ID != (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2) + AND ID != (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $3 AND tag = $4) LIMIT 1) WHERE uhrzeit_id = $5 AND tag = $6; )"; + + worker.exec_params(query, prevStunde, prevTag, nextStunde, nextTag, stunde, tag); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::sucheVertretung(std::string tag, std::string stunde) { + std::string dauer = getDauer(tag, stunde); + vertretung(tag, stunde, dauer); + incarbeitszeit(tag, stunde, dauer); + + if (dauer == "4") + upperHour(tag, stunde); +} + +void DBPlan::meldeKrank(std::string id, std::string tag, std::string stunde) { + try { + pqxx::work worker(connectionObject); + + worker.exec_params("UPDATE Veranstalter SET krank = TRUE WHERE ID = $1", id); + worker.commit( ); + + sucheVertretung(tag, stunde); + meldeGesund(id); + versendeEmails( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::meldeGesund(std::string id) { + try { + pqxx::work worker(connectionObject); + + worker.exec_params("UPDATE Veranstalter SET krank = FALSE WHERE ID = $1", id); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::deleteVeranstalterForeign(std::string id) { + try { + pqxx::work worker(connectionObject); + + worker.exec_params("UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = NULL WHERE Veranstalter_ID = $1;", id); + worker.commit( ); + versendeEmails( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::deleteVeranstalter(std::string id) { + deleteVeranstalterForeign(id); + + try { + pqxx::work worker(connectionObject); + + worker.exec_params("DELETE FROM Veranstalter WHERE ID = $1", id); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::deleteVeranstaltungForeign(std::string id) { + try { + pqxx::work worker(connectionObject); + + worker.exec_params("UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstaltung_ID = NULL WHERE Veranstalter_ID = $1;", id); + worker.commit( ); + versendeEmails( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::deleteVeranstaltung(std::string id) { + deleteVeranstaltungForeign(id); + + try { + pqxx::work worker(connectionObject); + + worker.exec_params("DELETE FROM Veranstaltung WHERE ID = $1", id); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::hinzufuegenVeranstaltung(std::string name, std::string dauer, std::string ort, std::string raum) { + try { + pqxx::work worker(connectionObject); + worker.exec_params("INSERT INTO Veranstaltung (name, dauer, ort, raum) VALUES ($1, $2, $3, $4);", name, dauer, ort, raum); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::hinzufuegenVeranstalter(std::string email, std::string name, std::string pw, std::string admin) { + try { + pqxx::work worker(connectionObject); + + worker.exec_params("INSERT INTO Veranstalter (email, name, passwort, admin) VALUES ($1, $2, $3, $4);", email, name, pw, admin); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::deleteStudent(std::string id) { + try { + pqxx::work worker(connectionObject); + + worker.exec_params("DELETE FROM studenten WHERE ID = $1;", id); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::hinzufuegenStudent(std::string email, std::string name, std::string pw) { + try { + pqxx::work worker(connectionObject); + + worker.exec_params("INSERT INTO studenten (email, name, pw) VALUES ($1, $2, $3);", email, name, pw); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +std::string DBPlan::getDauer(std::string tag, std::string stunde) { + try { + pqxx::work worker(connectionObject); + + pqxx::result response = worker.exec_params( + "SELECT dauer FROM Veranstaltung WHERE ID = (SELECT Veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2);", + stunde, + tag + ); + + worker.commit( ); + return response[0][0].c_str( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } + return "0"; +} + +void DBPlan::addFirstOfDayTwo(std::string tag) { + try { + pqxx::work worker(connectionObject); + std::string query = + R"(UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = (SELECT ID FROM Veranstalter WHERE arbeitszeit <= 16 AND krank = FALSE LIMIT 1) + WHERE uhrzeit_id = 1 AND tag = $1;)"; + worker.exec_params(query, tag); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::addTwoHour(std::string tag, std::string stunde) { + try { + std::string prevStunde = std::to_string(std::stoi(stunde) - 1); + + fmt::printf("PrevStunde: %s\n Tag: %s\n Stunde: %s \n", prevStunde, tag, stunde); + pqxx::work worker(connectionObject); + std::string query = + R"(UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_id = (SELECT ID FROM Veranstalter + WHERE arbeitszeit <= 16 AND krank = FALSE + AND(standort = (SELECT ort FROM Veranstaltung WHERE ID = (SELECT veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) + AND ID != (SELECT veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) + ORDER BY random() LIMIT 1) + WHERE uhrzeit_id = $3 AND tag = $4;)"; + worker.exec_params(query, prevStunde, tag, stunde, tag); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::addFirstOfDayFour(std::string tag) { + try { + pqxx::work worker(connectionObject); + std::string query = + R"(UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = (SELECT ID FROM Veranstalter WHERE arbeitszeit <= 14 AND krank = FALSE LIMIT 1) + WHERE uhrzeit_id = 1 AND tag = $1;)"; + worker.exec_params(query, tag); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::addFourHour(std::string tag, std::string stunde) { + try { + std::string prevStunde = std::to_string(std::stoi(stunde) - 1); + pqxx::work worker(connectionObject); + std::string query = + R"(UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_id = (SELECT ID FROM Veranstalter + WHERE arbeitszeit <= 14 AND krank = FALSE + AND(standort = (SELECT ort FROM Veranstaltung WHERE ID = (SELECT veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) + AND ID != (SELECT veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) + ORDER BY random() LIMIT 1) + WHERE uhrzeit_id = $3 AND tag = $4;)"; + worker.exec_params(query, prevStunde, tag, stunde, tag); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::upperHour(std::string tag, std::string stunde) { + try { + std::string nextStunde = std::to_string(std::stoi(stunde) + 1); + + pqxx::work worker(connectionObject); + std::string query = + R"(UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2) + WHERE uhrzeit_id = $3 AND tag = $2;)"; + worker.exec_params(query, stunde, tag, nextStunde); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::updateStandort(std::string tag, std::string stunde) { + try { + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter SET standort = (SELECT ort FROM Veranstaltung WHERE ID = (SELECT Veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) WHERE ID = (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2);"; + worker.exec_params(query, stunde, tag); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::incarbeitszeit(std::string tag, std::string stunde, std::string amount) { + try { + pqxx::work worker(connectionObject); + + std::string query = + "UPDATE Veranstalter SET arbeitszeit = arbeitszeit + $1 WHERE ID = (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $2 AND tag = $3);"; + + worker.exec_params(query, amount, stunde, tag); + worker.commit( ); + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +void DBPlan::createPlan( ) { + try { + for (int tag = 1; tag < 6; tag++) { + std::string tagStr = std::to_string(tag); + for (int stunde = 1; stunde < 6; stunde++) { + std::string stundeStr = std::to_string(stunde); + //get dauer of next class + + if (std::stoi(getDauer(tagStr, stundeStr)) == 2) { + stunde == 1 ? addFirstOfDayTwo(tagStr) : addTwoHour(tagStr, stundeStr); + updateStandort(tagStr, stundeStr); + incarbeitszeit(tagStr, stundeStr, "2"); + } else { + stunde == 1 ? addFirstOfDayFour(tagStr) : addFourHour(tagStr, stundeStr); + upperHour(tagStr, stundeStr); + incarbeitszeit(tagStr, stundeStr, "4"); + updateStandort(tagStr, stundeStr); + stunde++; + } + } + } + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } +} + +std::vector DBPlan::getPlan( ) { + try { + std::vector plan; + + pqxx::work worker(connectionObject); + + std::string query = + R"(SELECT tag, u.anfangszeit, u.endzeit, o.ort, o.name, v.name, v.ID FROM Veranstalter_Veranstaltung_Uhrzeit LEFT JOIN Veranstalter v ON Veranstalter_Veranstaltung_Uhrzeit.veranstalter_ID = v.ID + LEFT JOIN Uhrzeit u ON Veranstalter_Veranstaltung_Uhrzeit.uhrzeit_ID = u.ID + LEFT JOIN Veranstaltung o ON Veranstalter_Veranstaltung_Uhrzeit.veranstaltung_ID = o.ID + ORDER BY tag, uhrzeit_ID;)"; + + pqxx::result response = worker.exec(query); + worker.commit( ); + + for (const auto& row : response) { + std::string rowstring; + for (const auto& col : row) { + rowstring.append(col.c_str( )); + rowstring.append(" , "); + } + plan.push_back(rowstring); + } + return plan; + } + catch (const std::exception& e) { + fmt::print(e.what( )); + } + return std::vector{ "" }; +} + +void DBPlan::versendeEmails( ) { + fmt::print("Der Einsatzplan wurde geändert"); +} diff --git a/src/Core/DBHandler/DBPlan/DBPlan.hpp b/src/Core/DBHandler/DBPlan/DBPlan.hpp new file mode 100644 index 0000000..4877f0a --- /dev/null +++ b/src/Core/DBHandler/DBPlan/DBPlan.hpp @@ -0,0 +1,107 @@ +#pragma once + +#include +#include +#include + +#include "../DBHandler/DBHandler.hpp" + +class DBPlan : public DBHandler { +private: + //Functions needed for creation and updating of the plan + std::string getDauer(std::string tag, std::string stunde); + void addFirstOfDayTwo(std::string tag); + void addTwoHour(std::string tag, std::string stunde); + void addFirstOfDayFour(std::string tag); + void upperHour(std::string tag, std::string stunde); + void addFourHour(std::string tag, std::string stunde); + void sucheVertretung(std::string tag, std::string stunde); + void vertretung(std::string tag, std::string stunde, std::string dauer); + void deleteVeranstalterForeign(std::string id); + void deleteVeranstaltungForeign(std::string id); + void updateStandort(std::string tag, std::string stunde); + void incarbeitszeit(std::string tag, std::string stunde, std::string amount); + void versendeEmails( ); + +public: + DBPlan(std::string connStr); + + /** + * @brief Deletes prof from plan and searches new one + * + * @param id + * @param tag + * @param stunde + */ + void meldeKrank(std::string id, std::string tag, std::string stunde); + + /** + * @brief Currently directly used after meldeKrank, so Mitarbeiter is only sick for specific hour + * + * @param id + */ + void meldeGesund(std::string id); + + /** + * @brief Deletes Veranstaltung from relation Veranstaltung and from Einsatzplan + * + * @param id + */ + void deleteVeranstaltung(std::string id); + + /** + * @brief Adds Veranstaltung to relation Veranstaltung + * + * @param name + * @param dauer + * @param ort + * @param raum + */ + void hinzufuegenVeranstaltung(std::string name, std::string dauer, std::string ort, std::string raum); + + /** + * @brief Deletes Veranstlater from relattion Veranstalter and from Einsatzplan + * + * @param id + */ + void deleteVeranstalter(std::string id); + + /** + * @brief Add Veranstalter to relation Veranstalter + * + * @param email + * @param name + * @param pw + * @param admin + */ + void hinzufuegenVeranstalter(std::string email, std::string name, std::string pw, std::string admin); + + /** + * @brief Deletes a student from the database + * + * @param id + */ + void deleteStudent(std::string id); + + /** + * @brief Adds a new student + * + * @param email + * @param name + * @param pw + */ + void hinzufuegenStudent(std::string email, std::string name, std::string pw); + + /** + * @brief Create a Plan object + * + */ + void createPlan( ); + + /** + * @brief Each string in form of (tag , anfangszeit , endzeit , Ort , Veranstaltung , Mitarbeiter , mitarbeiterID , ) + * + * @return std::vector + */ + std::vector getPlan( ); +}; diff --git a/src/Core/config/config.hpp b/src/Core/config/config.hpp new file mode 100644 index 0000000..a611ddd --- /dev/null +++ b/src/Core/config/config.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include +#include + +inline static const std::map& load_config(const std::string& filename) { + static std::map config; + static bool is_loaded{ false }; + static std::string fn{ "" }; + + if (!is_loaded || fn != filename) { + std::ifstream file(filename); + std::string line; + + while (std::getline(file, line)) { + std::istringstream line_stream(line); + std::string key; + if (std::getline(line_stream, key, '=')) { + std::string value; + if (std::getline(line_stream, value)) { + config[key] = value; + } + } + } + + is_loaded = true; + fn = filename; + } + return config; +} diff --git a/src/View/EinsatzplanFrame/Dialogs/CreateMember/CreateMember.cpp b/src/View/EinsatzplanFrame/Dialogs/CreateMember/CreateMember.cpp new file mode 100644 index 0000000..0dcbaae --- /dev/null +++ b/src/View/EinsatzplanFrame/Dialogs/CreateMember/CreateMember.cpp @@ -0,0 +1,137 @@ +#include "CreateMember.hpp" + +CreateMemDialog::CreateMemDialog(QWidget* parent) + :QDialog(parent) { + setWindowTitle("Mitarbeiter Hinzufügen"); + setFixedSize(300, 400); + setObjectName("CreateMemDialog"); + setStyleSheet(R"( + #CreateMemDialog{ + background-color: #212121; + border: none; + } + )"); + + m_name = new QLineEdit(this); + m_name->setPlaceholderText("Name"); + m_name->setFixedSize(220, 40); + m_name->setObjectName("name"); + m_name->setStyleSheet(R"( + #name{ + color: #DADADA; + font-size: 16px; + background-color: #313131; + border-radius: 10px; + padding: 5px; + border: 2px solid #414141; + } + )"); + m_name->show( ); + + + m_email = new QLineEdit(this); + m_email->setPlaceholderText("Email"); + m_email->setFixedSize(220, 40); + m_email->setObjectName("email"); + m_email->setStyleSheet(R"( + #email{ + color: #DADADA; + font-size: 16px; + background-color: #313131; + border-radius: 10px; + padding: 5px; + border: 2px solid #414141; + } + )"); + m_email->show( ); + + m_password = new QLineEdit(this); + m_password->setPlaceholderText("Passwort"); + m_password->setEchoMode(QLineEdit::Password); + m_password->setFixedSize(220, 40); + m_password->setObjectName("password"); + m_password->setStyleSheet(R"( + #password{ + color: #DADADA; + font-size: 16px; + background-color: #313131; + border-radius: 10px; + padding: 5px; + border: 2px solid #414141; + } + )"); + m_password->show( ); + + m_admin = new QCheckBox("Admin", this); + m_admin->setFixedSize(220, 40); + m_admin->setObjectName("admin"); + m_admin->setStyleSheet(R"( + #admin{ + color: #DADADA; + font-size: 20px; + border: none; + } + )"); + m_admin->show( ); + + QVBoxLayout* layout = new QVBoxLayout(this); + + layout->setContentsMargins(30, 30, 30, 30); + + layout->addWidget(m_name, 1, Qt::AlignCenter); + layout->addWidget(m_email, 1, Qt::AlignCenter); + layout->addWidget(m_password, 1, Qt::AlignCenter); + layout->addWidget(m_admin, 1, Qt::AlignCenter); + + QHBoxLayout* buttonLayout = new QHBoxLayout( ); + + m_okButton = new QPushButton("OK", this); + m_okButton->setFixedSize(110, 40); + m_okButton->setObjectName("okButton"); + m_okButton->setStyleSheet(R"( + #okButton{ + color: #212121; + font-size: 16px; + font-weight: bold; + background-color: #53EC87; + border-radius: 10px; + } + )"); + + m_cancelButton = new QPushButton("Abbrechen", this); + m_cancelButton->setFixedSize(110, 40); + m_cancelButton->setObjectName("cancelButton"); + m_cancelButton->setStyleSheet(R"( + #cancelButton{ + color: #212121; + font-size: 16px; + font-weight: bold; + background-color: #FF5555; + border-radius: 10px; + } + )"); + + buttonLayout->addWidget(m_okButton, 1, Qt::AlignCenter); + buttonLayout->addWidget(m_cancelButton, 1, Qt::AlignCenter); + + layout->addLayout(buttonLayout); + + connect(m_okButton, &QPushButton::clicked, this, &QDialog::accept); + connect(m_cancelButton, &QPushButton::clicked, this, &QDialog::reject); +} + +QString CreateMemDialog::getName( ) const { + return m_name->text( ); +} + +QString CreateMemDialog::getEmail( ) const { + return m_email->text( ); +} + +QString CreateMemDialog::getPassword( ) const { + return m_password->text( ); +} + +bool CreateMemDialog::isAdmin( ) const { + return m_admin->isChecked( ); +} diff --git a/src/View/EinsatzplanFrame/Dialogs/CreateMember/CreateMember.hpp b/src/View/EinsatzplanFrame/Dialogs/CreateMember/CreateMember.hpp new file mode 100644 index 0000000..182f836 --- /dev/null +++ b/src/View/EinsatzplanFrame/Dialogs/CreateMember/CreateMember.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include +#include +#include + +class CreateMemDialog : public QDialog { + Q_OBJECT +protected: + QLineEdit* m_name; + QLineEdit* m_email; + QLineEdit* m_password; + QCheckBox* m_admin; + QPushButton* m_okButton; + QPushButton* m_cancelButton; + +public: + CreateMemDialog(QWidget* parent = nullptr); + + QString getName( ) const; + QString getEmail( ) const; + QString getPassword( ) const; + bool isAdmin( ) const; +}; diff --git a/src/View/EinsatzplanFrame/Dialogs/CreateVeranstaltung/CreateVeranstaltung.cpp b/src/View/EinsatzplanFrame/Dialogs/CreateVeranstaltung/CreateVeranstaltung.cpp new file mode 100644 index 0000000..2a7a143 --- /dev/null +++ b/src/View/EinsatzplanFrame/Dialogs/CreateVeranstaltung/CreateVeranstaltung.cpp @@ -0,0 +1,141 @@ +#include "CreateVeranstaltung.hpp" + +CreateVerDialog::CreateVerDialog(QWidget* parent) + : QDialog(parent) { + setWindowTitle("Veranstaltung Hinzufügen"); + setFixedSize(300, 400); + setObjectName("createMemDialog"); + setStyleSheet(R"( + #createMemDialog{ + background-color: #212121; + border: none; + } + )"); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setContentsMargins(30, 30, 30, 30); + + m_name = new QLineEdit(this); + m_name->setPlaceholderText("Veranstaltungskürzel"); + m_name->setFixedSize(220, 40); + m_name->setObjectName("name"); + m_name->setStyleSheet(R"( + #name{ + color: #DADADA; + font-size: 16px; + background-color: #313131; + border-radius: 10px; + padding: 5px; + border: 2px solid #414141; + } + )"); + layout->addWidget(m_name, 1, Qt::AlignCenter); + + m_raum = new QLineEdit(this); + m_raum->setPlaceholderText("Raum"); + m_raum->setFixedSize(220, 40); + m_raum->setObjectName("raum"); + m_raum->setStyleSheet(R"( + #raum{ + color: #DADADA; + font-size: 16px; + background-color: #313131; + border-radius: 10px; + padding: 5px; + border: 2px solid #414141; + } + )"); + layout->addWidget(m_raum, 1, Qt::AlignCenter); + + m_campus = new QComboBox(this); + m_campus->addItem("Campus A"); + m_campus->addItem("Campus B"); + m_campus->setFixedSize(220, 40); + m_campus->setObjectName("campus"); + m_campus->setStyleSheet(R"( + #campus{ + color: #DADADA; + font-size: 16px; + background-color: #313131; + border-radius: 10px; + padding: 5px; + } + #campus::Item{ + color: #DADADA; + background-color: #313131; + } + )"); + layout->addWidget(m_campus, 1, Qt::AlignCenter); + + m_time = new QComboBox(this); + m_time->addItem("2h"); + m_time->addItem("4h"); + m_time->setFixedSize(220, 40); + m_time->setObjectName("time"); + m_time->setStyleSheet(R"( + #time{ + color: #DADADA; + font-size: 16px; + background-color: #313131; + border-radius: 10px; + padding: 5px; + } + #time::Item{ + color: #DADADA; + background-color: #313131; + } + )"); + layout->addWidget(m_time, 1, Qt::AlignCenter); + + QHBoxLayout* buttonLayout = new QHBoxLayout( ); + + m_okButton = new QPushButton("OK", this); + m_okButton->setFixedSize(110, 40); + m_okButton->setObjectName("okButton"); + m_okButton->setStyleSheet(R"( + #okButton{ + color: #212121; + font-size: 16px; + font-weight: bold; + background-color: #53EC87; + border-radius: 10px; + } + )"); + + m_cancelButton = new QPushButton("Abbrechen", this); + m_cancelButton->setFixedSize(110, 40); + m_cancelButton->setObjectName("cancelButton"); + m_cancelButton->setStyleSheet(R"( + #cancelButton{ + color: #212121; + font-size: 16px; + font-weight: bold; + background-color: #FF5555; + border-radius: 10px; + } + )"); + + buttonLayout->addWidget(m_okButton, 1, Qt::AlignCenter); + buttonLayout->addWidget(m_cancelButton, 1, Qt::AlignCenter); + + layout->addLayout(buttonLayout, 1); + + connect(m_okButton, &QPushButton::clicked, this, &QDialog::accept); + connect(m_cancelButton, &QPushButton::clicked, this, &QDialog::reject); +} + +QString CreateVerDialog::getName( ) const { + return m_name->text( ); +} + +QString CreateVerDialog::getRaum( ) const { + return m_raum->text( ); +} + +QString CreateVerDialog::getCampus( ) const { + return m_campus->currentText( ); +} + +QString CreateVerDialog::getTime( ) const { + return m_time->currentText( ); +} diff --git a/src/View/EinsatzplanFrame/Dialogs/CreateVeranstaltung/CreateVeranstaltung.hpp b/src/View/EinsatzplanFrame/Dialogs/CreateVeranstaltung/CreateVeranstaltung.hpp new file mode 100644 index 0000000..50e666a --- /dev/null +++ b/src/View/EinsatzplanFrame/Dialogs/CreateVeranstaltung/CreateVeranstaltung.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include +#include + +class CreateVerDialog : public QDialog { + Q_OBJECT +protected: + QLineEdit* m_name; + QLineEdit* m_raum; + + QComboBox* m_campus; + QComboBox* m_time; + + QPushButton* m_okButton; + QPushButton* m_cancelButton; + +public: + CreateVerDialog(QWidget* parent = nullptr); + + QString getName( ) const; + QString getRaum( ) const; + QString getCampus( ) const; + QString getTime( ) const; +}; diff --git a/src/View/EinsatzplanFrame/EinsatzplanFrame.cpp b/src/View/EinsatzplanFrame/EinsatzplanFrame.cpp new file mode 100644 index 0000000..267c769 --- /dev/null +++ b/src/View/EinsatzplanFrame/EinsatzplanFrame.cpp @@ -0,0 +1,229 @@ +#include "EinsatzplanFrame.hpp" + +EinsatzplanFrame::EinsatzplanFrame(QWidget* parent, QString id, bool admin) + :QFrame(parent) { + setFrameStyle(QFrame::Box); + setObjectName("einsatzplanFrame"); + setStyleSheet(R"( + #einsatzplanFrame{ + background-color: #212121; + border: none; + } + )"); + + m_controller = new EinsatzplanFrameController(id, admin); + + m_profileImg = new QLabel(this); + m_profileImg->setFixedSize(60, 60); + m_profileImg->setPixmap(QPixmap(":account-box.png")); + m_profileImg->setObjectName("profileImg"); + m_profileImg->setStyleSheet(R"( + #profileImg{ + + } + )"); + m_profileImg->show( ); + + m_id = new QLabel(id, this); + m_id->setFixedSize(122, 80); + m_id->setObjectName("id"); + m_id->setStyleSheet(R"( + #id{ + font-size: 24px; + color: #d8d8d8; + font-weight: bold; + } + )"); + m_id->show( ); + + m_abmeldenButton = new QPushButton("Abmelden", this); + m_abmeldenButton->setFixedSize(150, 50); + m_abmeldenButton->setObjectName("abmeldenButton"); + m_abmeldenButton->setStyleSheet(R"( + #abmeldenButton{ + font-size: 24px; + font-weight: bold; + color: #212121; + background-color: #E0894A; + border-radius: 10px; + } + #abmeldenButton:pressed{ + background-color: #D0793A; + } + )"); + m_abmeldenButton->show( ); + + //implement logoutButton functionality + connect(m_abmeldenButton, &QPushButton::clicked, this, &EinsatzplanFrame::abmelden); + + m_einsatzplanLabel = new QLabel("Einsatzplan", this); + m_einsatzplanLabel->setFixedSize(645, 80); + m_einsatzplanLabel->setAlignment(Qt::AlignCenter); + m_einsatzplanLabel->setObjectName("einsatzplanLabel"); + m_einsatzplanLabel->setStyleSheet(R"( + #einsatzplanLabel{ + font-size:40px; + color: #7FF; + font-weight: bold; + } + )"); + m_einsatzplanLabel->show( ); + + m_planGrid = new PlanGrid(this); + m_planGrid->show( ); + + QVBoxLayout* totalLayout = new QVBoxLayout(this); + totalLayout->setContentsMargins(30, 20, 30, 20); + + QHBoxLayout* topLayout = new QHBoxLayout( ); + topLayout->addWidget(m_profileImg, 0, Qt::AlignLeft); + topLayout->addSpacing(10); + topLayout->addWidget(m_id, 0, Qt::AlignLeft); + topLayout->addWidget(m_einsatzplanLabel, 4, Qt::AlignCenter); + topLayout->addWidget(m_abmeldenButton, 0, Qt::AlignRight); + + QHBoxLayout* bottomLayout = new QHBoxLayout( ); + bottomLayout->addWidget(m_planGrid, 1, Qt::AlignCenter); + + //make bottomLayout bigger then topLayout + totalLayout->addLayout(topLayout, 1); + totalLayout->addLayout(bottomLayout, 4); + + if (!admin) { return; } + + m_createMemberButton = new QPushButton("Mitarbeiter\nHinzufügen", this); + m_createMemberButton->setFixedSize(200, 50); + m_createMemberButton->setObjectName("createMember"); + m_createMemberButton->setStyleSheet(R"( + #createMember{ + font-size: 16px; + font-weight: bold; + background-color: #DCFF78; + color: #212121; + border-radius: 10px; + } + #createMember:pressed{ + background-color: #CCEF68; + } + )"); + m_createMemberButton->show( ); + + //implement createMemberButton functionality + connect(m_createMemberButton, &QPushButton::clicked, this, &EinsatzplanFrame::createMember); + + m_deleteMemberButton = new QPushButton("Mitarbeiter\nEntfernen", this); + m_deleteMemberButton->setFixedSize(200, 50); + m_deleteMemberButton->setObjectName("deleteMember"); + m_deleteMemberButton->setStyleSheet(R"( + #deleteMember{ + font-size: 16px; + font-weight: bold; + background-color: #DCFF78; + color: #212121; + border-radius: 10px; + } + #deleteMember:pressed{ + background-color: #CCEF68; + } + )"); + m_deleteMemberButton->show( ); + + //implement deleteMemberButton functionality + connect(m_deleteMemberButton, &QPushButton::clicked, this, &EinsatzplanFrame::deleteMember); + + m_createVeranstaltungButton = new QPushButton("Veranstaltung\nHinzufügen", this); + m_createVeranstaltungButton->setFixedSize(200, 50); + m_createVeranstaltungButton->setObjectName("createVeranstaltung"); + m_createVeranstaltungButton->setStyleSheet(R"( + #createVeranstaltung{ + font-size: 16px; + font-weight: bold; + background-color: #DCFF78; + color: #212121; + border-radius: 10px; + } + #createVeranstaltung:pressed{ + background-color: #CCEF68; + } + )"); + m_createVeranstaltungButton->show( ); + + //implement createVeranstaltungButton functionality + connect(m_createVeranstaltungButton, &QPushButton::clicked, this, &EinsatzplanFrame::createVeranstaltung); + + m_deleteVeranstaltungButton = new QPushButton("Veranstaltung\nEntfernen", this); + m_deleteVeranstaltungButton->setFixedSize(200, 50); + m_deleteVeranstaltungButton->setObjectName("deleteVeranstaltung"); + m_deleteVeranstaltungButton->setStyleSheet(R"( + #deleteVeranstaltung{ + font-size: 16px; + font-weight: bold; + background-color: #DCFF78; + color: #212121; + border-radius: 10px; + } + #deleteVeranstaltung:pressed{ + background-color: #CCEF68; + } + )"); + m_deleteVeranstaltungButton->show( ); + + //implement deleteVeranstaltungButton functionality + connect(m_deleteVeranstaltungButton, &QPushButton::clicked, this, &EinsatzplanFrame::deleteVeranstaltung); + + QHBoxLayout* adminLayout = new QHBoxLayout( ); + adminLayout->addWidget(m_createMemberButton, 1, Qt::AlignLeft); + adminLayout->addWidget(m_deleteMemberButton, 1, Qt::AlignLeft); + adminLayout->addStretch(1); + adminLayout->addWidget(m_createVeranstaltungButton, 1, Qt::AlignRight); + adminLayout->addWidget(m_deleteVeranstaltungButton, 1, Qt::AlignRight); + + totalLayout->addLayout(adminLayout); +} + +void EinsatzplanFrame::abmelden( ) { + static_cast(parent( )->parent( ))->exit( ); +} + +void EinsatzplanFrame::deleteVeranstaltung( ) { + bool ok; + QString text = QInputDialog::getText(this, tr("Veranstaltung Entfernen"), + tr("Bitte geben sie den Veranstaltungskürzel ein:"), QLineEdit::Normal, + "", &ok); + (ok && text.size( ) == 3) ? + QMessageBox::information(this, "Veranstaltung Entfernen", "Veranstaltungskürzel besteht aus 3 Zeichen!") : + QMessageBox::information(this, "Veranstaltung entfernen", "Veranstaltung wird entfernt!"); +} + +void EinsatzplanFrame::createVeranstaltung( ) { + CreateVerDialog dialog(this); + if (dialog.exec( ) == QDialog::Accepted) { + QString name = dialog.getName( ); + QString raum = dialog.getRaum( ); + QString campus = dialog.getCampus( ); + QString time = dialog.getTime( ); + m_controller->createVeranstaltung(name, raum, campus, time); + } +} + +void EinsatzplanFrame::deleteMember( ) { + bool ok; + QString text = QInputDialog::getText(this, tr("Mitarbeiter Entfernen"), + tr("Bitte geben sie die Mitarbeiter ID ein:"), QLineEdit::Normal, + "", &ok); + + (ok && text.size( ) == 7) ? + QMessageBox::information(this, "Mitarbeiter entfernen", "Mitarbeiter wird entfernt!") : + QMessageBox::information(this, "Mitarbeiter Entfernen", "Mitarbeiter ID besteht aus 7 Zahlen!"); +} + +void EinsatzplanFrame::createMember( ) { + CreateMemDialog dialog(this); + if (dialog.exec( ) == QDialog::Accepted) { + QString name = dialog.getName( ); + QString email = dialog.getEmail( ); + QString password = dialog.getPassword( ); + bool isAdmin = dialog.isAdmin( ); + m_controller->createMember(name, email, password, isAdmin); + } +} diff --git a/src/View/EinsatzplanFrame/EinsatzplanFrame.hpp b/src/View/EinsatzplanFrame/EinsatzplanFrame.hpp new file mode 100644 index 0000000..673af1b --- /dev/null +++ b/src/View/EinsatzplanFrame/EinsatzplanFrame.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../PlanGrid/PlanGrid.hpp" +#include "../../Controller/EinsatzplanFrameController/EinsatzplanFrameController.hpp" +#include "Dialogs/CreateMember/CreateMember.hpp" +#include "Dialogs/CreateVeranstaltung/CreateVeranstaltung.hpp" + +class EinsatzplanFrame : public QFrame { + Q_OBJECT +protected: + EinsatzplanFrameController* m_controller; + + QLabel* m_profileImg; + QLabel* m_id; + QLabel* m_einsatzplanLabel; + + PlanGrid* m_planGrid; + + QPushButton* m_abmeldenButton; + QPushButton* m_createMemberButton; + QPushButton* m_deleteMemberButton; + QPushButton* m_createVeranstaltungButton; + QPushButton* m_deleteVeranstaltungButton; + +public: + EinsatzplanFrame(QWidget* parent = nullptr, QString id = "0000000", bool admin = true); + +private slots: + + void abmelden( ); + void deleteVeranstaltung( ); + void createVeranstaltung( ); + void deleteMember( ); + void createMember( ); +}; diff --git a/src/View/EinsatzplanWindow/EinsatzplanWindow.cpp b/src/View/EinsatzplanWindow/EinsatzplanWindow.cpp new file mode 100644 index 0000000..f4296a9 --- /dev/null +++ b/src/View/EinsatzplanWindow/EinsatzplanWindow.cpp @@ -0,0 +1,8 @@ +#include "EinsatzplanWindow.hpp" + +EinsatzplanWindow::EinsatzplanWindow(QWidget* parent, QString id, bool admin) + :QMainWindow(parent) { + m_frame = new EinsatzplanFrame(this, id, admin); + setFixedSize(1400, 800); + m_frame->setFixedSize(size( )); +} diff --git a/src/View/EinsatzplanWindow/EinsatzplanWindow.hpp b/src/View/EinsatzplanWindow/EinsatzplanWindow.hpp new file mode 100644 index 0000000..0e88b96 --- /dev/null +++ b/src/View/EinsatzplanWindow/EinsatzplanWindow.hpp @@ -0,0 +1,12 @@ +# pragma once +# include +# include "../EinsatzplanFrame/EinsatzplanFrame.hpp" + +class EinsatzplanWindow : public QMainWindow { + Q_OBJECT +private: + EinsatzplanFrame* m_frame; + +public: + EinsatzplanWindow(QWidget* parent = nullptr, QString id = "0000000", bool admin = true); +}; diff --git a/src/View/PlanGrid/PlanGrid.cpp b/src/View/PlanGrid/PlanGrid.cpp new file mode 100644 index 0000000..2f94475 --- /dev/null +++ b/src/View/PlanGrid/PlanGrid.cpp @@ -0,0 +1,122 @@ +#include "PlanGrid.hpp" + +PlanGrid::PlanGrid(QWidget* parent) + :QWidget(parent) { + setObjectName("PlanGrid"); + setStyleSheet(R"( + QWidget{ + background-color: #313131; + border: 2px solid #414141; + } + )"); + + m_weekdays[0] = "Montag"; + m_weekdays[1] = "Dienstag"; + m_weekdays[2] = "Mittwoch"; + m_weekdays[3] = "Donnerstag"; + m_weekdays[4] = "Freitag"; + + m_times[0] = "8:00 - 10:00"; + m_times[1] = "10:00 - 12:00"; + m_times[2] = "12:00 - 14:00"; + m_times[3] = "14:00 - 16:00"; + m_times[4] = "16:00 - 18:00"; + + planMap = new QMap, QLabel*>( ); + + gridLayout = new QGridLayout(this); + + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 5; ++j) { + QLabel* temp = new QLabel( ); + temp->setObjectName("temp"); + temp->setStyleSheet(R"( + #temp{ + + } + )"); + temp->setFixedSize(240, 100); + planMap->insert(qMakePair(m_weekdays[i], m_times[j]), temp); + } + + populateGrid( ); + + QLabel* temp = new QLabel( ); + temp->setObjectName("temp"); + temp->setStyleSheet(R"( + #temp{ + border-top-left-radius: 10px; + } + )"); + temp->setFixedSize(130, 80); + gridLayout->addWidget(temp, 0, 0); + + for (int i = 0; i < 5; i++) { + QLabel* temp = new QLabel(m_weekdays[i]); + temp->setFixedSize(240, 80); + temp->setObjectName("temp"); + if (i == 4) { + temp->setStyleSheet(R"( + #temp{ + font-size: 24px; + font-weight: bold; + border-top-right-radius: 10px; + color: #d8d8d8; + } + )"); + } else { + temp->setStyleSheet(R"( + #temp{ + font-size: 24px; + font-weight: bold; + color: #d8d8d8; + } + )"); + } + temp->setAlignment(Qt::AlignCenter); + gridLayout->addWidget(temp, 0, i + 1); + } + + for (int i = 0; i < 5; i++) { + QLabel* temp = new QLabel(m_times[i]); + temp->setFixedSize(130, 100); + temp->setObjectName("temp"); + if (i == 4) { + temp->setStyleSheet(R"( + #temp{ + font-size: 16px; + font-weight: bold; + border-bottom-left-radius: 10px; + color: #d8d8d8; + } + )"); + } else { + temp->setStyleSheet(R"( + #temp{ + font-size: 16px; + font-weight: bold; + color: #d8d8d8; + } + )"); + } + temp->setAlignment(Qt::AlignCenter); + gridLayout->addWidget(temp, i + 1, 0); + } + + gridLayout->setSpacing(0); + setLayout(gridLayout); +} + +void PlanGrid::populateGrid( ) { + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; ++j) { + gridLayout->addWidget(planMap->value(qMakePair(m_weekdays[i], m_times[j])), j + 1, i + 1); + if (i == 4 && j == 4) { + (planMap->value(qMakePair(m_weekdays[i], m_times[j])))->setStyleSheet(R"( + border-bottom-right-radius:10px; + )"); + } + } + } +} + diff --git a/src/View/PlanGrid/PlanGrid.hpp b/src/View/PlanGrid/PlanGrid.hpp new file mode 100644 index 0000000..f69a57d --- /dev/null +++ b/src/View/PlanGrid/PlanGrid.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include + +#include "../../Controller/PlanGridController/PlanGridController.hpp" +#include "../Widgets/GridItem.hpp" + +class PlanGrid : public QWidget { + Q_OBJECT +private: + QString m_weekdays[5]; + QString m_times[5]; + + void populateGrid( ); + +protected: + QGridLayout* gridLayout; + QMap, QLabel*>* planMap; + +public: + PlanGrid(QWidget* parent = nullptr); +}; diff --git a/src/View/Widgets/GridItem.cpp b/src/View/Widgets/GridItem.cpp new file mode 100644 index 0000000..605aa10 --- /dev/null +++ b/src/View/Widgets/GridItem.cpp @@ -0,0 +1,19 @@ +# include "GridItem.hpp" + +GridItem::GridItem(QString text, QWidget* parent) + :QLabel(parent) { + //Fix later + //text_m = new QLabel(text,this); + //text_m->setAlignment(Qt::AlignCenter); + setText(text); +} + +void GridItem::mousePressEvent(QMouseEvent* event) { + if (event->button( ) == Qt::RightButton) + emit clicked( ); + QWidget::mousePressEvent(event); +} + +void GridItem::paintEvent(QPaintEvent* event) { + +} diff --git a/src/View/Widgets/GridItem.hpp b/src/View/Widgets/GridItem.hpp new file mode 100644 index 0000000..116035a --- /dev/null +++ b/src/View/Widgets/GridItem.hpp @@ -0,0 +1,17 @@ +# pragma once +# include +# include +# include + +class GridItem : public QLabel { + Q_OBJECT +protected: + //QLabel* text_m; + + void mousePressEvent(QMouseEvent* event) override; + void paintEvent(QPaintEvent* event) override; +public: + GridItem(QString text = "", QWidget* parent = nullptr); +signals: + void clicked( ); +}; diff --git a/src/main.cpp b/src/main.cpp index 7e239ab..313560f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ # include + # include "View/LoginWindow/LoginWindow.hpp" int main(int argc, char* argv[]){ @@ -6,4 +7,4 @@ int main(int argc, char* argv[]){ LoginWindow* loginWindow = new LoginWindow(); loginWindow->show(); return app.exec(); -} \ No newline at end of file +}