Imported existing sources

This commit is contained in:
0xFEEDC0DE64
2018-09-17 19:51:36 +02:00
parent 7b23f62b91
commit 3081d7de2d
155 changed files with 9172 additions and 0 deletions

33
.gitmodules vendored Normal file
View File

@@ -0,0 +1,33 @@
[submodule "plugins/absenceplugin"]
path = plugins/absenceplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-absenceplugin.git
[submodule "plugins/advancedviewplugin"]
path = plugins/advancedviewplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-advancedviewplugin.git
[submodule "plugins/devtoolsplugin"]
path = plugins/devtoolsplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-devtoolsplugin.git
[submodule "plugins/lunchmealplugin"]
path = plugins/lunchmealplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-lunchmealplugin.git
[submodule "plugins/presenceplugin"]
path = plugins/presenceplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-presenceplugin.git
[submodule "plugins/profileplugin"]
path = plugins/profileplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-profileplugin.git
[submodule "plugins/reportsplugin"]
path = plugins/reportsplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-reportsplugin.git
[submodule "plugins/sketchplugin"]
path = plugins/sketchplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-sketchplugin.git
[submodule "plugins/updaterplugin"]
path = plugins/updaterplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-updaterplugin.git
[submodule "plugins/weatherplugin"]
path = plugins/weatherplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-weatherplugin.git
[submodule "plugins/webradioplugin"]
path = plugins/webradioplugin
url = https://github.com/0xFEEDC0DE64/DbZeiterfassung-webradioplugin.git

10
DbZeiterfassung.pro Normal file
View File

@@ -0,0 +1,10 @@
TEMPLATE = subdirs
SUBDIRS += plugins \
zeiterfassung \
zeiterfassungcorelib \
zeiterfassungguilib
plugins.depends += zeiterfassungcorelib zeiterfassungguilib
zeiterfassung.depends += zeiterfassungcorelib zeiterfassungguilib
zeiterfassungguilib.depends += zeiterfassungcorelib

1
plugins/absenceplugin Submodule

Submodule plugins/absenceplugin added at af02fa79fd

5
plugins/plugin.pri Normal file
View File

@@ -0,0 +1,5 @@
PROJECT_ROOT = ../../..
TEMPLATE = lib
CONFIG += shared
DESTDIR = $${OUT_PWD}/$${PROJECT_ROOT}/bin/plugins/zeiterfassung
include(../../project.pri)

15
plugins/plugins.pro Normal file
View File

@@ -0,0 +1,15 @@
TEMPLATE = subdirs
SUBDIRS += absenceplugin \
advancedviewplugin \
devtoolsplugin \
lunchmealplugin \
profileplugin \
presenceplugin \
reportsplugin \
sketchplugin \
updaterplugin \
weatherplugin \
webradioplugin
OTHER_FILES += plugin.pri

1
plugins/profileplugin Submodule

Submodule plugins/profileplugin added at c1f1b884ff

1
plugins/reportsplugin Submodule

Submodule plugins/reportsplugin added at b24ac9e00a

1
plugins/sketchplugin Submodule

Submodule plugins/sketchplugin added at 30fad70d72

1
plugins/updaterplugin Submodule

Submodule plugins/updaterplugin added at 26da75bf63

1
plugins/weatherplugin Submodule

Submodule plugins/weatherplugin added at 1b5a7563f6

0
win32/Qt.conf Normal file
View File

BIN
zeiterfassung/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1,52 @@
themesInstall.path = $${DESTDIR}/themes
themesInstall.files = themes/dark_theme.qss
INSTALLS += themesInstall
darkThemeInstall.path = $${DESTDIR}/themes/dark_theme
darkThemeInstall.files = themes/dark_theme/checkbox_indeterminate_disabled.png \
themes/dark_theme/radio_unchecked.png \
themes/dark_theme/up_arrow.png \
themes/dark_theme/branch_closed-on.png \
themes/dark_theme/checkbox_checked_disabled.png \
themes/dark_theme/checkbox_unchecked.png \
themes/dark_theme/checkbox_indeterminate.png \
themes/dark_theme/stylesheet-branch-more.png \
themes/dark_theme/checkbox_checked.png \
themes/dark_theme/checkbox_unchecked_disabled.png \
themes/dark_theme/radio_checked.png \
themes/dark_theme/checkbox_indeterminate_focus.png \
themes/dark_theme/checkbox_checked_focus.png \
themes/dark_theme/branch_closed.png \
themes/dark_theme/Vsepartoolbar.png \
themes/dark_theme/radio_checked_disabled.png \
themes/dark_theme/left_arrow.png \
themes/dark_theme/Vmovetoolbar.png \
themes/dark_theme/branch_open-on.png \
themes/dark_theme/close.png \
themes/dark_theme/stylesheet-branch-end.png \
themes/dark_theme/stylesheet-vline.png \
themes/dark_theme/down_arrow_disabled.png \
themes/dark_theme/radio_unchecked_disabled.png \
themes/dark_theme/left_arrow_disabled.png \
themes/dark_theme/Hmovetoolbar.png \
themes/dark_theme/close-pressed.png \
themes/dark_theme/up_arrow_disabled.png \
themes/dark_theme/branch_open.png \
themes/dark_theme/radio_checked_focus.png \
themes/dark_theme/sizegrip.png \
themes/dark_theme/checkbox_unchecked_focus.png \
themes/dark_theme/right_arrow_disabled.png \
themes/dark_theme/Hsepartoolbar.png \
themes/dark_theme/undock.png \
themes/dark_theme/transparent.png \
themes/dark_theme/close-hover.png \
themes/dark_theme/radio_unchecked_focus.png \
themes/dark_theme/down_arrow.png \
themes/dark_theme/right_arrow.png
INSTALLS += darkThemeInstall
stripLayoutsInstall.path = $${DESTDIR}/strips
stripLayoutsInstall.files = strips/bookingstartstrip.ui \
strips/bookingendstrip.ui \
strips/timeassignmentstrip.ui
INSTALLS += stripLayoutsInstall

379
zeiterfassung/main.cpp Executable file
View File

