FINALLY DONE

This commit is contained in:
Crylia
2024-07-09 01:19:22 +02:00
parent 68b18e12e0
commit 4a475458d0
3 changed files with 129 additions and 84 deletions

View File

@@ -44,8 +44,8 @@ CREATE TABLE IF NOT EXISTS Veranstalter(
CREATE TABLE IF NOT EXISTS StundeImPlan ( CREATE TABLE IF NOT EXISTS StundeImPlan (
uhrzeit INTEGER REFERENCES Uhrzeit(ID), uhrzeit INTEGER REFERENCES Uhrzeit(ID),
tag INTEGER NOT NULL, tag INTEGER NOT NULL,
veranstaltung VARCHAR(3) REFERENCES Veranstaltung(name), veranstaltung VARCHAR(3) REFERENCES Veranstaltung(name) ON DELETE SET NULL,
veranstalter INTEGER REFERENCES Veranstalter(ID), veranstalter INTEGER REFERENCES Veranstalter(ID) ON DELETE SET NULL,
PRIMARY KEY(uhrzeit, tag) PRIMARY KEY(uhrzeit, tag)
); );
@@ -67,13 +67,11 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
-- Trigger to call the above function
CREATE TRIGGER trg_delete_stundeimplan_for_veranstaltung CREATE TRIGGER trg_delete_stundeimplan_for_veranstaltung
AFTER DELETE ON Veranstaltung AFTER DELETE ON Veranstaltung
FOR EACH ROW FOR EACH ROW
EXECUTE FUNCTION delete_stundeimplan_for_veranstaltung(); EXECUTE FUNCTION delete_stundeimplan_for_veranstaltung();
-- Function to update StundeImPlan when Veranstalter is deleted
CREATE OR REPLACE FUNCTION update_stundeimplan_for_veranstalter() CREATE OR REPLACE FUNCTION update_stundeimplan_for_veranstalter()
RETURNS TRIGGER AS $$ RETURNS TRIGGER AS $$
DECLARE DECLARE
@@ -131,16 +129,32 @@ BEGIN
FOR u_row IN SELECT * FROM Uhrzeit LOOP FOR u_row IN SELECT * FROM Uhrzeit LOOP
-- Loop through each available Veranstaltung -- Loop through each available Veranstaltung
FOR v_row IN SELECT * FROM Veranstaltung WHERE used_in_plan = 0 LOOP FOR v_row IN SELECT * FROM Veranstaltung WHERE used_in_plan = 0 LOOP
-- Find an available Veranstalter -- Find an available Veranstalter with matching ort and not scheduled in the same tag and uhrzeit
SELECT * INTO available_veranstalter SELECT * INTO available_veranstalter
FROM Veranstalter FROM Veranstalter v
WHERE arbeitszeit + v_row.dauer <= 18 WHERE v.arbeitszeit + v_row.dauer <= 18
ORDER BY arbeitszeit ASC AND NOT EXISTS (
SELECT 1
FROM StundeImPlan sp
JOIN Veranstaltung va ON sp.veranstaltung = va.name
WHERE sp.uhrzeit = u_row.ID
AND sp.tag = random_day
AND sp.veranstalter = v.ID
)
AND NOT EXISTS (
SELECT 1
FROM StundeImPlan prev_sp
JOIN Veranstaltung prev_va ON prev_sp.veranstaltung = prev_va.name
WHERE prev_sp.uhrzeit = u_row.ID - 1
AND prev_sp.tag = random_day
AND prev_sp.veranstalter = v.ID
AND prev_va.ort <> v_row.ort -- Ensure different ort for previous hour
)
ORDER BY v.arbeitszeit ASC
LIMIT 1; LIMIT 1;
IF FOUND THEN IF FOUND THEN
-- Check if there is already an event scheduled for this tag and uhrzeit combination -- Check if there is already an event scheduled for this tag and uhrzeit combination
random_day = random_between_days(); random_day = random_between_days();
IF NOT EXISTS ( IF NOT EXISTS (
SELECT 1 SELECT 1
@@ -154,6 +168,25 @@ BEGIN
-- Update the used_in_plan flag and arbeitszeit -- Update the used_in_plan flag and arbeitszeit
UPDATE Veranstaltung SET used_in_plan = used_in_plan + 1 WHERE name = v_row.name; UPDATE Veranstaltung SET used_in_plan = used_in_plan + 1 WHERE name = v_row.name;
UPDATE Veranstalter SET arbeitszeit = arbeitszeit + v_row.dauer WHERE ID = available_veranstalter.ID; UPDATE Veranstalter SET arbeitszeit = arbeitszeit + v_row.dauer WHERE ID = available_veranstalter.ID;
-- If the duration is 4, also insert for the next time slot
IF v_row.dauer = 4 THEN
-- Ensure the next time slot is within the range
IF EXISTS (SELECT 1 FROM Uhrzeit WHERE ID = u_row.ID + 1) THEN
-- Check if the next time slot is free
IF NOT EXISTS (
SELECT 1
FROM StundeImPlan
WHERE uhrzeit = u_row.ID + 1 AND tag = random_day
) THEN
INSERT INTO StundeImPlan (uhrzeit, tag, veranstaltung, veranstalter)
VALUES (u_row.ID + 1, random_day, v_row.name, available_veranstalter.ID);
-- Mark the second part as used in the plan
UPDATE Veranstaltung SET used_in_plan = used_in_plan + 1 WHERE name = v_row.name;
END IF;
END IF;
END IF;
END IF; END IF;
END IF; END IF;
END LOOP; END LOOP;
@@ -161,7 +194,6 @@ BEGIN
RETURN NEW; RETURN NEW;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE TRIGGER trg_generate_plan CREATE TRIGGER trg_generate_plan
AFTER INSERT ON Veranstaltung AFTER INSERT ON Veranstaltung
FOR EACH STATEMENT FOR EACH STATEMENT
@@ -173,7 +205,7 @@ DECLARE
new_veranstalter_id INTEGER; new_veranstalter_id INTEGER;
v_name VARCHAR(3); v_name VARCHAR(3);
BEGIN BEGIN
-- Find a new veranstalter for the same stundeImPlan -- Find the name of the Veranstaltung for the same stundeImPlan
SELECT veranstaltung.name INTO v_name SELECT veranstaltung.name INTO v_name
FROM Veranstaltung FROM Veranstaltung
WHERE name = (SELECT veranstaltung FROM StundeImPlan WHERE uhrzeit = NEW.stundeImPlan_uhrzeit AND tag = NEW.stundeImPlan_tag); WHERE name = (SELECT veranstaltung FROM StundeImPlan WHERE uhrzeit = NEW.stundeImPlan_uhrzeit AND tag = NEW.stundeImPlan_tag);
@@ -185,12 +217,12 @@ BEGIN
WHERE sp.uhrzeit = NEW.stundeImPlan_uhrzeit - 1 WHERE sp.uhrzeit = NEW.stundeImPlan_uhrzeit - 1
AND sp.tag = NEW.stundeImPlan_tag AND sp.tag = NEW.stundeImPlan_tag
) )
SELECT ID INTO new_veranstalter_id SELECT v.ID INTO new_veranstalter_id
FROM Veranstalter v FROM Veranstalter v
JOIN StundeImPlan sp ON v.ID = sp.veranstalter JOIN StundeImPlan sp ON v.ID = sp.veranstalter
JOIN Veranstaltung va ON sp.veranstaltung = va.name JOIN Veranstaltung va ON sp.veranstaltung = va.name
LEFT JOIN PreviousHour ph ON sp.uhrzeit = NEW.stundeImPlan_uhrzeit AND sp.tag = NEW.stundeImPlan_tag - 1 LEFT JOIN PreviousHour ph ON v.ID = ph.veranstalter
WHERE arbeitszeit + (SELECT dauer FROM Veranstaltung WHERE name = v_name) <= 18 WHERE v.arbeitszeit + (SELECT dauer FROM Veranstaltung WHERE name = v_name) <= 18
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 SELECT 1
FROM Krank k FROM Krank k
@@ -198,30 +230,34 @@ BEGIN
AND k.stundeImPlan_uhrzeit = NEW.stundeImPlan_uhrzeit AND k.stundeImPlan_uhrzeit = NEW.stundeImPlan_uhrzeit
AND k.stundeImPlan_tag = NEW.stundeImPlan_tag AND k.stundeImPlan_tag = NEW.stundeImPlan_tag
) )
AND (ph.veranstalter IS NULL OR v.ID <> ph.veranstalter OR va.ort = ph.ort) AND (ph.veranstalter IS NULL OR ph.veranstalter <> (
ORDER BY arbeitszeit ASC SELECT v.ID
FROM Veranstalter v
JOIN StundeImPlan sp ON v.ID = sp.veranstalter
JOIN Veranstaltung vaa ON sp.veranstaltung = vaa.name
WHERE sp.uhrzeit = NEW.stundeImPlan_uhrzeit
AND sp.tag = NEW.stundeImPlan_tag
AND vaa.ort = va.ort
))
ORDER BY v.arbeitszeit ASC
LIMIT 1; LIMIT 1;
SELECT ID INTO new_veranstalter_id -- Check if a new veranstalter was found
FROM Veranstalter v IF new_veranstalter_id IS NOT NULL THEN
WHERE arbeitszeit + (SELECT dauer FROM Veranstaltung WHERE name = v_name) <= 18 UPDATE Veranstalter
AND NOT EXISTS ( SET arbeitszeit = arbeitszeit + (SELECT dauer FROM Veranstaltung WHERE name = v_name)
SELECT 1 WHERE ID = new_veranstalter_id;
FROM Krank k
WHERE k.veranstalter = v.ID
AND k.stundeImPlan_uhrzeit = NEW.stundeImPlan_uhrzeit
AND k.stundeImPlan_tag = NEW.stundeImPlan_tag
);
-- Update the StundeImPlan with the replacement
UPDATE Veranstalter UPDATE StundeImPlan
SET arbeitszeit = arbeitszeit + (SELECT dauer FROM Veranstaltung WHERE name = v_name) SET veranstalter = new_veranstalter_id
WHERE ID = new_veranstalter_id; WHERE uhrzeit = NEW.stundeImPlan_uhrzeit AND tag = NEW.stundeImPlan_tag;
ELSE
-- Update the StundeImPlan with the replacement or NULL -- If no suitable veranstalter is found, set veranstalter to NULL
UPDATE StundeImPlan UPDATE StundeImPlan
SET veranstalter = COALESCE(new_veranstalter_id, NULL) SET veranstalter = NULL
WHERE uhrzeit = NEW.stundeImPlan_uhrzeit AND tag = NEW.stundeImPlan_tag; WHERE uhrzeit = NEW.stundeImPlan_uhrzeit AND tag = NEW.stundeImPlan_tag;
END IF;
RETURN NEW; RETURN NEW;
END; END;
@@ -232,6 +268,57 @@ AFTER INSERT ON Krank
FOR EACH ROW FOR EACH ROW
EXECUTE FUNCTION handle_krank_insert(); EXECUTE FUNCTION handle_krank_insert();
CREATE OR REPLACE FUNCTION handle_veranstalter_deletion() RETURNS TRIGGER AS $$
DECLARE
new_veranstalter RECORD;
affected_row RECORD;
BEGIN
FOR affected_row IN
SELECT * FROM StundeImPlan WHERE veranstalter = OLD.id
LOOP
-- Find a new suitable Veranstalter
SELECT * INTO new_veranstalter
FROM Veranstalter v
WHERE v.arbeitszeit + (SELECT dauer FROM Veranstaltung va WHERE va.name = affected_row.veranstaltung) <= 18
AND NOT EXISTS (
SELECT 1
FROM Krank k
WHERE k.veranstalter = v.ID
AND k.stundeImPlan_uhrzeit = affected_row.uhrzeit
AND k.stundeImPlan_tag = affected_row.tag
)
AND NOT EXISTS (
SELECT 1
FROM StundeImPlan sp
JOIN Veranstaltung va ON sp.veranstaltung = va.name
WHERE sp.uhrzeit = affected_row.uhrzeit - 1
AND sp.tag = affected_row.tag
AND sp.veranstalter = v.ID
AND va.ort <> (SELECT ort FROM Veranstaltung WHERE name = affected_row.veranstaltung)
)
AND v.ID <> affected_row.veranstalter
ORDER BY v.arbeitszeit ASC
LIMIT 1;
UPDATE StundeImPlan
SET veranstalter = new_veranstalter.ID
WHERE uhrzeit = affected_row.uhrzeit AND tag = affected_row.tag AND veranstalter = OLD.id;
UPDATE Veranstalter
SET arbeitszeit = arbeitszeit + (SELECT dauer FROM Veranstaltung WHERE name = affected_row.veranstaltung)
WHERE ID = new_veranstalter.ID;
END LOOP;
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER before_veranstalter_delete
BEFORE DELETE ON Veranstalter
FOR EACH ROW
EXECUTE FUNCTION handle_veranstalter_deletion();
INSERT INTO Uhrzeit (anfangszeit, endzeit) VALUES INSERT INTO Uhrzeit (anfangszeit, endzeit) VALUES
('08:00:00', '10:00:00'), ('08:00:00', '10:00:00'),
('10:00:00', '12:00:00'), ('10:00:00', '12:00:00'),

