Bidding round control communicating with the server.

This commit is contained in:
2026-02-13 20:24:48 +01:00
parent ba4f95eb2d
commit cfd3031cf9
8 changed files with 149 additions and 11 deletions

View File

@ -574,6 +574,13 @@ void MainWindow::setupEventTab() {
m_biddingRoundControl = make_unique<BiddingRoundControl>(); m_biddingRoundControl = make_unique<BiddingRoundControl>();
containerLayout->addWidget(m_biddingRoundControl.get()); containerLayout->addWidget(m_biddingRoundControl.get());
/// requests
connect(m_biddingRoundControl.get(), &BiddingRoundControl::sendGetRequest, m_core.get(),
&GenericCore::sendGetRequest);
/// responses
connect(m_core.get(), &GenericCore::currentBiddingRoundChanged, m_biddingRoundControl.get(),
&BiddingRoundControl::onCurrentBiddingRoundChanged);
ui->tabWidget->insertTab(0, containerWidget, "Event (&1)"); ui->tabWidget->insertTab(0, containerWidget, "Event (&1)");
} }

View File

@ -27,11 +27,11 @@ BiddingRoundControl::BiddingRoundControl(QWidget* parent)
m_layout->addWidget(m_refreshRoundButton); m_layout->addWidget(m_refreshRoundButton);
connect(m_newRoundButton, &QPushButton::clicked, this, connect(m_newRoundButton, &QPushButton::clicked, this,
&BiddingRoundControl::triggerStartNewRound); &BiddingRoundControl::onStartNewRoundTriggered);
connect(m_restartRoundButton, &QPushButton::clicked, this, connect(m_restartRoundButton, &QPushButton::clicked, this,
&BiddingRoundControl::triggerRestartLastRound); &BiddingRoundControl::onRestartLastRoundTriggered);
connect(m_stopRoundButton, &QPushButton::clicked, this, connect(m_stopRoundButton, &QPushButton::clicked, this,
&BiddingRoundControl::triggerStopCurrentRound); &BiddingRoundControl::onStopCurrentRoundTriggered);
connect(m_refreshRoundButton, &QPushButton::clicked, this, connect(m_refreshRoundButton, &QPushButton::clicked, this,
&BiddingRoundControl::onRefreshCurrentRoundTriggered); &BiddingRoundControl::onRefreshCurrentRoundTriggered);
} }
@ -40,6 +40,16 @@ void BiddingRoundControl::onRefreshCurrentRoundTriggered() {
emit sendGetRequest(GetCurrentBiddingRound); emit sendGetRequest(GetCurrentBiddingRound);
} }
void BiddingRoundControl::onStartNewRoundTriggered() { emit sendGetRequest(StartNewBiddingRound); }
void BiddingRoundControl::onRestartLastRoundTriggered() {
emit sendGetRequest(RestartLastBiddingRound);
}
void BiddingRoundControl::onStopCurrentRoundTriggered() {
emit sendGetRequest(StopCurrentBiddingRound);
}
void BiddingRoundControl::onCurrentBiddingRoundChanged(int roundNumber, bool isActive) { void BiddingRoundControl::onCurrentBiddingRoundChanged(int roundNumber, bool isActive) {
QString text = QString::number(roundNumber); QString text = QString::number(roundNumber);
if (isActive) { if (isActive) {

View File

@ -23,6 +23,9 @@ class BiddingRoundControl : public QWidget {
public slots: public slots:
/// button slots /// button slots
void onRefreshCurrentRoundTriggered(); void onRefreshCurrentRoundTriggered();
void onStartNewRoundTriggered();
void onRestartLastRoundTriggered();
void onStopCurrentRoundTriggered();
/// event slots /// event slots
void onCurrentBiddingRoundChanged(int roundNumber, bool isActive); void onCurrentBiddingRoundChanged(int roundNumber, bool isActive);

View File

@ -3,6 +3,8 @@
#include <QObject> #include <QObject>
#include "model/metadata.h"
class QUndoStack; class QUndoStack;
class QAbstractItemModel; class QAbstractItemModel;
class QAbstractItemModelTester; class QAbstractItemModelTester;
@ -48,6 +50,14 @@ class GenericCore : public QObject {
signals: signals:
void displayStatusMessage(QString message); void displayStatusMessage(QString message);
/// *** server communication ***
/// request signals
void sendGetRequest(GetRequestTypes type);
/// response signals
void currentBiddingRoundChanged(int round, bool isRunning);
/// deprecated signals
void fetchItemsFromServer(); void fetchItemsFromServer();
void postItemToServer(const QByteArray& jsonData); void postItemToServer(const QByteArray& jsonData);
void deleteItemFromServer(const QString& id); void deleteItemFromServer(const QString& id);

View File

@ -83,7 +83,12 @@ static const QString ITEM_KEY_STRING = "item";
static const QString ITEMS_FILE_NAME = ITEMS_KEY_STRING + ".json"; static const QString ITEMS_FILE_NAME = ITEMS_KEY_STRING + ".json";
/// server communication /// server communication
enum GetRequestTypes { GetCurrentBiddingRound }; enum GetRequestTypes {
GetCurrentBiddingRound,
StartNewBiddingRound,
RestartLastBiddingRound,
StopCurrentBiddingRound
};
/// functions /// functions
static UserRoles GET_ROLE_FOR_COLUMN(const int column) { static UserRoles GET_ROLE_FOR_COLUMN(const int column) {

View File

@ -9,4 +9,10 @@ static const QString apiPrefix = "/api/";
static const QString ROUTE_ITEMS = apiPrefix + "items"; static const QString ROUTE_ITEMS = apiPrefix + "items";
static const QString ROUTE_BIDDINGROUNDS = apiPrefix + "bidding_rounds";
static const QString ROUTE_CURRENT_BIDDINGROUND = ROUTE_BIDDINGROUNDS + "/get_current";
static const QString ROUTE_START_BIDDINGROUND = ROUTE_BIDDINGROUNDS + "/start_new";
static const QString ROUTE_RESTART_BIDDINGROUND = ROUTE_BIDDINGROUNDS + "/restart";
static const QString ROUTE_STOP_BIDDINGROUND = ROUTE_BIDDINGROUNDS + "/stop";
#endif // APIROUTES_H #endif // APIROUTES_H

View File

@ -1,21 +1,27 @@
#include "servercommunicator.h" #include "servercommunicator.h"
#include "apiroutes.h"
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QRestAccessManager>
#include <QRestReply> #include <QRestReply>
#include "../genericcore.h"
#include "apiroutes.h"
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
ServerCommunicator::ServerCommunicator(QObject* parent) ServerCommunicator::ServerCommunicator(GenericCore* core)
: QObject{parent} { : m_core(core)
, QObject{core} {
m_netManager.setAutoDeleteReplies(true); m_netManager.setAutoDeleteReplies(true);
m_restManager = std::make_shared<QRestAccessManager>(&m_netManager); m_restManager = std::make_shared<QRestAccessManager>(&m_netManager);
m_serviceApi = std::make_shared<QNetworkRequestFactory>(); m_serviceApi = std::make_shared<QNetworkRequestFactory>();
connect(m_core, &GenericCore::sendGetRequest, this,
&ServerCommunicator::onSendGetRequestTriggered);
} }
bool ServerCommunicator::sslSupported() { bool ServerCommunicator::sslSupported() const {
#if QT_CONFIG(ssl) #if QT_CONFIG(ssl)
return QSslSocket::supportsSsl(); return QSslSocket::supportsSsl();
#else #else
@ -104,3 +110,80 @@ void ServerCommunicator::setServerConfiguration(const QString url,
m_email = email; m_email = email;
m_password = password; m_password = password;
} }
void ServerCommunicator::onSendGetRequestTriggered(const GetRequestTypes type) {
QString path;
switch (type) {
case GetCurrentBiddingRound:
path = ROUTE_CURRENT_BIDDINGROUND;
break;
case StartNewBiddingRound:
path = ROUTE_START_BIDDINGROUND;
break;
case RestartLastBiddingRound:
path = ROUTE_RESTART_BIDDINGROUND;
break;
case StopCurrentBiddingRound:
path = ROUTE_STOP_BIDDINGROUND;
break;
default:
qWarning() << "No route found for GetRequestType:" << type;
break;
}
// TODO move into default case of switch statement?
if (path.isEmpty()) {
qDebug() << "Empty path -> Not sending a request.";
return;
}
const QNetworkRequest request = m_serviceApi->createRequest(path);
m_restManager->get(request, this, [this, type](QRestReply& reply) {
if (reply.isSuccess()) {
qInfo() << "Request successful.";
const QJsonDocument doc = reply.readJson().value();
onGetReplySuccessful(type, doc);
} else {
if (reply.hasError()) {
const QString errorString = reply.errorString();
qWarning() << "Network error:" << errorString;
onGetReplyFailure(type, errorString);
} else {
int statusCode = reply.httpStatus();
qWarning() << "Request not successful:" << statusCode;
onGetReplyFailure(type, QString("HTTP status code: %1").arg(statusCode));
}
}
});
}
void ServerCommunicator::onGetReplySuccessful(const GetRequestTypes type, const QJsonDocument doc) {
switch (type) {
case GetCurrentBiddingRound:
case StartNewBiddingRound:
case RestartLastBiddingRound:
case StopCurrentBiddingRound:
currentBiddingRoundChangedReply(doc);
break;
default:
qWarning() << "Can't match request type:" << type;
break;
}
}
void ServerCommunicator::onGetReplyFailure(const GetRequestTypes type, const QString errorString) {
const QString message =
QString("Request of type %1 returned: %2").arg(QString::number(type), errorString);
m_core->displayStatusMessage(message);
}
void ServerCommunicator::currentBiddingRoundChangedReply(const QJsonDocument jsonDoc) {
qInfo() << "Current bidding round received.";
const QJsonObject rootObject = jsonDoc["data"].toObject();
const int roundNumber = rootObject["round_number"].toInt();
const bool stopped = rootObject["stopped"].toBool();
const bool isActive = !stopped;
emit m_core->currentBiddingRoundChanged(roundNumber, isActive);
}

View File

@ -1,17 +1,22 @@
#ifndef SERVERCOMMUNICATOR_H #ifndef SERVERCOMMUNICATOR_H
#define SERVERCOMMUNICATOR_H #define SERVERCOMMUNICATOR_H
#include <QJsonDocument>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkRequestFactory> #include <QNetworkRequestFactory>
#include <QObject> #include <QObject>
#include <QRestAccessManager> #include <QRestAccessManager>
#include "../model/metadata.h"
class GenericCore;
class ServerCommunicator : public QObject { class ServerCommunicator : public QObject {
Q_OBJECT Q_OBJECT
public: public:
explicit ServerCommunicator(QObject* parent = nullptr); explicit ServerCommunicator(GenericCore* core);
bool sslSupported(); bool sslSupported() const;
QUrl url() const; QUrl url() const;
void setUrl(const QUrl& url); void setUrl(const QUrl& url);
@ -19,6 +24,10 @@ class ServerCommunicator : public QObject {
void setServerConfiguration(const QString url, const QString email, const QString password); void setServerConfiguration(const QString url, const QString email, const QString password);
public slots: public slots:
void onSendGetRequestTriggered(const GetRequestTypes type);
void onGetReplySuccessful(const GetRequestTypes type, const QJsonDocument doc);
void onGetReplyFailure(const GetRequestTypes type, const QString errorString);
void fetchItems(); void fetchItems();
void postItems(const QByteArray& jsonData); void postItems(const QByteArray& jsonData);
void deleteItem(const QString& id); void deleteItem(const QString& id);
@ -34,6 +43,8 @@ class ServerCommunicator : public QObject {
void deleteRequestFailure(const QString errorString); void deleteRequestFailure(const QString errorString);
private: private:
GenericCore* m_core = nullptr;
QNetworkAccessManager m_netManager; QNetworkAccessManager m_netManager;
std::shared_ptr<QRestAccessManager> m_restManager; std::shared_ptr<QRestAccessManager> m_restManager;
std::shared_ptr<QNetworkRequestFactory> m_serviceApi; std::shared_ptr<QNetworkRequestFactory> m_serviceApi;
@ -41,6 +52,9 @@ class ServerCommunicator : public QObject {
QString m_email; QString m_email;
QString m_password; QString m_password;
// QString m_authToken; // QString m_authToken;
/// reply parser
void currentBiddingRoundChangedReply(const QJsonDocument jsonDoc);
}; };
#endif // SERVERCOMMUNICATOR_H #endif // SERVERCOMMUNICATOR_H