@@ -0,0 +1,379 @@
#include <memory>
#include <QApplication>
#include <QTranslator>
#include <QMessageBox>
#include <QSplashScreen>
#include <QPixmap>
#include <QLocale>
#include <QTranslator>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QFileInfo>
#include <QInputDialog>
#include <QStringBuilder>
#include <QLibrary>
#include <QPluginLoader>
#include <QDebug>
#include "zeiterfassungsettings.h"
#include "dialogs/languageselectiondialog.h"
#include "zeiterfassungapi.h"
#include "dialogs/authenticationdialog.h"
#include "zeiterfassungplugin.h"
#include "mainwindow.h"
#include "replies/loginpagereply.h"
#include "replies/loginreply.h"
#include "replies/getuserinforeply.h"
#include "stripfactory.h"
struct {
QTranslator qtTranslator;
QTranslator zeiterfassungTranslator;
QTranslator zeiterfassungcorelibTranslator;
QTranslator zeiterfassungguilibTranslator;
} translators;
QSet<ZeiterfassungPlugin*> plugins;
bool loadAndInstallTranslator(QTranslator &translator, const QString &filename)
{
static auto dir = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("translations"));
if(!translator.load(QLocale(), filename, QStringLiteral("_"), dir))
{
qWarning() << "could not load translation" << filename;
return false;
}
if(!QCoreApplication::installTranslator(&translator))
{
qWarning() << "could not install translation" << filename;
return false;
}
return true;
}
bool loadTranslations(QSplashScreen &splashScreen, ZeiterfassungSettings &settings)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Loading translations..."), Qt::AlignHCenter | Qt::AlignBottom);
if(settings.language() == QLocale::AnyLanguage)
{
LanguageSelectionDialog dialog(&splashScreen);
again:
if(dialog.exec() != QDialog::Accepted)
return false;
if(dialog.language() == QLocale::AnyLanguage)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Invalid language selection!"),
QCoreApplication::translate("main", "Invalid language selection!") % "\n\n" %
QCoreApplication::translate("main", "You did not select a valid language!"));
goto again;
}
settings.setLanguage(dialog.language());
}
QLocale::setDefault(QLocale(settings.language(), QLocale::Austria));
loadAndInstallTranslator(translators.qtTranslator, QStringLiteral("qt"));
loadAndInstallTranslator(translators.zeiterfassungTranslator, QStringLiteral("zeiterfassung"));
loadAndInstallTranslator(translators.zeiterfassungcorelibTranslator, QStringLiteral("zeiterfassungcorelib"));
loadAndInstallTranslator(translators.zeiterfassungguilibTranslator, QStringLiteral("zeiterfassungguilib"));
return true;
}
bool loadTheme(QSplashScreen &splashScreen, ZeiterfassungSettings &settings)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Loading theme..."), Qt::AlignHCenter | Qt::AlignBottom);
if(settings.theme().isEmpty())
return true;
auto themePath = QDir(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("themes"))).absoluteFilePath(settings.theme());
QFile file(themePath % ".qss");
if(!file.exists())
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load theme!"),
QCoreApplication::translate("main", "Could not load theme!") % "\n\n" %
QCoreApplication::translate("main", "Theme file does not exist!"));
return false;
}
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load theme!"),
QCoreApplication::translate("main", "Could not load theme!") % "\n\n" %
file.errorString());
return false;
}
QTextStream textStream(&file);
qApp->setStyleSheet(textStream.readAll().replace(QStringLiteral("@THEME_RESOURCES@"), themePath));
return true;
}
bool loadStripLayouts(QSplashScreen &splashScreen, StripFactory &stripFactory)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Loading strip layouts..."), Qt::AlignHCenter | Qt::AlignBottom);
if(!stripFactory.load(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("strips"))))
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return false;
}
{
auto widget = stripFactory.createBookingStartStrip();
if(!widget)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return false;
}
}
{
auto widget = stripFactory.createBookingEndStrip();
if(!widget)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return false;
}
}
{
auto widget = stripFactory.createTimeAssignmentStrip();
if(!widget)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return false;
}
}
return true;
}
bool loadLoginPage(QSplashScreen &splashScreen, ZeiterfassungSettings &settings, ZeiterfassungApi &erfassung)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Loading login page..."), Qt::AlignHCenter | Qt::AlignBottom);
again:
auto reply = erfassung.doLoginPage();
reply->waitForFinished();
if(!reply->success())
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not access Zeiterfassung!"),
QCoreApplication::translate("main", "Could not access Zeiterfassung!") % "\n\n" % reply->message());
inputAgain:
bool ok;
auto text = QInputDialog::getText(&splashScreen, QCoreApplication::translate("main", "Base url"),
QCoreApplication::translate("main", "Please enter the base url to the Zeiterfassung:"),
QLineEdit::Normal, settings.url().toString(), &ok);
if(!ok)
return false;
auto url = QUrl::fromUserInput(text);
if(!url.isValid())
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Invalid url!"),
QCoreApplication::translate("main", "This url is not valid!"));
goto inputAgain;
}
settings.setUrl(url);
erfassung.setUrl(url);
goto again;
}
return true;
}
bool doAuthentication(QSplashScreen &splashScreen, ZeiterfassungSettings &settings, ZeiterfassungApi &erfassung)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Authenticating..."), Qt::AlignHCenter | Qt::AlignBottom);
if(settings.username().isNull() || settings.password().isNull())
{
AuthenticationDialog dialog(&splashScreen);
if(dialog.exec() != QDialog::Accepted)
return false;
settings.setUsername(dialog.username());
settings.setPassword(dialog.password());
}
{
again:
auto reply = erfassung.doLogin(settings.username(), settings.password());
reply->waitForFinished();
if(!reply->success())
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not authenticate with Zeiterfassung!"),
QCoreApplication::translate("main", "Could not authenticate with Zeiterfassung!") % "\n\n" % reply->message());
AuthenticationDialog dialog(&splashScreen);
dialog.setUsername(settings.username());
dialog.setPassword(settings.password());
if(dialog.exec() != QDialog::Accepted)
return false;
settings.setUsername(dialog.username());
settings.setPassword(dialog.password());
goto again;
}
}
return true;
}
bool loadUserInfo(QSplashScreen &splashScreen, ZeiterfassungApi &erfassung, GetUserInfoReply::UserInfo &userInfo)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Getting user information..."), Qt::AlignHCenter | Qt::AlignBottom);
{
auto reply = erfassung.doUserInfo();
reply->waitForFinished();
if(!reply->success())
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not get user information!"),
QCoreApplication::translate("main", "Could not get user information!") % "\n\n" % reply->message());
return false;
}
userInfo = reply->userInfo();
}
return true;
}
bool loadPlugins(QSplashScreen &splashScreen)
{
auto ok = true;
QDir dir(
QDir(
QDir(
QCoreApplication::applicationDirPath()
).absoluteFilePath(QStringLiteral("plugins"))
).absoluteFilePath(QStringLiteral("zeiterfassung"))
);
for(const auto &fileInfo : dir.entryInfoList(QDir::Files | QDir::NoSymLinks))
{
if(!QLibrary::isLibrary(fileInfo.filePath()))
{
qWarning() << "skipping" << fileInfo.fileName() << "because no QLibrary";
continue; // to skip windows junk files
}
QPluginLoader pluginLoader(fileInfo.filePath());
if(!pluginLoader.load())
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load plugin %0!").arg(fileInfo.fileName()),
QCoreApplication::translate("main", "Could not load plugin %0!").arg(fileInfo.fileName()) %
"\n\n" % pluginLoader.errorString());
ok = false;
continue;
}
if(auto plugin = qobject_cast<ZeiterfassungPlugin*>(pluginLoader.instance()))
plugins.insert(plugin);
else
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Plugin not valid %0!"),
QCoreApplication::translate("main", "Plugin not valid %0!").arg(pluginLoader.fileName()) %
"\n\n" % pluginLoader.errorString());
}
return ok;
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
qSetMessagePattern(QStringLiteral("%{time dd.MM.yyyy HH:mm:ss.zzz} "
"["
"%{if-debug}D%{endif}"
"%{if-info}I%{endif}"
"%{if-warning}W%{endif}"
"%{if-critical}C%{endif}"
"%{if-fatal}F%{endif}"
"] "
"%{function}(): "
"%{message}"));
QCoreApplication::setOrganizationDomain(QStringLiteral("brunner.ninja"));
QCoreApplication::setOrganizationName(QStringLiteral("db-software"));
QCoreApplication::setApplicationName(QStringLiteral("zeiterfassung"));
QCoreApplication::setApplicationVersion(QStringLiteral("1.5"));
QSplashScreen splashScreen(QPixmap(QStringLiteral(":/zeiterfassung/images/splash.png")));
splashScreen.showMessage(QCoreApplication::translate("main", "Loading settings..."), Qt::AlignHCenter | Qt::AlignBottom);
splashScreen.show();
ZeiterfassungSettings settings(&app);
if(!loadTranslations(splashScreen, settings))
return -1;
// not critical if it fails
//if(!loadTheme(splashScreen, settings))
// return -2;
loadTheme(splashScreen, settings);
StripFactory stripFactory(&app);
if(!loadStripLayouts(splashScreen, stripFactory))
return -3;
ZeiterfassungApi erfassung(settings.url().toString(), &app);
if(!loadLoginPage(splashScreen, settings, erfassung))
return -4;
if(!doAuthentication(splashScreen, settings, erfassung))
return -5;
GetUserInfoReply::UserInfo userInfo;
if(!loadUserInfo(splashScreen, erfassung, userInfo))
return -6;
loadPlugins(splashScreen);
MainWindow mainWindow(settings, erfassung, userInfo, stripFactory, plugins);
splashScreen.finish(&mainWindow);
for(auto &plugin : plugins)
plugin->attachTo(mainWindow);
mainWindow.show();
return app.exec();
}

