Compare commits

..

8 Commits

17 changed files with 316 additions and 54 deletions

View File

@ -30,6 +30,8 @@ void EditItemDialog::createContent() {
/// online user stuff /// online user stuff
connect(m_detailMapper, &ItemDetailMapper::createOnlineAccountTriggered, this, connect(m_detailMapper, &ItemDetailMapper::createOnlineAccountTriggered, this,
&EditItemDialog::createOnlineAccountTriggered); &EditItemDialog::createOnlineAccountTriggered);
connect(m_detailMapper, &ItemDetailMapper::sendInviteMailTriggered, this,
&EditItemDialog::sendInviteMailTriggered);
} }
void EditItemDialog::accept() { void EditItemDialog::accept() {

View File

@ -21,6 +21,8 @@ class EditItemDialog : public AbstractDialog {
signals: signals:
void createOnlineAccountTriggered(const QString& mailAddress); void createOnlineAccountTriggered(const QString& mailAddress);
void sendInviteMailTriggered(const QString& mailAddress);
public slots: public slots:
void accept() override; void accept() override;
void reject() override; void reject() override;

View File

@ -27,12 +27,12 @@ void SettingsDialog::createContent() {
serverLayout->addWidget(m_urlEdit, 0, 1); serverLayout->addWidget(m_urlEdit, 0, 1);
QLabel* emailLabel = new QLabel("Email:"); QLabel* emailLabel = new QLabel("Email:");
m_emailEdit = new QLineEdit(); m_emailEdit = new QLineEdit();
m_emailEdit->setEnabled(false); // m_emailEdit->setEnabled(false);
serverLayout->addWidget(emailLabel, 1, 0); serverLayout->addWidget(emailLabel, 1, 0);
serverLayout->addWidget(m_emailEdit, 1, 1); serverLayout->addWidget(m_emailEdit, 1, 1);
QLabel* passwordLabel = new QLabel("Password:"); QLabel* passwordLabel = new QLabel("Password:");
m_passwordEdit = new QLineEdit(); m_passwordEdit = new QLineEdit();
m_passwordEdit->setEnabled(false); // m_passwordEdit->setEnabled(false);
m_passwordEdit->setEchoMode(QLineEdit::Password); m_passwordEdit->setEchoMode(QLineEdit::Password);
serverLayout->addWidget(passwordLabel, 2, 0); serverLayout->addWidget(passwordLabel, 2, 0);
serverLayout->addWidget(m_passwordEdit, 2, 1); serverLayout->addWidget(m_passwordEdit, 2, 1);

View File

@ -570,4 +570,7 @@ void MainWindow::setupEventTab() {
void MainWindow::initServerConnection() { void MainWindow::initServerConnection() {
connect(m_editItemDialog.get(), &EditItemDialog::createOnlineAccountTriggered, m_core.get(), connect(m_editItemDialog.get(), &EditItemDialog::createOnlineAccountTriggered, m_core.get(),
&GenericCore::onCreateOnlineAccountTriggered); &GenericCore::onCreateOnlineAccountTriggered);
connect(m_editItemDialog.get(), &EditItemDialog::sendInviteMailTriggered, m_core.get(),
&GenericCore::onSendInviteMailTriggered);
emit m_core->loginAndStoreAuthToken();
} }

View File

@ -165,6 +165,8 @@ ItemDetailMapper::ItemDetailMapper(QWidget* parent)
connect(m_createOnlineAccountButton, &QAbstractButton::clicked, this, connect(m_createOnlineAccountButton, &QAbstractButton::clicked, this,
&ItemDetailMapper::onCreateOnlineAccountTriggered); &ItemDetailMapper::onCreateOnlineAccountTriggered);
connect(m_sendInviteMailButton, &QAbstractButton::clicked, this,
&ItemDetailMapper::onSendInviteMailTriggered);
} }
void ItemDetailMapper::setModelMappings(QTableView* tableView) { void ItemDetailMapper::setModelMappings(QTableView* tableView) {
@ -243,15 +245,6 @@ void ItemDetailMapper::updateButtons(int row) {
m_nextButton->setEnabled(row < m_model->rowCount() - 1); 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, void ItemDetailMapper::onCurrentIndexChanged(const QModelIndex& current,
const QModelIndex& /*previous*/) { const QModelIndex& /*previous*/) {
if (!isEnabled()) { if (!isEnabled()) {
@ -259,7 +252,6 @@ void ItemDetailMapper::onCurrentIndexChanged(const QModelIndex& current,
} }
m_mapper->setCurrentModelIndex(current); m_mapper->setCurrentModelIndex(current);
updateButtons(current.row()); updateButtons(current.row());
emitContentChanged(current);
} }
void ItemDetailMapper::updateQRCode(const QString text) { void ItemDetailMapper::updateQRCode(const QString text) {
@ -302,7 +294,7 @@ void ItemDetailMapper::onAccessCodeChanged(const QString& text) {
updateQRCode(""); updateQRCode("");
} else { } else {
m_sendInviteMailButton->setEnabled(true); m_sendInviteMailButton->setEnabled(true);
const QString accessUrl = "http://127.0.0.1:4000/api/users/" + text; const QString accessUrl = "http://127.0.0.1:4000/log_in/" + text;
m_accessUrlDisplay->setText(accessUrl); m_accessUrlDisplay->setText(accessUrl);
updateQRCode(accessUrl); updateQRCode(accessUrl);
} }
@ -311,3 +303,7 @@ void ItemDetailMapper::onAccessCodeChanged(const QString& text) {
void ItemDetailMapper::onCreateOnlineAccountTriggered() { void ItemDetailMapper::onCreateOnlineAccountTriggered() {
emit createOnlineAccountTriggered(m_mailEdit->text()); emit createOnlineAccountTriggered(m_mailEdit->text());
} }
void ItemDetailMapper::onSendInviteMailTriggered() {
emit sendInviteMailTriggered(m_mailEdit->text());
}

View File

@ -31,6 +31,7 @@ class ItemDetailMapper : public QWidget {
void contentChanged(const QString text); void contentChanged(const QString text);
void createOnlineAccountTriggered(const QString& mailAddress); void createOnlineAccountTriggered(const QString& mailAddress);
void sendInviteMailTriggered(const QString& mailAddress);
private slots: private slots:
void rowsInserted(const QModelIndex& parent, int start, int end); void rowsInserted(const QModelIndex& parent, int start, int end);
@ -38,7 +39,6 @@ class ItemDetailMapper : public QWidget {
void toPrevious(); void toPrevious();
void toNext(); void toNext();
void updateButtons(int row); void updateButtons(int row);
void emitContentChanged(const QModelIndex& currentIndex);
void onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous); void onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous);
void updateQRCode(const QString text = ""); void updateQRCode(const QString text = "");
@ -46,6 +46,7 @@ class ItemDetailMapper : public QWidget {
void onOnlineIDChanged(const QString& text); void onOnlineIDChanged(const QString& text);
void onAccessCodeChanged(const QString& text); void onAccessCodeChanged(const QString& text);
void onCreateOnlineAccountTriggered(); void onCreateOnlineAccountTriggered();
void onSendInviteMailTriggered();
private: private:
/// *** members *** /// *** members ***

View File

@ -4,6 +4,7 @@
#include <QJsonObject> #include <QJsonObject>
#include "../model/metadata.h" #include "../model/metadata.h"
#include "../structs.h"
QList<ModelItemValues> JsonParser::toItemValuesList(const QByteArray& jsonData, QList<ModelItemValues> JsonParser::toItemValuesList(const QByteArray& jsonData,
const QString& rootValueName) { const QString& rootValueName) {
@ -70,7 +71,7 @@ QByteArray JsonParser::itemValuesListToJson(const QList<ModelItemValues>& itemVa
return jsonDoc.toJson(QJsonDocument::Compact); return jsonDoc.toJson(QJsonDocument::Compact);
} }
QByteArray JsonParser::ToJsonObject(const QHash<QString, QVariant>& values, QByteArray JsonParser::toJsonDoc(const QHash<QString, QVariant>& values,
const QString& objectName) { const QString& objectName) {
QJsonDocument jsonDoc; QJsonDocument jsonDoc;
QJsonObject rootObject; QJsonObject rootObject;
@ -90,6 +91,45 @@ QByteArray JsonParser::ToJsonObject(const QHash<QString, QVariant>& values,
return jsonDoc.toJson(QJsonDocument::Compact); return jsonDoc.toJson(QJsonDocument::Compact);
} }
ModelItemValues JsonParser::serverUserCredentialsToItemValues(const QJsonDocument& jsonDoc) {
ModelItemValues values;
const QJsonObject rootObject = jsonDoc["data"].toObject();
const QString emailAddress = rootObject["email"].toString();
const QString uuid = rootObject["id"].toString();
const QString token = rootObject["token"].toString();
values.insert(MailRole, emailAddress);
values.insert(OnlineIdRole, uuid);
values.insert(AccessCodeRole, token);
return values;
}
QList<bidding> JsonParser::extractBiddings(const QJsonDocument& jsonDoc) {
QList<bidding> result;
if (jsonDoc.isEmpty()) {
return result;
}
QJsonArray itemArray = JsonParser::extractItemArray(jsonDoc, "data");
foreach (QJsonValue value, itemArray) {
// REFACTOR implement & use "JsonParser::parseServerResponse(const QJsonObject& object,
// QHash<QString, int> entries)"
QJsonObject itemJsonObject = value.toObject();
bidding values{.userId = itemJsonObject.value("user_id").toString(),
.biddingRound = itemJsonObject.value("bidding_round").toInt(),
.amount = itemJsonObject.value("amount").toInt(),
.depotWishOne = itemJsonObject.value("depot_wish_one").toString(),
.depotWishTwo = itemJsonObject.value("depot_wish_two").toString()};
result.append(values);
}
return result;
}
QJsonArray JsonParser::extractItemArray(const QJsonDocument& doc, const QString& objectName) { QJsonArray JsonParser::extractItemArray(const QJsonDocument& doc, const QString& objectName) {
QJsonArray itemArray; QJsonArray itemArray;
if (objectName.isEmpty()) { if (objectName.isEmpty()) {
@ -101,8 +141,6 @@ QJsonArray JsonParser::extractItemArray(const QJsonDocument& doc, const QString&
return itemArray; return itemArray;
} }
JsonParser::JsonParser() {}
ModelItemValues JsonParser::jsonObjectToItemValues(const QJsonObject& itemJsonObject) { ModelItemValues JsonParser::jsonObjectToItemValues(const QJsonObject& itemJsonObject) {
ModelItemValues values; ModelItemValues values;
@ -115,6 +153,8 @@ ModelItemValues JsonParser::jsonObjectToItemValues(const QJsonObject& itemJsonOb
return values; return values;
} }
JsonParser::JsonParser() {}
pair<int, QVariant> JsonParser::getKeyValuePair(const QJsonObject& itemJsonObject, const int role) { pair<int, QVariant> JsonParser::getKeyValuePair(const QJsonObject& itemJsonObject, const int role) {
QVariant result; QVariant result;
const QJsonValue jsonValue = itemJsonObject[ROLE_NAMES.value(role)]; const QJsonValue jsonValue = itemJsonObject[ROLE_NAMES.value(role)];

View File

@ -9,6 +9,7 @@ class QByteArray;
class QJsonArray; class QJsonArray;
typedef QMap<int, QVariant> ModelItemValues; typedef QMap<int, QVariant> ModelItemValues;
class bidding;
using namespace std; using namespace std;
@ -18,15 +19,22 @@ class JsonParser {
const QString& rootValueName = ""); const QString& rootValueName = "");
static QByteArray itemValuesListToJson(const QList<ModelItemValues>& itemValuesList, static QByteArray itemValuesListToJson(const QList<ModelItemValues>& itemValuesList,
const QString& objectName = ""); const QString& objectName = "");
static QByteArray ToJsonObject(const QHash<QString, QVariant>& Values, static QByteArray toJsonDoc(const QHash<QString, QVariant>& Values,
const QString& objectName = ""); const QString& objectName = "");
private: static ModelItemValues serverUserCredentialsToItemValues(const QJsonDocument& jsonDoc);
explicit JsonParser(); static QList<bidding> extractBiddings(const QJsonDocument& jsonDoc);
// static ModelItemValues parseServerResponse(const QJsonDocument& jsonDoc,
// QHash<QString, int> entries);
// static ModelItemValues parseServerResponse(const QJsonObject& object,
// QHash<QString, int> entries);
static QJsonArray extractItemArray(const QJsonDocument& doc, const QString& objectName); static QJsonArray extractItemArray(const QJsonDocument& doc, const QString& objectName);
static ModelItemValues jsonObjectToItemValues(const QJsonObject& itemJsonObject); static ModelItemValues jsonObjectToItemValues(const QJsonObject& itemJsonObject);
private:
explicit JsonParser();
static pair<int, QVariant> getKeyValuePair(const QJsonObject& itemJsonObject, const int role); static pair<int, QVariant> getKeyValuePair(const QJsonObject& itemJsonObject, const int role);
}; };

View File

@ -15,6 +15,7 @@
#include "constants.h" #include "constants.h"
#include "data/filehandler.h" #include "data/filehandler.h"
#include "data/settingshandler.h" #include "data/settingshandler.h"
#include "formats/jsonparser.h"
#include "model/generalsortfiltermodel.h" #include "model/generalsortfiltermodel.h"
#include "model/metadata.h" #include "model/metadata.h"
#include "model/modelsummary.h" #include "model/modelsummary.h"
@ -155,16 +156,23 @@ bool GenericCore::isSyncServerSetup() const {
} }
} }
void GenericCore::onBiddingsChanged(int round, QList<bidding> biddings) { void GenericCore::onLoginSuccessful() {
qInfo() << "onBiddingsChanged: round:" << round << "- biddings:" << biddings.count(); qInfo() << "Login successful.";
emit displayStatusMessage("Login successful.");
emit sendGetRequest(GetCurrentBiddingRound);
}
void GenericCore::onBiddingsChanged(const QList<bidding> biddings) {
qInfo() << "onBiddingsChanged: biddings:" << biddings.count();
// NEXT merge biddings into model // NEXT merge biddings into model
m_mainModel->updateBiddings(biddings);
} }
void GenericCore::onCreateOnlineAccountTriggered(const QString& mailAddress) { void GenericCore::onCreateOnlineAccountTriggered(const QString& mailAddress) {
qInfo() << "Creating online account for:" << mailAddress; qInfo() << "Creating online account for:" << mailAddress;
QHash<QString, QVariant> hash; QHash<QString, QVariant> hash;
hash.insert("email", mailAddress); hash.insert("email", mailAddress);
const QByteArray jsonDoc = JsonParser::ToJsonObject(hash, "user"); const QByteArray jsonDoc = JsonParser::toJsonDoc(hash, "user");
emit sendPostRequest(RegisterUser, jsonDoc); emit sendPostRequest(RegisterUser, jsonDoc);
} }
@ -176,6 +184,12 @@ void GenericCore::onOnlineUserAccountReceived(const QString mailAddress,
const QString message = QString("Online credentials received for: %1").arg(mailAddress); const QString message = QString("Online credentials received for: %1").arg(mailAddress);
emit displayStatusMessage(message); 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() { void GenericCore::setupModels() {
@ -248,6 +262,7 @@ void GenericCore::applyServerConfiguration() {
if (!urlValue.isEmpty()) { if (!urlValue.isEmpty()) {
const QString emailValue = serverSettings.value("email").toString(); const QString emailValue = serverSettings.value("email").toString();
const QString passwordValue = serverSettings.value("password").toString(); const QString passwordValue = serverSettings.value("password").toString();
m_serverCommunicator->setServerConfiguration(urlValue, emailValue, passwordValue); const QString authToken = serverSettings.value("token").toString();
m_serverCommunicator->setServerConfiguration(urlValue, emailValue, passwordValue, authToken);
} }
} }

View File

@ -47,17 +47,21 @@ class GenericCore : public QObject {
bool isSyncServerSetup() const; bool isSyncServerSetup() const;
public slots: public slots:
void onBiddingsChanged(int round, QList<bidding> biddings); void onLoginSuccessful();
void onBiddingsChanged(const QList<bidding> biddings);
void onCreateOnlineAccountTriggered(const QString& mailAddress); void onCreateOnlineAccountTriggered(const QString& mailAddress);
void onOnlineUserAccountReceived(const QString mailAddress, void onOnlineUserAccountReceived(const QString mailAddress,
const QString uuid, const QString uuid,
const QString accessToken); const QString accessToken);
void onSendInviteMailTriggered(const QString& mailAddress);
signals: signals:
void displayStatusMessage(QString message); void displayStatusMessage(QString message);
/// *** server communication *** /// *** server communication ***
void loginAndStoreAuthToken();
/// request signals /// request signals
void sendGetRequest(GetRequestTypes type, QVariant data = QVariant()); void sendGetRequest(GetRequestTypes type, QVariant data = QVariant());
void sendPostRequest(PostRequestTypes type, QByteArray data); void sendPostRequest(PostRequestTypes type, QByteArray data);

View File

@ -91,7 +91,7 @@ enum GetRequestTypes {
GetBiddingsOfSpecificRound, GetBiddingsOfSpecificRound,
GetBiddingsOfHighestRound GetBiddingsOfHighestRound
}; };
enum PostRequestTypes { RegisterUser }; enum PostRequestTypes { LogInAdmin, RegisterUser, MailInvite };
/// functions /// functions
static UserRoles GET_ROLE_FOR_COLUMN(const int column) { static UserRoles GET_ROLE_FOR_COLUMN(const int column) {

View File

@ -1,16 +1,17 @@
#include "tablemodel.h" #include "tablemodel.h"
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include "../formats/jsonparser.h" #include "../formats/jsonparser.h"
#include "../structs.h"
#include "commands/edititemcommand.h" #include "commands/edititemcommand.h"
#include "commands/insertrowscommand.h" #include "commands/insertrowscommand.h"
#include "commands/removerowscommand.h" #include "commands/removerowscommand.h"
#include "metadata.h" #include "metadata.h"
#include "modelitem.h" #include "modelitem.h"
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
QByteArray TableModel::generateExampleItems() { QByteArray TableModel::generateExampleItems() {
QJsonDocument doc = QJsonDocument(); QJsonDocument doc = QJsonDocument();
QJsonObject rootObject; QJsonObject rootObject;
@ -238,6 +239,55 @@ void TableModel::setOnlineCredentials(const QString& mail,
setItemData(itemIndex, {{OnlineIdRole, uuid}, {AccessCodeRole, token}}); 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<bidding> biddings) {
QListIterator<bidding> i(biddings);
while (i.hasNext()) {
const bidding localBidding = i.next();
qInfo() << "Processing bidding:";
const int biddingRound = localBidding.biddingRound;
if (biddingRound == 0 || biddingRound > 3) {
qWarning() << "Bidding round exceeds valid bounds. Ignoring...";
continue;
}
const QString uuid = localBidding.userId;
const QModelIndex itemIndex = getIndexByRoleValue(localBidding.userId, OnlineIdRole);
if (itemIndex.isValid()) {
qInfo() << "Found Uuid for user:" << itemIndex.data(MailRole);
const QMap<int, QVariant> values = getItemValues(localBidding);
setItemData(itemIndex, values);
}
}
}
bool TableModel::removeRows(int firstRow, int nRows, const QModelIndex& parentIndex) { bool TableModel::removeRows(int firstRow, int nRows, const QModelIndex& parentIndex) {
if (parentIndex != QModelIndex()) { if (parentIndex != QModelIndex()) {
@ -330,6 +380,7 @@ qreal TableModel::biddingAverage2() const {
qInfo() << "average calculation (2):" << averageBidding; qInfo() << "average calculation (2):" << averageBidding;
return averageBidding; return averageBidding;
} }
qreal TableModel::biddingAverage3() const { qreal TableModel::biddingAverage3() const {
const UserRoles biddingRole = Bidding3Role; const UserRoles biddingRole = Bidding3Role;
const qreal averageBidding = averageBiddingAmount(biddingRole); const qreal averageBidding = averageBiddingAmount(biddingRole);
@ -603,9 +654,38 @@ QModelIndex TableModel::getIndexByRoleValue(const QString& valueString, const in
} }
} }
if (itemRow < 0 || itemRow >= m_items.length()) { if (itemRow < 0 || itemRow >= m_items.length()) {
qWarning() << "Couldn't find item with mail address:" << valueString << "- Returning..."; qWarning() << "Couldn't find item with:" << valueString << " matching role" << role
<< "- Returning...";
return QModelIndex(); return QModelIndex();
} }
const QModelIndex itemIndex = index(itemRow, 0); const QModelIndex itemIndex = index(itemRow, 0);
return itemIndex; return itemIndex;
} }
QMap<int, QVariant> TableModel::getItemValues(const bidding bid) {
const int biddingRound = bid.biddingRound;
const int amount = bid.amount;
const QString depotWishOne = bid.depotWishOne;
const QString depotWishTwo = bid.depotWishTwo;
UserRoles biddingRole;
switch (biddingRound) {
case 1:
biddingRole = Bidding1Role;
break;
case 2:
biddingRole = Bidding2Role;
break;
case 3:
biddingRole = Bidding3Role;
break;
default:
break;
}
if (biddingRound == 1) {
return {{biddingRole, amount}, {DepotWish1Role, depotWishOne}, {DepotWish2Role, depotWishTwo}};
} else {
return {{biddingRole, amount}};
}
}

View File

@ -4,6 +4,7 @@
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include "metadata.h" #include "metadata.h"
class bidding;
class QUndoStack; class QUndoStack;
class ModelItem; class ModelItem;
@ -45,6 +46,10 @@ class TableModel : public QAbstractTableModel {
bool updateItem(const ModelItemValues& itemValues); bool updateItem(const ModelItemValues& itemValues);
void setOnlineCredentials(const QString& mail, const QString& uuid, const QString& token); void setOnlineCredentials(const QString& mail, const QString& uuid, const QString& token);
QJsonDocument getMailInviteJsonDoc(const QString& mail, const QString& serverUrl) const;
void updateBiddings(const QList<bidding> biddings);
public slots: public slots:
// bool insertRows(int position, int rows, const QModelIndex& parentIndex = QModelIndex()) // bool insertRows(int position, int rows, const QModelIndex& parentIndex = QModelIndex())
// override; // override;
@ -108,6 +113,7 @@ class TableModel : public QAbstractTableModel {
qreal totalSharesWithBiddings(const UserRoles biddingRole) const; qreal totalSharesWithBiddings(const UserRoles biddingRole) const;
QModelIndex getIndexByRoleValue(const QString& valueString, const int role) const; QModelIndex getIndexByRoleValue(const QString& valueString, const int role) const;
QMap<int, QVariant> getItemValues(const bidding bid);
}; };
#endif // TABLEMODEL_H #endif // TABLEMODEL_H

View File

@ -5,11 +5,16 @@
// TODO add namespace // TODO add namespace
static const QString ROUTE_USER_LOG_IN = "/log_in";
static const QString apiPrefix = "/api/"; static const QString apiPrefix = "/api/";
static const QString ROUTE_ITEMS = apiPrefix + "items"; static const QString ROUTE_ITEMS = apiPrefix + "items";
static const QString ROUTE_ADMIN_LOG_IN = apiPrefix + "log_in";
static const QString ROUTE_REGISTER_USER = apiPrefix + "users"; 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_BIDDINGROUNDS = apiPrefix + "bidding_rounds";
static const QString ROUTE_CURRENT_BIDDINGROUND = ROUTE_BIDDINGROUNDS + "/get_current"; static const QString ROUTE_CURRENT_BIDDINGROUND = ROUTE_BIDDINGROUNDS + "/get_current";

View File

@ -5,10 +5,13 @@
#include <QRestAccessManager> #include <QRestAccessManager>
#include <QRestReply> #include <QRestReply>
#include "../formats/jsonparser.h"
#include "../genericcore.h" #include "../genericcore.h"
#include "../structs.h" #include "../structs.h"
#include "apiroutes.h" #include "apiroutes.h"
#include "../data/settingshandler.h"
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
ServerCommunicator::ServerCommunicator(GenericCore* core) ServerCommunicator::ServerCommunicator(GenericCore* core)
@ -18,6 +21,9 @@ ServerCommunicator::ServerCommunicator(GenericCore* core)
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(core, &GenericCore::loginAndStoreAuthToken, this, &ServerCommunicator::onLoginTriggered);
connect(this, &ServerCommunicator::loginSuccessful, core, &GenericCore::onLoginSuccessful);
connect(m_core, &GenericCore::sendGetRequest, this, connect(m_core, &GenericCore::sendGetRequest, this,
&ServerCommunicator::onSendGetRequestTriggered); &ServerCommunicator::onSendGetRequestTriggered);
connect(m_core, &GenericCore::sendPostRequest, this, connect(m_core, &GenericCore::sendPostRequest, this,
@ -50,11 +56,22 @@ void ServerCommunicator::setUrl(const QUrl& url) {
void ServerCommunicator::setServerConfiguration(const QString url, void ServerCommunicator::setServerConfiguration(const QString url,
const QString email, const QString email,
const QString password) { const QString password,
const QString authToken) {
setUrl(url); setUrl(url);
m_email = email; m_email = email;
m_password = password; m_password = password;
m_authToken = authToken;
if (!m_authToken.isEmpty()) {
m_serviceApi->setBearerToken(authToken.toLatin1());
}
}
QString ServerCommunicator::getUserLoginUrl() const {
const QString logInUrl = m_serviceApi->baseUrl().toString() + ROUTE_USER_LOG_IN;
return logInUrl;
} }
void ServerCommunicator::onSendGetRequestTriggered(const GetRequestTypes type, void ServerCommunicator::onSendGetRequestTriggered(const GetRequestTypes type,
@ -90,6 +107,7 @@ void ServerCommunicator::onSendGetRequestTriggered(const GetRequestTypes type,
return; return;
} }
m_serviceApi->setBearerToken(m_authToken.toLatin1());
const QNetworkRequest request = m_serviceApi->createRequest(path); const QNetworkRequest request = m_serviceApi->createRequest(path);
m_restManager->get(request, this, [this, type](QRestReply& reply) { m_restManager->get(request, this, [this, type](QRestReply& reply) {
@ -139,9 +157,15 @@ void ServerCommunicator::onSendPostRequestTriggered(const PostRequestTypes type,
const QByteArray data) { const QByteArray data) {
QString path; QString path;
switch (type) { switch (type) {
case LogInAdmin:
path = ROUTE_ADMIN_LOG_IN;
break;
case RegisterUser: case RegisterUser:
path = ROUTE_REGISTER_USER; path = ROUTE_REGISTER_USER;
break; break;
case MailInvite:
path = ROUTE_MAIL_INVITE;
break;
default: default:
qWarning() << "No route found for PostRequestType:" << type; qWarning() << "No route found for PostRequestType:" << type;
break; break;
@ -153,6 +177,7 @@ void ServerCommunicator::onSendPostRequestTriggered(const PostRequestTypes type,
return; return;
} }
m_serviceApi->setBearerToken(m_authToken.toLatin1());
const QNetworkRequest request = m_serviceApi->createRequest(path); const QNetworkRequest request = m_serviceApi->createRequest(path);
m_restManager->post(request, data, this, [this, type](QRestReply& reply) { m_restManager->post(request, data, this, [this, type](QRestReply& reply) {
@ -179,10 +204,18 @@ void ServerCommunicator::onSendPostRequestTriggered(const PostRequestTypes type,
void ServerCommunicator::onPostReplySuccessful(const PostRequestTypes type, void ServerCommunicator::onPostReplySuccessful(const PostRequestTypes type,
const QJsonDocument doc) { const QJsonDocument doc) {
switch (type) { switch (type) {
case LogInAdmin:
qInfo() << "Admin successfully logged in:" << type;
handleLogInReply(doc);
break;
case RegisterUser: case RegisterUser:
qInfo() << "Register user successful:" << type; qInfo() << "Register user successful:" << type;
onlineUserAccountReply(doc); onlineUserAccountReply(doc);
break; break;
case MailInvite:
qInfo() << "Mail invite successful sent:" << type;
mailInviteSentReply(doc);
break;
default: default:
qWarning() << "Can't match request type:" << type; qWarning() << "Can't match request type:" << type;
break; break;
@ -193,11 +226,42 @@ void ServerCommunicator::onPostReplyFailure(const PostRequestTypes type,
const QString errorString) { const QString errorString) {
const QString message = const QString message =
QString("Request of type %1 returned: %2").arg(QString::number(type), errorString); QString("Request of type %1 returned: %2").arg(QString::number(type), errorString);
m_core->displayStatusMessage(message); // NEXT improve error message to the UI;
emit m_core->displayStatusMessage(message);
}
QByteArray ServerCommunicator::createLoginBody() {
QHash<QString, QVariant> values;
values.insert("email", m_email);
values.insert("password", m_password);
return JsonParser::toJsonDoc(values, "admin");
}
void ServerCommunicator::handleLogInReply(const QJsonDocument jsonDoc) {
QJsonObject rootObject = jsonDoc.object();
bool hasErrors = rootObject.contains(QString("errors"));
if (hasErrors) {
qCritical() << "Reply has error(s)!";
QString errorString = rootObject["errors"].toString();
emit m_core->displayStatusMessage(errorString);
} else {
qInfo() << "Reply has no error(s)!";
const QJsonObject dataObject = rootObject["data"].toObject();
const QString authToken = dataObject["token"].toString();
m_authToken = authToken;
SettingsHandler::saveSettings({{"token", authToken}}, "Server");
emit loginSuccessful();
emit m_core->displayStatusMessage("Successfully logged in.");
}
} }
void ServerCommunicator::currentBiddingRoundChangedReply(const QJsonDocument jsonDoc) { void ServerCommunicator::currentBiddingRoundChangedReply(const QJsonDocument jsonDoc) {
qInfo() << "Current bidding round received."; qInfo() << "Current bidding round received.";
// REFACTOR implement & use "JsonParser::parseServerResponse(const QJsonDocument& jsonDoc,
// QHash<QString, int> entries)" (generalized version of
// "serverUserCredentialsToItemValues")
const QJsonObject rootObject = jsonDoc["data"].toObject(); const QJsonObject rootObject = jsonDoc["data"].toObject();
const int roundNumber = rootObject["round_number"].toInt(); const int roundNumber = rootObject["round_number"].toInt();
const bool stopped = rootObject["stopped"].toBool(); const bool stopped = rootObject["stopped"].toBool();
@ -211,24 +275,47 @@ void ServerCommunicator::currentBiddingRoundChangedReply(const QJsonDocument jso
void ServerCommunicator::currentBiddingsReply(const QJsonDocument jsonDoc) { void ServerCommunicator::currentBiddingsReply(const QJsonDocument jsonDoc) {
qCritical() << "currentBiddingsReply:" << jsonDoc; qCritical() << "currentBiddingsReply:" << jsonDoc;
// NEXT extract biddings from jsonDoc const QList<bidding> biddings = JsonParser::extractBiddings(jsonDoc);
const int roundNumber = 0;
const bidding dummyBidding{.userId = QUuid(), emit biddingsChanged(biddings);
.biddingRound = 0,
.amount = 123,
.depotWishOne = "one",
.depotWishTwo = "two"};
const QList<bidding> biddings{dummyBidding};
emit biddingsChanged(roundNumber, biddings);
} }
void ServerCommunicator::onlineUserAccountReply(const QJsonDocument jsonDoc) { void ServerCommunicator::onlineUserAccountReply(const QJsonDocument jsonDoc) {
qInfo() << "Online user account received."; qInfo() << "Online user account received.";
// TODO move data extraction of jsonDoc into JsonParser ModelItemValues values = JsonParser::serverUserCredentialsToItemValues(jsonDoc);
const QJsonObject rootObject = jsonDoc["data"].toObject();
const QString emailAddress = rootObject["email"].toString();
const QString uuid = rootObject["id"].toString();
const QString token = rootObject["token"].toString();
emit onlineUserAccountReceived(emailAddress, uuid, token); 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.");
}
void ServerCommunicator::onLoginTriggered() {
qInfo() << "Login triggered...";
if (m_email.isEmpty() || m_password.isEmpty()) {
emit m_core->displayStatusMessage(
"Missing email or password in settings! Not trying to log in.");
return;
}
if (m_authToken.isEmpty()) {
/// get new authToken
qWarning() << "Creating a new authToken!";
const QByteArray loginBody = createLoginBody();
onSendPostRequestTriggered(LogInAdmin, loginBody);
} else {
/// try authToken
qWarning() << "Validity check of token not implemented yet!!!";
qInfo() << "Assuming validity of token...";
emit loginSuccessful();
// TODO try validity of token and trigger log_in if not valid
// try default route to test access;
// if (access denied) {
// m_apiClient->sendAPIRequestPost(ROUTE_LOG_IN_ADMIN, );
// }
}
} }

View File

@ -22,9 +22,15 @@ class ServerCommunicator : public QObject {
QUrl url() const; QUrl url() const;
void setUrl(const QUrl& url); void setUrl(const QUrl& url);
void setServerConfiguration(const QString url, const QString email, const QString password); void setServerConfiguration(const QString url,
const QString email,
const QString password,
const QString authToken);
QString getUserLoginUrl() const;
public slots: public slots:
void onLoginTriggered();
void onSendGetRequestTriggered(const GetRequestTypes type, QVariant data); void onSendGetRequestTriggered(const GetRequestTypes type, QVariant data);
void onGetReplySuccessful(const GetRequestTypes type, const QJsonDocument doc); void onGetReplySuccessful(const GetRequestTypes type, const QJsonDocument doc);
void onGetReplyFailure(const GetRequestTypes type, const QString errorString); void onGetReplyFailure(const GetRequestTypes type, const QString errorString);
@ -43,8 +49,10 @@ class ServerCommunicator : public QObject {
void deleteRequestSuccessful(const QByteArray responseData); void deleteRequestSuccessful(const QByteArray responseData);
void deleteRequestFailure(const QString errorString); void deleteRequestFailure(const QString errorString);
void loginSuccessful();
void currentBiddingRoundChanged(int round, bool isRunning); void currentBiddingRoundChanged(int round, bool isRunning);
void biddingsChanged(int round, QList<bidding> biddings); void biddingsChanged(QList<bidding> biddings);
void onlineUserAccountReceived(const QString mailAddress, void onlineUserAccountReceived(const QString mailAddress,
const QString uuid, const QString uuid,
const QString accessToken); const QString accessToken);
@ -58,12 +66,17 @@ class ServerCommunicator : public QObject {
QString m_email; QString m_email;
QString m_password; QString m_password;
// QString m_authToken; QString m_authToken;
QByteArray createLoginBody();
/// reply parser /// reply parser
void handleLogInReply(const QJsonDocument jsonDoc);
void currentBiddingRoundChangedReply(const QJsonDocument jsonDoc); void currentBiddingRoundChangedReply(const QJsonDocument jsonDoc);
void currentBiddingsReply(const QJsonDocument jsonDoc); void currentBiddingsReply(const QJsonDocument jsonDoc);
void onlineUserAccountReply(const QJsonDocument jsonDoc); void onlineUserAccountReply(const QJsonDocument jsonDoc);
void mailInviteSentReply(const QJsonDocument jsonDoc);
}; };
#endif // SERVERCOMMUNICATOR_H #endif // SERVERCOMMUNICATOR_H

View File

@ -4,7 +4,7 @@
#include <QUuid> #include <QUuid>
struct bidding { struct bidding {
QUuid userId; QString userId;
int biddingRound; int biddingRound;
int amount; int amount;
QString depotWishOne; QString depotWishOne;