From 064da850c4c9e9a47de23f08052543f1f467bdf5 Mon Sep 17 00:00:00 2001 From: Bent Witthold Date: Thu, 19 Feb 2026 20:54:24 +0100 Subject: [PATCH] Clicking the sendInvite button triggers a post request to the server to send a bidding invite via mail. --- .../dialogs/edititemdialog.cpp | 2 ++ UIs/BeetRoundWidgets/dialogs/edititemdialog.h | 2 ++ UIs/BeetRoundWidgets/mainwindow.cpp | 2 ++ .../views/itemdetailmapper.cpp | 16 ++++------ UIs/BeetRoundWidgets/views/itemdetailmapper.h | 3 +- libs/BeetRoundCore/genericcore.cpp | 6 ++++ libs/BeetRoundCore/genericcore.h | 1 + libs/BeetRoundCore/model/metadata.h | 2 +- libs/BeetRoundCore/model/tablemodel.cpp | 29 +++++++++++++++++++ libs/BeetRoundCore/model/tablemodel.h | 3 ++ libs/BeetRoundCore/network/apiroutes.h | 3 ++ .../network/servercommunicator.cpp | 17 +++++++++++ .../network/servercommunicator.h | 2 ++ 13 files changed, 76 insertions(+), 12 deletions(-) diff --git a/UIs/BeetRoundWidgets/dialogs/edititemdialog.cpp b/UIs/BeetRoundWidgets/dialogs/edititemdialog.cpp index 1565f5f..1c5904e 100644 --- a/UIs/BeetRoundWidgets/dialogs/edititemdialog.cpp +++ b/UIs/BeetRoundWidgets/dialogs/edititemdialog.cpp @@ -30,6 +30,8 @@ void EditItemDialog::createContent() { /// online user stuff connect(m_detailMapper, &ItemDetailMapper::createOnlineAccountTriggered, this, &EditItemDialog::createOnlineAccountTriggered); + connect(m_detailMapper, &ItemDetailMapper::sendInviteMailTriggered, this, + &EditItemDialog::sendInviteMailTriggered); } void EditItemDialog::accept() { diff --git a/UIs/BeetRoundWidgets/dialogs/edititemdialog.h b/UIs/BeetRoundWidgets/dialogs/edititemdialog.h index ad28bfb..a76e40e 100644 --- a/UIs/BeetRoundWidgets/dialogs/edititemdialog.h +++ b/UIs/BeetRoundWidgets/dialogs/edititemdialog.h @@ -21,6 +21,8 @@ class EditItemDialog : public AbstractDialog { signals: void createOnlineAccountTriggered(const QString& mailAddress); + void sendInviteMailTriggered(const QString& mailAddress); + public slots: void accept() override; void reject() override; diff --git a/UIs/BeetRoundWidgets/mainwindow.cpp b/UIs/BeetRoundWidgets/mainwindow.cpp index ba3c9cb..9e503cc 100644 --- a/UIs/BeetRoundWidgets/mainwindow.cpp +++ b/UIs/BeetRoundWidgets/mainwindow.cpp @@ -570,4 +570,6 @@ void MainWindow::setupEventTab() { void MainWindow::initServerConnection() { connect(m_editItemDialog.get(), &EditItemDialog::createOnlineAccountTriggered, m_core.get(), &GenericCore::onCreateOnlineAccountTriggered); + connect(m_editItemDialog.get(), &EditItemDialog::sendInviteMailTriggered, m_core.get(), + &GenericCore::onSendInviteMailTriggered); } diff --git a/UIs/BeetRoundWidgets/views/itemdetailmapper.cpp b/UIs/BeetRoundWidgets/views/itemdetailmapper.cpp index 24aa4f0..07ffc44 100644 --- a/UIs/BeetRoundWidgets/views/itemdetailmapper.cpp +++ b/UIs/BeetRoundWidgets/views/itemdetailmapper.cpp @@ -165,6 +165,8 @@ ItemDetailMapper::ItemDetailMapper(QWidget* parent) connect(m_createOnlineAccountButton, &QAbstractButton::clicked, this, &ItemDetailMapper::onCreateOnlineAccountTriggered); + connect(m_sendInviteMailButton, &QAbstractButton::clicked, this, + &ItemDetailMapper::onSendInviteMailTriggered); } void ItemDetailMapper::setModelMappings(QTableView* tableView) { @@ -243,15 +245,6 @@ void ItemDetailMapper::updateButtons(int row) { m_nextButton->setEnabled(row < m_model->rowCount() - 1); } -void ItemDetailMapper::emitContentChanged(const QModelIndex& currentIndex) { - // BUG QR-Code isn't updated after changes through the ItemDetailMapper #18 - QString toStringText = ""; - if (currentIndex.isValid()) { - toStringText = currentIndex.data(ToStringRole).toString(); - } - emit contentChanged(toStringText); -} - void ItemDetailMapper::onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& /*previous*/) { if (!isEnabled()) { @@ -259,7 +252,6 @@ void ItemDetailMapper::onCurrentIndexChanged(const QModelIndex& current, } m_mapper->setCurrentModelIndex(current); updateButtons(current.row()); - emitContentChanged(current); } void ItemDetailMapper::updateQRCode(const QString text) { @@ -311,3 +303,7 @@ void ItemDetailMapper::onAccessCodeChanged(const QString& text) { void ItemDetailMapper::onCreateOnlineAccountTriggered() { emit createOnlineAccountTriggered(m_mailEdit->text()); } + +void ItemDetailMapper::onSendInviteMailTriggered() { + emit sendInviteMailTriggered(m_mailEdit->text()); +} diff --git a/UIs/BeetRoundWidgets/views/itemdetailmapper.h b/UIs/BeetRoundWidgets/views/itemdetailmapper.h index 9aa802e..6c6839c 100644 --- a/UIs/BeetRoundWidgets/views/itemdetailmapper.h +++ b/UIs/BeetRoundWidgets/views/itemdetailmapper.h @@ -31,6 +31,7 @@ class ItemDetailMapper : public QWidget { void contentChanged(const QString text); void createOnlineAccountTriggered(const QString& mailAddress); + void sendInviteMailTriggered(const QString& mailAddress); private slots: void rowsInserted(const QModelIndex& parent, int start, int end); @@ -38,7 +39,6 @@ class ItemDetailMapper : public QWidget { void toPrevious(); void toNext(); void updateButtons(int row); - void emitContentChanged(const QModelIndex& currentIndex); void onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous); void updateQRCode(const QString text = ""); @@ -46,6 +46,7 @@ class ItemDetailMapper : public QWidget { void onOnlineIDChanged(const QString& text); void onAccessCodeChanged(const QString& text); void onCreateOnlineAccountTriggered(); + void onSendInviteMailTriggered(); private: /// *** members *** diff --git a/libs/BeetRoundCore/genericcore.cpp b/libs/BeetRoundCore/genericcore.cpp index 7aaafcf..31f81d2 100644 --- a/libs/BeetRoundCore/genericcore.cpp +++ b/libs/BeetRoundCore/genericcore.cpp @@ -178,6 +178,12 @@ void GenericCore::onOnlineUserAccountReceived(const QString mailAddress, const QString message = QString("Online credentials received for: %1").arg(mailAddress); emit displayStatusMessage(message); } + +void GenericCore::onSendInviteMailTriggered(const QString& mailAddress) { + qInfo() << "Sending invite mail to:" << mailAddress; + const QString serverUrl = m_serverCommunicator->getUserLoginUrl(); + const QJsonDocument mailInviteJsonDoc = m_mainModel->getMailInviteJsonDoc(mailAddress, serverUrl); + emit sendPostRequest(MailInvite, mailInviteJsonDoc.toJson()); } void GenericCore::setupModels() { diff --git a/libs/BeetRoundCore/genericcore.h b/libs/BeetRoundCore/genericcore.h index 56300bd..45a3c89 100644 --- a/libs/BeetRoundCore/genericcore.h +++ b/libs/BeetRoundCore/genericcore.h @@ -53,6 +53,7 @@ class GenericCore : public QObject { void onOnlineUserAccountReceived(const QString mailAddress, const QString uuid, const QString accessToken); + void onSendInviteMailTriggered(const QString& mailAddress); signals: void displayStatusMessage(QString message); diff --git a/libs/BeetRoundCore/model/metadata.h b/libs/BeetRoundCore/model/metadata.h index 83ffdb9..e2de431 100644 --- a/libs/BeetRoundCore/model/metadata.h +++ b/libs/BeetRoundCore/model/metadata.h @@ -91,7 +91,7 @@ enum GetRequestTypes { GetBiddingsOfSpecificRound, GetBiddingsOfHighestRound }; -enum PostRequestTypes { RegisterUser }; +enum PostRequestTypes { RegisterUser, MailInvite }; /// functions static UserRoles GET_ROLE_FOR_COLUMN(const int column) { diff --git a/libs/BeetRoundCore/model/tablemodel.cpp b/libs/BeetRoundCore/model/tablemodel.cpp index 5447b52..efac9c7 100644 --- a/libs/BeetRoundCore/model/tablemodel.cpp +++ b/libs/BeetRoundCore/model/tablemodel.cpp @@ -239,6 +239,34 @@ void TableModel::setOnlineCredentials(const QString& mail, setItemData(itemIndex, {{OnlineIdRole, uuid}, {AccessCodeRole, token}}); } +QJsonDocument TableModel::getMailInviteJsonDoc(const QString& mail, + const QString& serverUrl) const { + QJsonDocument doc = QJsonDocument(); + + QModelIndex index = getIndexByRoleValue(mail, MailRole); + + if (index.isValid()) { + QJsonObject rootObject; + + const QString user_id = data(index, OnlineIdRole).toString(); + const QString email = data(index, MailRole).toString(); + const QString name = data(index, FullNameRole).toString(); + const QString token = data(index, AccessCodeRole).toString(); + const QString accessUrl = serverUrl + "/" + token; + + QJsonObject userObject; + userObject.insert("user_id", user_id); + userObject.insert("email", email); + userObject.insert("name", name); + userObject.insert("access_url", accessUrl); + + rootObject.insert("user", userObject); + + doc.setObject(rootObject); + } + return doc; +} + void TableModel::updateBiddings(const QList biddings) { QListIterator i(biddings); while (i.hasNext()) { @@ -352,6 +380,7 @@ qreal TableModel::biddingAverage2() const { qInfo() << "average calculation (2):" << averageBidding; return averageBidding; } + qreal TableModel::biddingAverage3() const { const UserRoles biddingRole = Bidding3Role; const qreal averageBidding = averageBiddingAmount(biddingRole); diff --git a/libs/BeetRoundCore/model/tablemodel.h b/libs/BeetRoundCore/model/tablemodel.h index 14e4f5a..5bd0011 100644 --- a/libs/BeetRoundCore/model/tablemodel.h +++ b/libs/BeetRoundCore/model/tablemodel.h @@ -46,6 +46,8 @@ class TableModel : public QAbstractTableModel { bool updateItem(const ModelItemValues& itemValues); void setOnlineCredentials(const QString& mail, const QString& uuid, const QString& token); + QJsonDocument getMailInviteJsonDoc(const QString& mail, const QString& serverUrl) const; + void updateBiddings(const QList biddings); public slots: @@ -111,6 +113,7 @@ class TableModel : public QAbstractTableModel { qreal totalSharesWithBiddings(const UserRoles biddingRole) const; QModelIndex getIndexByRoleValue(const QString& valueString, const int role) const; + QMap getItemValues(const bidding bid); }; #endif // TABLEMODEL_H diff --git a/libs/BeetRoundCore/network/apiroutes.h b/libs/BeetRoundCore/network/apiroutes.h index a89c9f5..e1ad0e8 100644 --- a/libs/BeetRoundCore/network/apiroutes.h +++ b/libs/BeetRoundCore/network/apiroutes.h @@ -5,11 +5,14 @@ // TODO add namespace +static const QString ROUTE_LOG_IN = "/log_in"; + static const QString apiPrefix = "/api/"; static const QString ROUTE_ITEMS = apiPrefix + "items"; static const QString ROUTE_REGISTER_USER = apiPrefix + "users"; +static const QString ROUTE_MAIL_INVITE = apiPrefix + "invite"; static const QString ROUTE_BIDDINGROUNDS = apiPrefix + "bidding_rounds"; static const QString ROUTE_CURRENT_BIDDINGROUND = ROUTE_BIDDINGROUNDS + "/get_current"; diff --git a/libs/BeetRoundCore/network/servercommunicator.cpp b/libs/BeetRoundCore/network/servercommunicator.cpp index cf2509f..8e672af 100644 --- a/libs/BeetRoundCore/network/servercommunicator.cpp +++ b/libs/BeetRoundCore/network/servercommunicator.cpp @@ -58,6 +58,11 @@ void ServerCommunicator::setServerConfiguration(const QString url, m_password = password; } +QString ServerCommunicator::getUserLoginUrl() const { + const QString logInUrl = m_serviceApi->baseUrl().toString() + ROUTE_LOG_IN; + return logInUrl; +} + void ServerCommunicator::onSendGetRequestTriggered(const GetRequestTypes type, QVariant data = QVariant()) { QString path; @@ -143,6 +148,9 @@ void ServerCommunicator::onSendPostRequestTriggered(const PostRequestTypes type, case RegisterUser: path = ROUTE_REGISTER_USER; break; + case MailInvite: + path = ROUTE_MAIL_INVITE; + break; default: qWarning() << "No route found for PostRequestType:" << type; break; @@ -184,6 +192,10 @@ void ServerCommunicator::onPostReplySuccessful(const PostRequestTypes type, qInfo() << "Register user successful:" << type; onlineUserAccountReply(doc); break; + case MailInvite: + qInfo() << "Mail invite successful sent:" << type; + mailInviteSentReply(doc); + break; default: qWarning() << "Can't match request type:" << type; break; @@ -228,3 +240,8 @@ void ServerCommunicator::onlineUserAccountReply(const QJsonDocument jsonDoc) { emit onlineUserAccountReceived(values[MailRole].toString(), values[OnlineIdRole].toString(), values[AccessCodeRole].toString()); } + +void ServerCommunicator::mailInviteSentReply(const QJsonDocument jsonDoc) { + qInfo() << "Invitation mail successfully sent."; + emit m_core->displayStatusMessage("Invitation mail successfully sent."); +} diff --git a/libs/BeetRoundCore/network/servercommunicator.h b/libs/BeetRoundCore/network/servercommunicator.h index 36da14b..525850d 100644 --- a/libs/BeetRoundCore/network/servercommunicator.h +++ b/libs/BeetRoundCore/network/servercommunicator.h @@ -23,6 +23,7 @@ class ServerCommunicator : public QObject { void setUrl(const QUrl& url); void setServerConfiguration(const QString url, const QString email, const QString password); + QString getUserLoginUrl() const; public slots: void onSendGetRequestTriggered(const GetRequestTypes type, QVariant data); @@ -64,6 +65,7 @@ class ServerCommunicator : public QObject { void currentBiddingRoundChangedReply(const QJsonDocument jsonDoc); void currentBiddingsReply(const QJsonDocument jsonDoc); void onlineUserAccountReply(const QJsonDocument jsonDoc); + void mailInviteSentReply(const QJsonDocument jsonDoc); }; #endif // SERVERCOMMUNICATOR_H