View File

@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>bookingEndStrip</class>
<widget class="QFrame" name="bookingEndStrip">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>44</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QLabel { color: black; } #bookingEndStrip { background-color: qlineargradient( x1:0 y1:0, x2:0 y2:1, stop:0 #FF7F7F, stop:1 #BF6F6F); }</string>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" stretch="0,1,0,0">
<property name="spacing">
<number>10</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="labelTime">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QLabel { background-color: qlineargradient( x1:0 y1:0, x2:0 y2:1, stop:0 #EEEEEE, stop:1 #BBBBBB); }</string>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string notr="true">9:99</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelType">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string>END</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelDuration">
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string notr="true">9:99h</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelId">
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string notr="true">0123456</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>bookingStartStrip</class>
<widget class="QFrame" name="bookingStartStrip">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>44</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QLabel { color: black; } #bookingStartStrip { background-color: qlineargradient( x1:0 y1:0, x2:0 y2:1, stop:0 #7FFF7F, stop:1 #6FBF6F); }</string>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" stretch="0,1,0">
<property name="spacing">
<number>10</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="labelTime">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QLabel { background-color: qlineargradient( x1:0 y1:0, x2:0 y2:1, stop:0 #EEEEEE, stop:1 #BBBBBB); }</string>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string notr="true">9:99</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelType">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string>START</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelId">
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string notr="true">0123456</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>timeAssignmentStrip</class>
<widget class="QFrame" name="timeAssignmentStrip">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>73</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QLabel { color: black; } #timeAssignmentStrip { background-color: qlineargradient( x1:0 y1:0, x2:0 y2:1, stop:0 #7FFFFF, stop:1 #6FBFBF); }</string>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" stretch="0,0">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<layout class="QHBoxLayout" stretch="0,1,0">
<property name="spacing">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="labelTime">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QLabel { background-color: qlineargradient( x1:0 y1:0, x2:0 y2:1, stop:0 #EEEEEE, stop:1 #BBBBBB); }</string>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string notr="true">9:99</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelProject">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string notr="true">PROJECT 1
12345</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelId">
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string notr="true">0123456</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" stretch="0,0,1">
<item>
<widget class="QLabel" name="labelSubproject">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string notr="true">Subproject</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelWorkpackage">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string notr="true">Workpackage</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelText">
<property name="styleSheet">
<string notr="true">background-color: rgba(0,0,0,30);</string>
</property>
<property name="text">
<string notr="true">Text</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de_DE">
<context>
<name>bookingEndStrip</name>
<message>
<location filename="../strips/bookingendstrip.ui" line="72"/>
<source>END</source>
<translation>GEHEN</translation>
</message>
</context>
<context>
<name>bookingStartStrip</name>
<message>
<location filename="../strips/bookingstartstrip.ui" line="72"/>
<source>START</source>
<translation>KOMMEN</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.cpp" line="320"/>
<source>Loading settings...</source>
<translation>Lade Einstellungen...</translation>
</message>
<message>
<location filename="../main.cpp" line="60"/>
<source>Loading translations...</source>
<translation>Lade Übersetzungen...</translation>
</message>
<message>
<location filename="../main.cpp" line="72"/>
<location filename="../main.cpp" line="73"/>
<source>Invalid language selection!</source>
<translation>Ungültige Sprachauswahl!</translation>
</message>
<message>
<location filename="../main.cpp" line="74"/>
<source>You did not select a valid language!</source>
<translation>Sie haben keine gültige Sprachauswahl getroffen!</translation>
</message>
<message>
<location filename="../main.cpp" line="92"/>
<source>Loading theme...</source>
<translation>Lade Aussehen...</translation>
</message>
<message>
<location filename="../main.cpp" line="103"/>
<location filename="../main.cpp" line="104"/>
<location filename="../main.cpp" line="111"/>
<location filename="../main.cpp" line="112"/>
<source>Could not load theme!</source>
<translation>Konnte Aussehen nicht laden!</translation>
</message>
<message>
<location filename="../main.cpp" line="105"/>
<source>Theme file does not exist!</source>
<translation>Aussehen-Datei existiert nicht!</translation>
</message>
<message>
<location filename="../main.cpp" line="169"/>
<source>Loading login page...</source>
<translation>Lade Login-Seite...</translation>
</message>
<message>
<location filename="../main.cpp" line="178"/>
<location filename="../main.cpp" line="179"/>
<source>Could not access Zeiterfassung!</source>
<translation>Konnte Zeiterfassung nicht erreichen!</translation>
</message>
<message>
<location filename="../main.cpp" line="182"/>
<source>Base url</source>
<translation>Basis URL</translation>
</message>
<message>
<location filename="../main.cpp" line="183"/>
<source>Please enter the base url to the Zeiterfassung:</source>
<translation>Bitte geben Sie die Basis URL zur Zeiterfassung ein:</translation>
</message>
<message>
<location filename="../main.cpp" line="200"/>
<source>Authenticating...</source>
<translation>Authentifiziere...</translation>
</message>
<message>
<location filename="../main.cpp" line="221"/>
<location filename="../main.cpp" line="222"/>
<source>Could not authenticate with Zeiterfassung!</source>
<translation>Konnte nicht mit Zeiterfassung authentifizieren!</translation>
</message>
<message>
<location filename="../main.cpp" line="243"/>
<source>Getting user information...</source>
<translation>Hole Benutzer Information...</translation>
</message>
<message>
<location filename="../main.cpp" line="252"/>
<location filename="../main.cpp" line="253"/>
<source>Could not get user information!</source>
<translation>Konnte Benutzer Information nicht holen!</translation>
</message>
<message>
<location filename="../main.cpp" line="286"/>
<location filename="../main.cpp" line="287"/>
<source>Could not load plugin %0!</source>
<translation>Konnte Plugin %0 nicht laden!</translation>
</message>
<message>
<location filename="../main.cpp" line="360"/>
<location filename="../main.cpp" line="361"/>
<source>Plugin not valid %0!</source>
<translation>Plugin %0 nicht gültig!</translation>
</message>
<message>
<location filename="../main.cpp" line="125"/>
<source>Loading strip layouts...</source>
<translation>Lade Streifenlayouts...</translation>
</message>
<message>
<location filename="../main.cpp" line="129"/>
<location filename="../main.cpp" line="130"/>
<location filename="../main.cpp" line="138"/>
<location filename="../main.cpp" line="139"/>
<location filename="../main.cpp" line="148"/>
<location filename="../main.cpp" line="149"/>
<location filename="../main.cpp" line="158"/>
<location filename="../main.cpp" line="159"/>
<source>Could not load strips!</source>
<translation>Konnte Streifenlayouts nicht laden!</translation>
</message>
</context>
</TS>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
<name>bookingEndStrip</name>
<message>
<location filename="../strips/bookingendstrip.ui" line="72"/>
<source>END</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>bookingStartStrip</name>
<message>
<location filename="../strips/bookingstartstrip.ui" line="72"/>
<source>START</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.cpp" line="320"/>
<source>Loading settings...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="60"/>
<source>Loading translations...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="72"/>
<location filename="../main.cpp" line="73"/>
<source>Invalid language selection!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="74"/>
<source>You did not select a valid language!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="92"/>
<source>Loading theme...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="103"/>
<location filename="../main.cpp" line="104"/>
<location filename="../main.cpp" line="111"/>
<location filename="../main.cpp" line="112"/>
<source>Could not load theme!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="105"/>
<source>Theme file does not exist!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="169"/>
<source>Loading login page...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="178"/>
<location filename="../main.cpp" line="179"/>
<source>Could not access Zeiterfassung!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="182"/>
<source>Base url</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="183"/>
<source>Please enter the base url to the Zeiterfassung:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="200"/>
<source>Authenticating...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="221"/>
<location filename="../main.cpp" line="222"/>
<source>Could not authenticate with Zeiterfassung!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="243"/>
<source>Getting user information...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="252"/>
<location filename="../main.cpp" line="253"/>
<source>Could not get user information!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="286"/>
<location filename="../main.cpp" line="287"/>
<source>Could not load plugin %0!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="360"/>
<location filename="../main.cpp" line="361"/>
<source>Plugin not valid %0!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="125"/>
<source>Loading strip layouts...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="129"/>
<location filename="../main.cpp" line="130"/>
<location filename="../main.cpp" line="138"/>
<location filename="../main.cpp" line="139"/>
<location filename="../main.cpp" line="148"/>
<location filename="../main.cpp" line="149"/>
<location filename="../main.cpp" line="158"/>
<location filename="../main.cpp" line="159"/>
<source>Could not load strips!</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

25
zeiterfassung/zeiterfassung.pro Executable file
View File

@@ -0,0 +1,25 @@
QT += core network gui widgets
DBLIBS += zeiterfassungcore zeiterfassunggui
TARGET = zeiterfassung
PROJECT_ROOT = ../..
RC_ICONS = icon.ico
SOURCES += main.cpp
HEADERS +=
FORMS += strips/bookingstartstrip.ui \
strips/bookingendstrip.ui \
strips/timeassignmentstrip.ui
RESOURCES += zeiterfassung_resources.qrc
TRANSLATIONS += translations/zeiterfassung_en.ts \
translations/zeiterfassung_de.ts
include($${PROJECT_ROOT}/app.pri)
include(installs.pri)

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/zeiterfassung">
<file>images/splash.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,43 @@
#pragma once
#if __cplusplus < 201402L && _MSC_VER < 1800
// std includes
#include <memory>
#include <cstddef>
#include <memory>
#include <type_traits>
#include <utility>
namespace std {
template<class T> struct _Unique_if {
typedef unique_ptr<T> _Single_object;
};
template<class T> struct _Unique_if<T[]> {
typedef unique_ptr<T[]> _Unknown_bound;
};
template<class T, size_t N> struct _Unique_if<T[N]> {
typedef void _Known_bound;
};
template<class T, class... Args>
typename _Unique_if<T>::_Single_object
make_unique(Args&&... args) {
return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
template<class T>
typename _Unique_if<T>::_Unknown_bound
make_unique(size_t n) {
typedef typename remove_extent<T>::type U;
return unique_ptr<T>(new U[n]());
}
template<class T, class... Args>
typename _Unique_if<T>::_Known_bound
make_unique(Args&&...) = delete;
}
#endif // __cplusplus < 201402L

View File

@@ -0,0 +1,26 @@
#include "createbookingreply.h"
CreateBookingReply::CreateBookingReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &CreateBookingReply::requestFinished);
}
void CreateBookingReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
// empty response so nothing to check
setSuccess(true);
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZEITERFASSUNGCORELIB_EXPORT CreateBookingReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit CreateBookingReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
};

View File

@@ -0,0 +1,64 @@
#include "createtimeassignmentreply.h"
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
CreateTimeAssignmentReply::CreateTimeAssignmentReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply)),
m_timeAssignmentId(-1)
{
connect(m_reply.get(), &QNetworkReply::finished, this, &CreateTimeAssignmentReply::requestFinished);
}
int CreateTimeAssignmentReply::timeAssignmentId() const
{
return m_timeAssignmentId;
}
void CreateTimeAssignmentReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
{
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON failed: %0").arg(error.errorString()));
goto end;
}
if(!document.isObject())
{
setSuccess(false);
setMessage(tr("JSON document is not an object!"));
goto end;
}
auto obj = document.object();
if(!obj.contains(QStringLiteral("bookingNr")))
{
setSuccess(false);
setMessage(tr("JSON does not contain bookingNr!"));
goto end;
}
setSuccess(true);
m_timeAssignmentId = obj.value(QStringLiteral("bookingNr")).toInt();
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZEITERFASSUNGCORELIB_EXPORT CreateTimeAssignmentReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit CreateTimeAssignmentReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
int timeAssignmentId() const;
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
int m_timeAssignmentId;
};

View File

@@ -0,0 +1,27 @@
#include "deletebookingreply.h"
DeleteBookingReply::DeleteBookingReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &DeleteBookingReply::requestFinished);
}
void DeleteBookingReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
//should be empty, so nothing to check...
setSuccess(true);
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZEITERFASSUNGCORELIB_EXPORT DeleteBookingReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit DeleteBookingReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
};

