diff --git a/UIs/BeetRoundWidgets/CMakeLists.txt b/UIs/BeetRoundWidgets/CMakeLists.txt index 8c97104..1e558a0 100644 --- a/UIs/BeetRoundWidgets/CMakeLists.txt +++ b/UIs/BeetRoundWidgets/CMakeLists.txt @@ -36,6 +36,7 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) views/itemdetailmapper.h views/itemdetailmapper.cpp widgets/comboboxdelegate.h widgets/comboboxdelegate.cpp widgets/spinboxdelegate.h widgets/spinboxdelegate.cpp + widgets/biddingroundcontrol.h widgets/biddingroundcontrol.cpp ) # Define target properties for Android with Qt 6 as: # set_property(TARGET ${TARGET_APP} APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR diff --git a/UIs/BeetRoundWidgets/mainwindow.cpp b/UIs/BeetRoundWidgets/mainwindow.cpp index 5b3985f..1fb23d4 100644 --- a/UIs/BeetRoundWidgets/mainwindow.cpp +++ b/UIs/BeetRoundWidgets/mainwindow.cpp @@ -17,6 +17,7 @@ #include "model/generalsortfiltermodel.h" #include "model/metadata.h" #include "model/tablemodel.h" +#include "widgets/biddingroundcontrol.h" #include "widgets/comboboxdelegate.h" #include "widgets/spinboxdelegate.h" @@ -70,6 +71,8 @@ MainWindow::MainWindow(QWidget* parent) onSelectionChanged(QItemSelection(), QItemSelection()); onCurrentChanged(QModelIndex(), QModelIndex()); + + setupEventTab(); } MainWindow::~MainWindow() { delete ui; } @@ -176,11 +179,6 @@ void MainWindow::on_actionCheck_for_update_triggered() { } } -void MainWindow::on_pushButton_clicked() { - const QString prefix("Backend provided by: "); - ui->label->setText(prefix + m_core->toString()); -} - void MainWindow::openNewItemDialog() { showStatusMessage(tr("Invoked 'Edit|New Item'")); m_newItemDialog->show(); @@ -300,24 +298,9 @@ void MainWindow::findItems() { } } -void MainWindow::fetchItems() { - showStatusMessage(tr("Invoked 'Server|Fetch items'")); - emit m_core->fetchItemsFromServer(); -} - -void MainWindow::postItems() { - showStatusMessage(tr("Invoked 'Server|Post items'")); - const QModelIndex currentIndex = ui->tableView->currentIndex(); - const QByteArray jsonData = m_proxyModel->jsonDataForServer(currentIndex); - emit m_core->postItemToServer(jsonData); -} - -void MainWindow::deleteItem() { - showStatusMessage(tr("Invoked 'Server|Delete items'")); - const QModelIndex currentIndex = ui->tableView->currentIndex(); - // const QByteArray jsonData = m_proxyModel->jsonDataForServer(currentIndex); - const QString currentId = m_proxyModel->getUuid(currentIndex); - emit m_core->deleteItemFromServer(currentId); +void MainWindow::fetchCurrentBiddings() { + showStatusMessage(tr("Invoked 'Server|Fetch current biddings'")); + emit m_core->sendGetRequest(GetBiddingsOfHighestRound); } void MainWindow::execSettingsDialog() { @@ -522,25 +505,12 @@ void MainWindow::createEditActions() { } void MainWindow::createServerActions() { - m_fetchItemsAct = make_unique(tr("&Fetch item(s)"), this); - m_fetchItemsAct->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_Down)); - m_fetchItemsAct->setStatusTip(tr("Fetches all item on configured server")); - connect(m_fetchItemsAct.get(), &QAction::triggered, this, &MainWindow::fetchItems); - ui->menu_Server->addAction(m_fetchItemsAct.get()); - - m_postItemsAct = make_unique(tr("&Post item(s)"), this); - m_postItemsAct->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_Up)); - // m_postItemsAct->setStatusTip(tr("Posts the selected items on configured server")); - m_postItemsAct->setStatusTip(tr("Posts the current item on configured server")); - connect(m_postItemsAct.get(), &QAction::triggered, this, &MainWindow::postItems); - ui->menu_Server->addAction(m_postItemsAct.get()); - - m_deleteItemsAct = make_unique(tr("&Delete item"), this); - m_deleteItemsAct->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_Backspace)); - // m_deleteItemsAct->setStatusTip(tr("Deletes the selected items on configured server")); - m_deleteItemsAct->setStatusTip(tr("Deletes the current item on configured server")); - connect(m_deleteItemsAct.get(), &QAction::triggered, this, &MainWindow::deleteItem); - ui->menu_Server->addAction(m_deleteItemsAct.get()); + m_fetchCurrentBiddingsAct = make_unique(tr("&Fetch biddings"), this); + m_fetchCurrentBiddingsAct->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_Down)); + m_fetchCurrentBiddingsAct->setStatusTip(tr("Fetches all biddings of the current round")); + connect(m_fetchCurrentBiddingsAct.get(), &QAction::triggered, this, + &MainWindow::fetchCurrentBiddings); + ui->menu_Server->addAction(m_fetchCurrentBiddingsAct.get()); } void MainWindow::createToolsActions() { @@ -569,3 +539,20 @@ void MainWindow::createGuiDialogs() { m_editItemDialog = make_unique(ui->tableView, this); m_editItemDialog->createContent(); } + +void MainWindow::setupEventTab() { + QWidget* containerWidget = new QWidget(); + QVBoxLayout* containerLayout = new QVBoxLayout(containerWidget); + m_biddingRoundControl = make_unique(); + 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)"); +} diff --git a/UIs/BeetRoundWidgets/mainwindow.h b/UIs/BeetRoundWidgets/mainwindow.h index b8f9949..75f610d 100644 --- a/UIs/BeetRoundWidgets/mainwindow.h +++ b/UIs/BeetRoundWidgets/mainwindow.h @@ -19,6 +19,7 @@ class TableModel; class GeneralSortFilterModel; class NewItemDialog; class EditItemDialog; +class BiddingRoundControl; using namespace std; @@ -44,8 +45,6 @@ class MainWindow : public QMainWindow { void onAboutClicked(); void on_actionCheck_for_update_triggered(); - void on_pushButton_clicked(); - /// slots for menu actions void openNewItemDialog(); void openEditItemDialog(); @@ -64,9 +63,7 @@ class MainWindow : public QMainWindow { void findItems(); /// 'Server' slots - void fetchItems(); - void postItems(); - void deleteItem(); + void fetchCurrentBiddings(); /// 'Tools' slots void execSettingsDialog(); @@ -78,7 +75,7 @@ class MainWindow : public QMainWindow { shared_ptr m_proxyModel; QUndoStack* m_modelUndoStack; unique_ptr m_modelUndoView; - + unique_ptr m_biddingRoundControl; /// File actions unique_ptr m_newFileAct; unique_ptr m_openAct; @@ -98,9 +95,7 @@ class MainWindow : public QMainWindow { unique_ptr m_deleteItemAct; unique_ptr m_findItemAct; /// Server actions - unique_ptr m_fetchItemsAct; - unique_ptr m_postItemsAct; - unique_ptr m_deleteItemsAct; + unique_ptr m_fetchCurrentBiddingsAct; /// View actions unique_ptr m_showModelUndoViewAct; @@ -119,5 +114,7 @@ class MainWindow : public QMainWindow { void createToolsActions(); void createHelpMenu(); void createGuiDialogs(); + + void setupEventTab(); }; #endif // MAINWINDOW_H diff --git a/UIs/BeetRoundWidgets/mainwindow.ui b/UIs/BeetRoundWidgets/mainwindow.ui index d32d7f5..86e34b6 100644 --- a/UIs/BeetRoundWidgets/mainwindow.ui +++ b/UIs/BeetRoundWidgets/mainwindow.ui @@ -14,22 +14,22 @@ GenericQtClient - - - - - - - - Push the button! - - - - - - - Button + + + + + 0 + + + Mitglieder (&2) + + + + + + + diff --git a/UIs/BeetRoundWidgets/widgets/biddingroundcontrol.cpp b/UIs/BeetRoundWidgets/widgets/biddingroundcontrol.cpp new file mode 100644 index 0000000..71dfbe1 --- /dev/null +++ b/UIs/BeetRoundWidgets/widgets/biddingroundcontrol.cpp @@ -0,0 +1,67 @@ +#include "biddingroundcontrol.h" + +#include +#include +#include + +BiddingRoundControl::BiddingRoundControl(QWidget* parent) + : QWidget{parent} { + m_layout = new QHBoxLayout(this); + m_title = new QLabel("Bidding round control:"); + m_status = new QLabel("(No round started yet.)"); + + m_newRoundButton = new QPushButton("Start new round"); + m_restartRoundButton = new QPushButton("Restart last round"); + m_stopRoundButton = new QPushButton("Stop round"); + m_refreshRoundButton = new QPushButton("Refresh"); + + m_newRoundButton->setEnabled(false); + m_restartRoundButton->setEnabled(false); + m_stopRoundButton->setEnabled(false); + + m_layout->addWidget(m_title); + m_layout->addWidget(m_status); + m_layout->addWidget(m_newRoundButton); + m_layout->addWidget(m_restartRoundButton); + m_layout->addWidget(m_stopRoundButton); + m_layout->addWidget(m_refreshRoundButton); + + connect(m_newRoundButton, &QPushButton::clicked, this, + &BiddingRoundControl::onStartNewRoundTriggered); + connect(m_restartRoundButton, &QPushButton::clicked, this, + &BiddingRoundControl::onRestartLastRoundTriggered); + connect(m_stopRoundButton, &QPushButton::clicked, this, + &BiddingRoundControl::onStopCurrentRoundTriggered); + connect(m_refreshRoundButton, &QPushButton::clicked, this, + &BiddingRoundControl::onRefreshCurrentRoundTriggered); +} + +void BiddingRoundControl::onRefreshCurrentRoundTriggered() { + 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) { + QString text = QString::number(roundNumber); + if (isActive) { + text.append(" (active)"); + m_newRoundButton->setEnabled(false); + m_restartRoundButton->setEnabled(false); + m_stopRoundButton->setEnabled(true); + } else { + text.append(" (stopped)"); + m_newRoundButton->setEnabled(true); + m_restartRoundButton->setEnabled(roundNumber > 0); + m_stopRoundButton->setEnabled(false); + } + m_status->setText(text); +} diff --git a/UIs/BeetRoundWidgets/widgets/biddingroundcontrol.h b/UIs/BeetRoundWidgets/widgets/biddingroundcontrol.h new file mode 100644 index 0000000..ee64bf1 --- /dev/null +++ b/UIs/BeetRoundWidgets/widgets/biddingroundcontrol.h @@ -0,0 +1,39 @@ +#ifndef BIDDINGROUNDCONTROL_H +#define BIDDINGROUNDCONTROL_H + +#include +#include "model/metadata.h" + +class QPushButton; +class QLabel; +class QHBoxLayout; +class BiddingRoundControl : public QWidget { + Q_OBJECT + public: + explicit BiddingRoundControl(QWidget* parent = nullptr); + + signals: + void sendGetRequest(GetRequestTypes type, QVariant data = QVariant()); + + public slots: + /// button slots + void onRefreshCurrentRoundTriggered(); + void onStartNewRoundTriggered(); + void onRestartLastRoundTriggered(); + void onStopCurrentRoundTriggered(); + + /// event slots + void onCurrentBiddingRoundChanged(int roundNumber, bool isActive); + + private: + QHBoxLayout* m_layout = nullptr; + QLabel* m_title = nullptr; + QLabel* m_status = nullptr; + + QPushButton* m_newRoundButton = nullptr; + QPushButton* m_restartRoundButton = nullptr; + QPushButton* m_stopRoundButton = nullptr; + QPushButton* m_refreshRoundButton = nullptr; +}; + +#endif // BIDDINGROUNDCONTROL_H diff --git a/UIs/BeetRoundWidgets/widgets/comboboxdelegate.h b/UIs/BeetRoundWidgets/widgets/comboboxdelegate.h index 59a03c3..a79b5d8 100644 --- a/UIs/BeetRoundWidgets/widgets/comboboxdelegate.h +++ b/UIs/BeetRoundWidgets/widgets/comboboxdelegate.h @@ -2,9 +2,10 @@ #define COMBOBOXDELEGATE_H #include - class QStringListModel; + class ComboboxDelegate : public QStyledItemDelegate { + // TODO move source code files into subfolder "widgets/delegate" Q_OBJECT public: explicit ComboboxDelegate(const QStringList items, QObject* parent = nullptr); diff --git a/UIs/BeetRoundWidgets/widgets/spinboxdelegate.h b/UIs/BeetRoundWidgets/widgets/spinboxdelegate.h index 1016640..a5e9920 100644 --- a/UIs/BeetRoundWidgets/widgets/spinboxdelegate.h +++ b/UIs/BeetRoundWidgets/widgets/spinboxdelegate.h @@ -4,6 +4,7 @@ #include class SpinboxDelegate : public QStyledItemDelegate { + // TODO move source code files into subfolder "widgets/delegate" Q_OBJECT public: explicit SpinboxDelegate(QObject* parent = nullptr); diff --git a/libs/BeetRoundCore/CMakeLists.txt b/libs/BeetRoundCore/CMakeLists.txt index 11492df..fcda6a6 100644 --- a/libs/BeetRoundCore/CMakeLists.txt +++ b/libs/BeetRoundCore/CMakeLists.txt @@ -23,19 +23,20 @@ add_library(${TARGET_APP} STATIC genericcore.h ${TS_FILES} constants.h + structs.h data/settingshandler.h data/settingshandler.cpp + data/filehandler.h data/filehandler.cpp + formats/jsonparser.h formats/jsonparser.cpp + formats/csvparser.h formats/csvparser.cpp + model/metadata.h model/tablemodel.h model/tablemodel.cpp model/modelitem.h model/modelitem.cpp - formats/jsonparser.h formats/jsonparser.cpp + model/generalsortfiltermodel.h model/generalsortfiltermodel.cpp model/commands/insertrowscommand.h model/commands/insertrowscommand.cpp model/commands/removerowscommand.h model/commands/removerowscommand.cpp model/commands/edititemcommand.h model/commands/edititemcommand.cpp - data/filehandler.h data/filehandler.cpp - model/metadata.h - formats/csvparser.h formats/csvparser.cpp - model/generalsortfiltermodel.h model/generalsortfiltermodel.cpp - network/servercommunicator.h network/servercommunicator.cpp network/apiroutes.h + network/servercommunicator.h network/servercommunicator.cpp # 3rd party libraries ../3rdParty/rapidcsv/src/rapidcsv.h ) diff --git a/libs/BeetRoundCore/genericcore.cpp b/libs/BeetRoundCore/genericcore.cpp index 6403ea5..3942fc0 100644 --- a/libs/BeetRoundCore/genericcore.cpp +++ b/libs/BeetRoundCore/genericcore.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "../../ApplicationConfig.h" #include "CoreConfig.h" @@ -19,8 +20,6 @@ #include "model/tablemodel.h" #include "network/servercommunicator.h" -#include - using namespace std; GenericCore::GenericCore() { @@ -155,36 +154,9 @@ bool GenericCore::isSyncServerSetup() const { } } -void GenericCore::onSendItemTriggered(const QByteArray& jsonData) { - m_serverCommunicator->postItems(jsonData); -} - -void GenericCore::onItemsFetched(const QByteArray jsonData) { - emit displayStatusMessage("New items fetched."); - // TODO ? check compability of JSON structure beforehand? - // NEXT check if item already exists and apply changes (UUID,...) ? ; - m_mainModel->appendItems(jsonData); -} - -void GenericCore::onItemsFetchFailure(const QString errorString) { - emit displayStatusMessage(QString("Error: %1").arg(errorString)); -} - -void GenericCore::onPostRequestSuccessful(const QByteArray responseData) { - const QString message = m_mainModel->updateItemsFromJson(responseData); - emit displayStatusMessage(message); -} - -void GenericCore::onPostRequestFailure(const QString errorString) { - emit displayStatusMessage(QString("Error: %1").arg(errorString)); -} - -void GenericCore::onDeleteRequestSuccessful(const QByteArray responseData) { - qWarning() << "TODO: Process success response!!!"; -} - -void GenericCore::onDeleteRequestFailure(const QString errorString) { - qWarning() << "TODO: Process error response!!!"; +void GenericCore::onBiddingsChanged(int round, QList biddings) { + qInfo() << "onBiddingsChanged: round:" << round << "- biddings:" << biddings.count(); + // NEXT merge biddings into model } void GenericCore::setupModels() { @@ -246,27 +218,6 @@ QString GenericCore::getMaintenanceToolFilePath() const { void GenericCore::setupServerConfiguration() { m_serverCommunicator = make_unique(this); - /// request connections - connect(this, &GenericCore::fetchItemsFromServer, m_serverCommunicator.get(), - &ServerCommunicator::fetchItems); - connect(this, &GenericCore::postItemToServer, this, &GenericCore::onSendItemTriggered); - connect(this, &GenericCore::deleteItemFromServer, m_serverCommunicator.get(), - &ServerCommunicator::deleteItem); - - /// response connections - connect(m_serverCommunicator.get(), &ServerCommunicator::itemsFetched, this, - &GenericCore::onItemsFetched); - connect(m_serverCommunicator.get(), &ServerCommunicator::itemsFetchFailure, this, - &GenericCore::onItemsFetchFailure); - connect(m_serverCommunicator.get(), &ServerCommunicator::postRequestSuccessful, this, - &GenericCore::onPostRequestSuccessful); - connect(m_serverCommunicator.get(), &ServerCommunicator::postRequestFailure, this, - &GenericCore::onPostRequestFailure); - connect(m_serverCommunicator.get(), &ServerCommunicator::deleteRequestSuccessful, this, - &GenericCore::onDeleteRequestSuccessful); - connect(m_serverCommunicator.get(), &ServerCommunicator::deleteRequestFailure, this, - &GenericCore::onDeleteRequestFailure); - applyServerConfiguration(); } diff --git a/libs/BeetRoundCore/genericcore.h b/libs/BeetRoundCore/genericcore.h index 4bf30ea..9df744b 100644 --- a/libs/BeetRoundCore/genericcore.h +++ b/libs/BeetRoundCore/genericcore.h @@ -2,6 +2,10 @@ #define GENERICCORE_H #include +#include + +#include "model/metadata.h" +#include "structs.h" class QUndoStack; class QAbstractItemModel; @@ -38,16 +42,18 @@ class GenericCore : public QObject { bool isSyncServerSetup() const; public slots: - void onSendItemTriggered(const QByteArray& jsonData); - void onItemsFetched(const QByteArray jsonData); - void onItemsFetchFailure(const QString errorString); - void onPostRequestSuccessful(const QByteArray responseData); - void onPostRequestFailure(const QString errorString); - void onDeleteRequestSuccessful(const QByteArray responseData); - void onDeleteRequestFailure(const QString errorString); + void onBiddingsChanged(int round, QList biddings); signals: void displayStatusMessage(QString message); + + /// *** server communication *** + /// request signals + void sendGetRequest(GetRequestTypes type, QVariant data = QVariant()); + /// response signals + void currentBiddingRoundChanged(int round, bool isRunning); + + /// deprecated signals void fetchItemsFromServer(); void postItemToServer(const QByteArray& jsonData); void deleteItemFromServer(const QString& id); diff --git a/libs/BeetRoundCore/model/metadata.h b/libs/BeetRoundCore/model/metadata.h index 435511b..dbbe9c0 100644 --- a/libs/BeetRoundCore/model/metadata.h +++ b/libs/BeetRoundCore/model/metadata.h @@ -82,6 +82,16 @@ static const QString ITEM_KEY_STRING = "item"; /// file naming static const QString ITEMS_FILE_NAME = ITEMS_KEY_STRING + ".json"; +/// server communication +enum GetRequestTypes { + GetCurrentBiddingRound, + StartNewBiddingRound, + RestartLastBiddingRound, + StopCurrentBiddingRound, + GetBiddingsOfSpecificRound, + GetBiddingsOfHighestRound +}; + /// functions static UserRoles GET_ROLE_FOR_COLUMN(const int column) { switch (column) { diff --git a/libs/BeetRoundCore/network/apiroutes.h b/libs/BeetRoundCore/network/apiroutes.h index e89da3a..5422772 100644 --- a/libs/BeetRoundCore/network/apiroutes.h +++ b/libs/BeetRoundCore/network/apiroutes.h @@ -9,4 +9,12 @@ static const QString apiPrefix = "/api/"; 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"; + +static const QString ROUTE_GET_BIDDINGS_OF_SPECIFIC_ROUND = apiPrefix + "biddings_of_round"; +static const QString ROUTE_GET_BIDDINGS_OF_HIGHEST_ROUND = apiPrefix + "biddings_of_highest_round"; #endif // APIROUTES_H diff --git a/libs/BeetRoundCore/network/servercommunicator.cpp b/libs/BeetRoundCore/network/servercommunicator.cpp index 7545e2e..0c42fb6 100644 --- a/libs/BeetRoundCore/network/servercommunicator.cpp +++ b/libs/BeetRoundCore/network/servercommunicator.cpp @@ -1,21 +1,29 @@ #include "servercommunicator.h" -#include "apiroutes.h" #include -#include #include +#include #include +#include "../genericcore.h" +#include "../structs.h" +#include "apiroutes.h" + using namespace Qt::StringLiterals; -ServerCommunicator::ServerCommunicator(QObject* parent) - : QObject{parent} { +ServerCommunicator::ServerCommunicator(GenericCore* core) + : m_core(core) + , QObject{core} { m_netManager.setAutoDeleteReplies(true); m_restManager = std::make_shared(&m_netManager); m_serviceApi = std::make_shared(); + + connect(m_core, &GenericCore::sendGetRequest, this, + &ServerCommunicator::onSendGetRequestTriggered); + connect(this, &ServerCommunicator::biddingsChanged, m_core, &GenericCore::onBiddingsChanged); } -bool ServerCommunicator::sslSupported() { +bool ServerCommunicator::sslSupported() const { #if QT_CONFIG(ssl) return QSslSocket::supportsSsl(); #else @@ -104,3 +112,108 @@ void ServerCommunicator::setServerConfiguration(const QString url, m_email = email; m_password = password; } + +void ServerCommunicator::onSendGetRequestTriggered(const GetRequestTypes type, + QVariant data = QVariant()) { + 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; + case GetBiddingsOfSpecificRound: + path = ROUTE_GET_BIDDINGS_OF_SPECIFIC_ROUND + "/" + data.toString(); + break; + case GetBiddingsOfHighestRound: + path = ROUTE_GET_BIDDINGS_OF_HIGHEST_ROUND; + 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; + case GetBiddingsOfSpecificRound: + case GetBiddingsOfHighestRound: + currentBiddingsReply(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; + + // NOTE ?use ServerCommunicator::currentBiddingRoundChanged signal instead of emiting a signal of + // the core directly? + emit m_core->currentBiddingRoundChanged(roundNumber, isActive); +} + +void ServerCommunicator::currentBiddingsReply(const QJsonDocument jsonDoc) { + qCritical() << "currentBiddingsReply:" << jsonDoc; + + // NEXT extract biddings from jsonDoc + const int roundNumber = 0; + const bidding dummyBidding{.userId = QUuid(), + .biddingRound = 0, + .amount = 123, + .depotWishOne = "one", + .depotWishTwo = "two"}; + const QList biddings{dummyBidding}; + + emit biddingsChanged(roundNumber, biddings); +} diff --git a/libs/BeetRoundCore/network/servercommunicator.h b/libs/BeetRoundCore/network/servercommunicator.h index 3107604..0f6b3df 100644 --- a/libs/BeetRoundCore/network/servercommunicator.h +++ b/libs/BeetRoundCore/network/servercommunicator.h @@ -1,17 +1,23 @@ #ifndef SERVERCOMMUNICATOR_H #define SERVERCOMMUNICATOR_H +#include #include #include #include #include +#include "../model/metadata.h" + +class bidding; +class GenericCore; + class ServerCommunicator : public QObject { Q_OBJECT public: - explicit ServerCommunicator(QObject* parent = nullptr); + explicit ServerCommunicator(GenericCore* core); - bool sslSupported(); + bool sslSupported() const; QUrl url() const; void setUrl(const QUrl& url); @@ -19,6 +25,10 @@ class ServerCommunicator : public QObject { void setServerConfiguration(const QString url, const QString email, const QString password); public slots: + void onSendGetRequestTriggered(const GetRequestTypes type, QVariant data); + void onGetReplySuccessful(const GetRequestTypes type, const QJsonDocument doc); + void onGetReplyFailure(const GetRequestTypes type, const QString errorString); + void fetchItems(); void postItems(const QByteArray& jsonData); void deleteItem(const QString& id); @@ -33,7 +43,12 @@ class ServerCommunicator : public QObject { void deleteRequestSuccessful(const QByteArray responseData); void deleteRequestFailure(const QString errorString); + void currentBiddingRoundChanged(int round, bool isRunning); + void biddingsChanged(int round, QList biddings); + private: + GenericCore* m_core = nullptr; + QNetworkAccessManager m_netManager; std::shared_ptr m_restManager; std::shared_ptr m_serviceApi; @@ -41,6 +56,10 @@ class ServerCommunicator : public QObject { QString m_email; QString m_password; // QString m_authToken; + + /// reply parser + void currentBiddingRoundChangedReply(const QJsonDocument jsonDoc); + void currentBiddingsReply(const QJsonDocument jsonDoc); }; #endif // SERVERCOMMUNICATOR_H diff --git a/libs/BeetRoundCore/structs.h b/libs/BeetRoundCore/structs.h new file mode 100644 index 0000000..c32bb93 --- /dev/null +++ b/libs/BeetRoundCore/structs.h @@ -0,0 +1,14 @@ +#ifndef STRUCTS_H +#define STRUCTS_H + +#include + +struct bidding { + QUuid userId; + int biddingRound; + int amount; + QString depotWishOne; + QString depotWishTwo; +}; + +#endif // STRUCTS_H