View File

@@ -116,53 +116,11 @@ QMap<QPair<QString, QString>, QWidget*>* PlanGridController::getVeranstaltungen(
)")); )"));
container->setFixedSize(240, 100); container->setFixedSize(240, 100);
if (infoVector.at(8) == "4") {
QFrame* container2 = new QFrame( );
container2->setObjectName("container2"); planMap->insert(qMakePair(
container2->setStyleSheet(R"( weekdays[std::stoi(infoVector.at(0)) - 1],
#container2{ QString::fromStdString(infoVector.at(1).erase(5, 8))),
background-color: #313131; container);
}
)");
auto layout2 = new QVBoxLayout(container2);
container2->setLayout(layout2);
QPushButton* widget2 = new QPushButton(QString::fromStdString(infoVector.at(4) + " - " + infoVector.at(5) + "\n" + infoVector.at(3) + infoVector.at(6)));
layout2->addWidget(widget2);
widget2->setProperty("MitarbeiterName", QString::fromStdString(infoVector.at(5)));
widget2->setProperty("MitarbeiterID", QString::fromStdString(infoVector.at(7)));
widget2->setObjectName("eintragung2");
widget2->setFixedSize(210, 70);
widget2->setToolTip(QString::fromStdString(infoVector.at(7)));
widget2->setCursor(Qt::PointingHandCursor);
layout2->setAlignment(Qt::AlignCenter);
widget2->setStyleSheet(QString::fromStdString(R"(
#eintragung2{
border: 0px solid #313131;
background-color: )" + color + R"(;
color: #212121;
font-weight: 900;
font-size: 18px;
border-radius: 8px;
}
)"));
container2->setFixedSize(240, 100);
planMap->insert(qMakePair(
weekdays[std::stoi(infoVector.at(0)) - 1],
QString::fromStdString(infoVector.at(2).erase(5, 8))),
container2);
}
planMap->insert(qMakePair(
weekdays[std::stoi(infoVector.at(0)) - 1],
QString::fromStdString(infoVector.at(1).erase(5, 8))),
container);
}
} }
return planMap; return planMap;