View File

@@ -0,0 +1,27 @@
#include "deletetimeassignmentreply.h"
DeleteTimeAssignmentReply::DeleteTimeAssignmentReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &DeleteTimeAssignmentReply::requestFinished);
}
void DeleteTimeAssignmentReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
//only contains deleted id, so nothing to check here
setSuccess(true);
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZEITERFASSUNGCORELIB_EXPORT DeleteTimeAssignmentReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit DeleteTimeAssignmentReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
};

View File

@@ -0,0 +1,77 @@
#include "getabsencesreply.h"
#include <QDebug>
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonObject>
#include "zeiterfassungapi.h"
GetAbsencesReply::GetAbsencesReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &GetAbsencesReply::requestFinished);
}
const QVector<GetAbsencesReply::Absence> &GetAbsencesReply::absences() const
{
return m_absences;
}
void GetAbsencesReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
{
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON failed: %0").arg(error.errorString()));
goto end;
}
if(!document.isArray())
{
setSuccess(false);
setMessage(tr("JSON document is not an array!"));
goto end;
}
auto arr = document.array();
setSuccess(true);
m_absences.clear();
m_absences.reserve(arr.count());
for(const auto &val : arr)
{
auto obj = val.toObject();
m_absences.append({
obj.value(QStringLiteral("altRepresentative")).toInt(),
obj.value(QStringLiteral("compositeId")).toString(),
parseDate(obj.value(QStringLiteral("end"))),
obj.value(QStringLiteral("hourCategory")).toString(),
obj.value(QStringLiteral("openMarking")).toString(),
obj.value(QStringLiteral("persNr")).toInt(),
obj.value(QStringLiteral("representative")).toInt(),
parseDate(obj.value(QStringLiteral("start"))),
obj.value(QStringLiteral("text")).toString()
});
}
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,43 @@
#pragma once
#include <memory>
#include <QString>
#include <QDate>
#include <QNetworkReply>
#include <QVector>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZeiterfassungApi;
class ZEITERFASSUNGCORELIB_EXPORT GetAbsencesReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit GetAbsencesReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
struct Absence
{
int altRepresentative;
QString compositeId;
QDate end;
QString hourCategory;
QString openMarking;
int persNr;
int representative;
QDate start;
QString text;
};
const QVector<Absence> &absences() const;
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
QVector<Absence> m_absences;
};