View File

@@ -68,7 +68,7 @@ bool DBHandler::deleteVeranstalter(const std::string& name) {
try { try {
pqxx::work W(*m_dbConnection.get( )); pqxx::work W(*m_dbConnection.get( ));
std::string query = fmt::format( std::string query = fmt::format(
"DELETE FROM Veranstalter WHERE name = {}", W.quote(name) "DELETE FROM Veranstalter WHERE id = {}", W.quote(name)
); );
W.exec(query); W.exec(query);
W.commit( ); W.commit( );
@@ -148,7 +148,7 @@ std::vector<std::string> DBHandler::getPlan( ) {
FROM StundeImPlan SIP FROM StundeImPlan SIP
JOIN Uhrzeit U ON SIP.uhrzeit = U.ID JOIN Uhrzeit U ON SIP.uhrzeit = U.ID
JOIN Veranstaltung VA ON SIP.veranstaltung = VA.name JOIN Veranstaltung VA ON SIP.veranstaltung = VA.name
JOIN Veranstalter V ON SIP.veranstalter = V.ID LEFT JOIN Veranstalter V ON SIP.veranstalter = V.ID
ORDER BY U.anfangszeit)"; ORDER BY U.anfangszeit)";
pqxx::result R(N.exec(query)); pqxx::result R(N.exec(query));
@@ -156,7 +156,7 @@ std::vector<std::string> DBHandler::getPlan( ) {
std::string entry = fmt::format( std::string entry = fmt::format(
"{},{},{},{},{},{},{},{},{}", "{},{},{},{},{},{},{},{},{}",
row["tag"].c_str( ), row["anfangszeit"].c_str( ), row["endzeit"].c_str( ), row["ort"].c_str( ), row["tag"].c_str( ), row["anfangszeit"].c_str( ), row["endzeit"].c_str( ), row["ort"].c_str( ),
row["veranstaltungsname"].c_str( ), row["veranstaltername"].c_str( ), row["raum"].c_str( ), row["veranstalter"].c_str( ), row["dauer"].c_str( ) row["veranstaltungsname"].c_str( ), row["veranstaltername"].is_null( ) ? "frei" : row["veranstaltername"].c_str( ), row["raum"].c_str( ), row["veranstalter"].c_str( ), row["dauer"].c_str( )
); );
plan.push_back(entry); plan.push_back(entry);
} }