View File

@@ -0,0 +1,73 @@
#include "getbookingsreply.h"
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonObject>
#include "zeiterfassungapi.h"
GetBookingsReply::GetBookingsReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &GetBookingsReply::requestFinished);
}
const QVector<GetBookingsReply::Booking> &GetBookingsReply::bookings() const
{
return m_bookings;
}
void GetBookingsReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
{
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON failed: %0").arg(error.errorString()));
goto end;
}
if(!document.isArray())
{
setSuccess(false);
setMessage(tr("JSON document is not an array!"));
goto end;
}
auto arr = document.array();
setSuccess(true);
m_bookings.clear();
m_bookings.reserve(arr.count());
for(const auto &val : arr)
{
auto obj = val.toObject();
m_bookings.append({
obj.value(QStringLiteral("bookingNr")).toInt(),
parseDate(obj.value(QStringLiteral("bookingDate"))),
parseTime(obj.value(QStringLiteral("bookingTime"))),
parseTime(obj.value(QStringLiteral("bookingTimespan"))),
obj.value(QStringLiteral("bookingType")).toString(),
obj.value(QStringLiteral("text")).toString()
});
}
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include <memory>
#include <QDate>
#include <QNetworkReply>
#include <QVector>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZeiterfassungApi;
class ZEITERFASSUNGCORELIB_EXPORT GetBookingsReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit GetBookingsReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
struct Booking
{
int id;
QDate date;
QTime time;
QTime timespan;
QString type;
QString text;
};
const QVector<Booking> &bookings() const;
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
QVector<Booking> m_bookings;
};

View File

@@ -0,0 +1,74 @@
#include "getdayinforeply.h"
#include <QDebug>
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonObject>
#include "zeiterfassungapi.h"
GetDayinfoReply::GetDayinfoReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &GetDayinfoReply::requestFinished);
}
const QVector<GetDayinfoReply::Dayinfo> &GetDayinfoReply::dayinfos() const
{
return m_dayinfos;
}
void GetDayinfoReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
{
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON failed: %0").arg(error.errorString()));
goto end;
}
if(!document.isArray())
{
setSuccess(false);
setMessage(tr("JSON document is not an array!"));
goto end;
}
auto arr = document.array();
setSuccess(true);
m_dayinfos.clear();
m_dayinfos.reserve(arr.count());
for(const auto &val : arr)
{
auto obj = val.toObject();
m_dayinfos.append({
obj.value(QStringLiteral("className")).toString(),
obj.value(QStringLiteral("persNr")).toInt(),
parseDate(obj.value(QStringLiteral("date"))),
parseTime(obj.value(QStringLiteral("ist"))),
parseTime(obj.value(QStringLiteral("soll"))),
obj.value(QStringLiteral("compositeId")).toString()
});
}
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include <memory>
#include <QString>
#include <QDate>
#include <QNetworkReply>
#include <QVector>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZeiterfassungApi;
class ZEITERFASSUNGCORELIB_EXPORT GetDayinfoReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit GetDayinfoReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
struct Dayinfo
{
QString className;
int userId;
QDate date;
QTime ist;
QTime soll;
QString compositeId;
};
const QVector<Dayinfo> &dayinfos() const;
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
QVector<Dayinfo> m_dayinfos;
};

View File

@@ -0,0 +1,71 @@
#include "getpresencestatusreply.h"
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonObject>
#include "zeiterfassungapi.h"
GetPresenceStatusReply::GetPresenceStatusReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &GetPresenceStatusReply::requestFinished);
}
const QVector<GetPresenceStatusReply::PresenceStatus> &GetPresenceStatusReply::presenceStatuses() const
{
return m_presenceStatuses;
}
void GetPresenceStatusReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
{
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON failed: %0").arg(error.errorString()));
goto end;
}
if(!document.isArray())
{
setSuccess(false);
setMessage(tr("JSON document is not an array!"));
goto end;
}
auto arr = document.array();
setSuccess(true);
m_presenceStatuses.clear();
m_presenceStatuses.reserve(arr.count());
for(const auto &val : arr)
{
auto obj = val.toObject();
m_presenceStatuses.append({
obj.value(QStringLiteral("persNr")).toInt(),
obj.value(QStringLiteral("firstName")).toString(),
obj.value(QStringLiteral("lastName")).toString(),
obj.value(QStringLiteral("presence")).toString()
});
}
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZeiterfassungApi;
class ZEITERFASSUNGCORELIB_EXPORT GetPresenceStatusReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit GetPresenceStatusReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
struct PresenceStatus
{
int userId;
QString firstName;
QString lastName;
QString presence;
};
const QVector<PresenceStatus> &presenceStatuses() const;
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
QVector<PresenceStatus> m_presenceStatuses;
};

View File

@@ -0,0 +1,87 @@
#include "getprojectsreply.h"
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
#include "zeiterfassungapi.h"
GetProjectsReply::GetProjectsReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &GetProjectsReply::requestFinished);
}
const QVector<GetProjectsReply::Project> &GetProjectsReply::projects() const
{
return m_projects;
}
void GetProjectsReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
{
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON failed: %0").arg(error.errorString()));
goto end;
}
if(!document.isObject())
{
setSuccess(false);
setMessage(tr("JSON document is not an object!"));
goto end;
}
auto rootObj = document.object();
if(!rootObj.contains(QStringLiteral("elements")))
{
setSuccess(false);
setMessage(tr("JSON does not contain elements!"));
goto end;
}
auto elements = rootObj.value(QStringLiteral("elements"));
if(!elements.isArray())
{
setSuccess(false);
setMessage(tr("elements is not an array!"));
goto end;
}
auto elementsArr = elements.toArray();
setSuccess(true);
m_projects.clear();
m_projects.reserve(elementsArr.count());
for(const auto &val : elementsArr)
{
auto obj = val.toObject();
m_projects.append({
obj.value(QStringLiteral("label")).toString(),
obj.value(QStringLiteral("value")).toString()
});
}
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,34 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include <QVector>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZeiterfassungApi;
class ZEITERFASSUNGCORELIB_EXPORT GetProjectsReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit GetProjectsReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
struct Project
{
QString label;
QString value;
};
const QVector<Project> &projects() const;
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
QVector<Project> m_projects;
};

View File

@@ -0,0 +1,51 @@
#include "getreportreply.h"
#include "zeiterfassungapi.h"
GetReportReply::GetReportReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &GetReportReply::request0Finished);
}
const QByteArray &GetReportReply::content() const
{
return m_content;
}
void GetReportReply::request0Finished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
m_reply = Q_NULLPTR;
Q_EMIT finished();
return;
}
QUrl url(zeiterfassung()->url());
url.setPath(QString(m_reply->readAll()));
m_reply = std::unique_ptr<QNetworkReply>(zeiterfassung()->manager()->get(QNetworkRequest(url)));
connect(m_reply.get(), &QNetworkReply::finished, this, &GetReportReply::request1Finished);
}
void GetReportReply::request1Finished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
setSuccess(true);
m_content = m_reply->readAll();
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include <QByteArray>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZEITERFASSUNGCORELIB_EXPORT GetReportReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit GetReportReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
const QByteArray &content() const;
private Q_SLOTS:
void request0Finished();
void request1Finished();
private:
std::unique_ptr<QNetworkReply> m_reply;
QByteArray m_content;
};

View File

@@ -0,0 +1,78 @@
#include "gettimeassignmentsreply.h"
#include <QNetworkReply>
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonObject>
#include "zeiterfassungapi.h"
GetTimeAssignmentsReply::GetTimeAssignmentsReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &GetTimeAssignmentsReply::requestFinished);
}
const QVector<GetTimeAssignmentsReply::TimeAssignment> &GetTimeAssignmentsReply::timeAssignments() const
{
return m_timeAssignments;
}
void GetTimeAssignmentsReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
{
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON failed: %0").arg(error.errorString()));
goto end;
}
if(!document.isArray())
{
setSuccess(false);
setMessage(tr("JSON document is not an array!"));
goto end;
}
auto arr = document.array();
setSuccess(true);
m_timeAssignments.clear();
m_timeAssignments.reserve(arr.count());
for(const auto &val : arr)
{
auto obj = val.toObject();
auto koWertList = obj.value(QStringLiteral("koWertList")).toArray();
m_timeAssignments.append({
obj.value(QStringLiteral("bookingNr")).toInt(),
parseDate(obj.value(QStringLiteral("bookingDate"))),
parseTime(obj.value(QStringLiteral("bookingTime"))),
parseTime(obj.value(QStringLiteral("bookingTimespan"))),
obj.value(QStringLiteral("text")).toString(),
koWertList.at(0).toObject().value(QStringLiteral("value")).toString(),
koWertList.at(1).toObject().value(QStringLiteral("value")).toString(),
koWertList.at(2).toObject().value(QStringLiteral("value")).toString()
});
}
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,42 @@
#pragma once
#include <memory>
#include <QDate>
#include <QTime>
#include <QNetworkReply>
#include <QVector>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZeiterfassungApi;
class ZEITERFASSUNGCORELIB_EXPORT GetTimeAssignmentsReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit GetTimeAssignmentsReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
struct TimeAssignment
{
int id;
QDate date;
QTime time;
QTime timespan;
QString text;
QString project;
QString subproject;
QString workpackage;
};
const QVector<TimeAssignment> &timeAssignments() const;
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
QVector<TimeAssignment> m_timeAssignments;
};

View File

@@ -0,0 +1,170 @@
#include "getuserinforeply.h"
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
#include "zeiterfassungapi.h"
GetUserInfoReply::GetUserInfoReply(std::unique_ptr<QNetworkReply> &&reply0, std::unique_ptr<QNetworkReply> &&reply1,
ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply0(std::move(reply0)),
m_reply1(std::move(reply1))
{
Q_ASSERT(m_reply0 != Q_NULLPTR);
Q_ASSERT(m_reply1 != Q_NULLPTR);
connect(m_reply0.get(), &QNetworkReply::finished, this, &GetUserInfoReply::request0Finished);
connect(m_reply1.get(), &QNetworkReply::finished, this, &GetUserInfoReply::request1Finished);
}
const GetUserInfoReply::UserInfo &GetUserInfoReply::userInfo() const
{
return m_userInfo;
}
void GetUserInfoReply::request0Finished()
{
if(m_reply0->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request 0 error occured: %0").arg(m_reply0->errorString()));
m_reply1 = Q_NULLPTR;
goto end;
}
{
QJsonParseError error;
auto document = QJsonDocument::fromJson(m_reply0->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON 0 failed: %0").arg(error.errorString()));
m_reply1 = Q_NULLPTR;
goto end;
}
if(!document.isObject())
{
setSuccess(false);
setMessage(tr("JSON document 0 is not an object!"));
m_reply1 = Q_NULLPTR;
goto end;
}
auto rootObj = document.object();
if(!rootObj.contains(QStringLiteral("evoAppsUser")))
{
setSuccess(false);
setMessage(tr("JSON 0 does not contain evoAppsUser!"));
m_reply1 = Q_NULLPTR;
goto end;
}
auto evoAppsUser = rootObj.value(QStringLiteral("evoAppsUser"));
if(!evoAppsUser.isObject())
{
setSuccess(false);
setMessage(tr("evoAppsUser is not an object!"));
m_reply1 = Q_NULLPTR;
goto end;
}
auto evoAppsUserObj = evoAppsUser.toObject();
if(!m_reply1)
setSuccess(true);
m_userInfo.userId = evoAppsUserObj.value(QStringLiteral("persNr")).toInt();
m_userInfo.email = evoAppsUserObj.value(QStringLiteral("email")).toString();
m_userInfo.longUsername = evoAppsUserObj.value(QStringLiteral("longUsername")).toString();
m_userInfo.text = evoAppsUserObj.value(QStringLiteral("text")).toString();
m_userInfo.username = evoAppsUserObj.value(QStringLiteral("username")).toString();
}
end:
m_reply0 = Q_NULLPTR;
if(!m_reply1)
Q_EMIT finished();
}
void GetUserInfoReply::request1Finished()
{
if(m_reply1->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request 1 error occured: %0").arg(m_reply0->errorString()));
m_reply0 = Q_NULLPTR;
goto end;
}
{
QJsonParseError error;
auto document = QJsonDocument::fromJson(m_reply1->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON 1 failed: %0").arg(error.errorString()));
m_reply0 = Q_NULLPTR;
goto end;
}
if(!document.isArray())
{
setSuccess(false);
setMessage(tr("JSON document 1 is not an array!"));
m_reply0 = Q_NULLPTR;
goto end;
}
auto arr = document.array();
if(arr.isEmpty())
{
setSuccess(false);
setMessage(tr("JSON array 1 is empty!"));
m_reply0 = Q_NULLPTR;
goto end;
}
auto first = arr.first();
if(!first.isObject())
{
setSuccess(false);
setMessage(tr("JSON array value is not an object!"));
m_reply0 = Q_NULLPTR;
goto end;
}
auto obj = first.toObject();
if(!m_reply0)
setSuccess(true);
m_userInfo.street = obj.value(QStringLiteral("gemeinde")).toString();
m_userInfo.city = obj.value(QStringLiteral("ort")).toString();
m_userInfo.employedSince = parseDate(obj.value(QStringLiteral("angFrom")));
m_userInfo.employedTill = parseDate(obj.value(QStringLiteral("angTill")));
m_userInfo.placeOfBirth = obj.value(QStringLiteral("gebOrt")).toString();
m_userInfo.zipcode = obj.value(QStringLiteral("plz")).toString();
m_userInfo.religion = obj.value(QStringLiteral("religion")).toString();
m_userInfo.department = obj.value(QStringLiteral("bereich")).toString();
m_userInfo.verwendgr = obj.value(QStringLiteral("verwendgr")).toString();
m_userInfo.taetig = obj.value(QStringLiteral("taetig")).toString();
m_userInfo.arbverh = obj.value(QStringLiteral("arbverh")).toString();
m_userInfo.betriebsnr = obj.value(QStringLiteral("betriebsnr")).toString();
}
end:
m_reply1 = Q_NULLPTR;
if(!m_reply0)
Q_EMIT finished();
}

View File

@@ -0,0 +1,53 @@
#pragma once
#include <memory>
#include <QString>
#include <QDate>
#include <QNetworkReply>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZeiterfassungApi;
class ZEITERFASSUNGCORELIB_EXPORT GetUserInfoReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit GetUserInfoReply(std::unique_ptr<QNetworkReply> &&reply0, std::unique_ptr<QNetworkReply> &&reply1,
ZeiterfassungApi *zeiterfassung);
struct UserInfo
{
int userId;
QString email;
QString longUsername;
QString text;
QString username;
QString street;
QString city;
QDate employedSince;
QDate employedTill;
QString placeOfBirth;
QString zipcode;
QString religion;
QString department;
QString verwendgr;
QString taetig;
QString arbverh;
QString betriebsnr;
};
const UserInfo &userInfo() const;
private Q_SLOTS:
void request0Finished();
void request1Finished();
private:
std::unique_ptr<QNetworkReply> m_reply0;
std::unique_ptr<QNetworkReply> m_reply1;
UserInfo m_userInfo;
};

View File

@@ -0,0 +1,34 @@
#include "loginpagereply.h"
#include <QNetworkReply>
LoginPageReply::LoginPageReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &LoginPageReply::requestFinished);
}
void LoginPageReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
if(!m_reply->readAll().contains(QByteArrayLiteral("evoApps Anmeldung")))
{
setSuccess(false);
setMessage(tr("Could not find necessary keywords in login page!"));
goto end;
}
setSuccess(true);
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZEITERFASSUNGCORELIB_EXPORT LoginPageReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit LoginPageReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
};

View File

@@ -0,0 +1,54 @@
#include "loginreply.h"
#include <QNetworkReply>
LoginReply::LoginReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply))
{
connect(m_reply.get(), &QNetworkReply::finished, this, &LoginReply::requestFinished);
}
void LoginReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
if(!m_reply->hasRawHeader(QByteArrayLiteral("Location")))
{
setSuccess(false);
setMessage(tr("Response did not contain a Location header."));
goto end;
}
{
auto location = m_reply->rawHeader(QByteArrayLiteral("Location"));
if(location == QByteArrayLiteral("/evoApps/pages/home.jsp"))
{
setSuccess(true);
goto end;
}
else if(location == QByteArrayLiteral("/evoApps/pages/login.jsp?error=user"))
{
setSuccess(false);
setMessage(tr("Authentication failure. Please check username and password."));
goto end;
}
else
{
setSuccess(false);
setMessage(tr("An unknown authentication failure occured. Redirected to: %0").arg(QString(location)));
goto end;
}
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZEITERFASSUNGCORELIB_EXPORT LoginReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit LoginReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
};

View File

@@ -0,0 +1,59 @@
#include "updatebookingreply.h"
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
UpdateBookingReply::UpdateBookingReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply)),
m_bookingId(-1)
{
connect(m_reply.get(), &QNetworkReply::finished, this, &UpdateBookingReply::requestFinished);
}
void UpdateBookingReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
{
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON failed: %0").arg(error.errorString()));
goto end;
}
if(!document.isObject())
{
setSuccess(false);
setMessage(tr("JSON document is not an object!"));
goto end;
}
auto obj = document.object();
if(!obj.contains(QStringLiteral("bookingNr")))
{
setSuccess(false);
setMessage(tr("JSON does not contain bookingNr!"));
goto end;
}
setSuccess(true);
m_bookingId = obj.value(QStringLiteral("bookingNr")).toInt();
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include <memory>
#include <QNetworkReply>
#include "zeiterfassungcorelib_global.h"
#include "zeiterfassungreply.h"
class ZEITERFASSUNGCORELIB_EXPORT UpdateBookingReply : public ZeiterfassungReply
{
Q_OBJECT
public:
explicit UpdateBookingReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
int m_bookingId;
};

View File

@@ -0,0 +1,64 @@
#include "updatetimeassignmentreply.h"
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
UpdateTimeAssignmentReply::UpdateTimeAssignmentReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung) :
ZeiterfassungReply(zeiterfassung),
m_reply(std::move(reply)),
m_timeAssignmentId(-1)
{
connect(m_reply.get(), &QNetworkReply::finished, this, &UpdateTimeAssignmentReply::requestFinished);
}
int UpdateTimeAssignmentReply::timeAssignmentId() const
{
return m_timeAssignmentId;
}
void UpdateTimeAssignmentReply::requestFinished()
{
if(m_reply->error() != QNetworkReply::NoError)
{
setSuccess(false);
setMessage(tr("Request error occured: %0").arg(m_reply->errorString()));
goto end;
}
{
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll(), &error);
if(error.error != QJsonParseError::NoError)
{
setSuccess(false);
setMessage(tr("Parsing JSON failed: %0").arg(error.errorString()));
goto end;
}
if(!document.isObject())
{
setSuccess(false);
setMessage(tr("JSON document is not an object!"));
goto end;
}
auto obj = document.object();
if(!obj.contains(QStringLiteral("bookingNr")))
{
setSuccess(false);
setMessage(tr("JSON does not contain bookingNr!"));
goto end;
}
setSuccess(true);
m_timeAssignmentId = obj.value(QStringLiteral("bookingNr")).toInt();
}
end:
m_reply = Q_NULLPTR;
Q_EMIT finished();
}

Some files were not shown because too many files have changed in this diff Show More