2018-07-14 14:03:35 +02:00
|
|
|
#include "mainwindow.h"
|
|
|
|
|
2018-07-22 20:10:22 +02:00
|
|
|
#include "basketmodel.h"
|
2019-10-10 13:36:48 +02:00
|
|
|
#include <config.h>
|
2018-07-21 19:24:56 +02:00
|
|
|
#include "pricedialog.h"
|
2018-07-30 09:50:54 +02:00
|
|
|
#include "reportdialog.h"
|
2018-07-25 16:04:45 +02:00
|
|
|
#include "salemodel.h"
|
2018-07-26 08:34:01 +02:00
|
|
|
#include "sellerdialog.h"
|
2018-07-30 13:40:58 +02:00
|
|
|
#include "settingsdialog.h"
|
2018-07-16 12:00:17 +02:00
|
|
|
|
2019-10-10 08:09:16 +02:00
|
|
|
#include <core/csvreader.h>
|
|
|
|
#include <core/excelreader.h>
|
|
|
|
#include <core/jsonutil.h>
|
|
|
|
#include <core/utils.h>
|
|
|
|
#include <printer/posprinter.h>
|
|
|
|
#include <printer/utils.h>
|
2018-08-01 15:36:41 +02:00
|
|
|
|
2018-08-02 15:28:35 +02:00
|
|
|
#include <exception>
|
2018-08-09 08:36:45 +02:00
|
|
|
#include <filesystem>
|
2018-08-09 12:58:11 +02:00
|
|
|
#include <regex>
|
2019-02-25 09:26:21 +01:00
|
|
|
#include <string>
|
2018-07-20 22:07:42 +02:00
|
|
|
|
2018-08-01 15:36:41 +02:00
|
|
|
#include <QFileDialog>
|
2018-07-23 13:39:49 +02:00
|
|
|
#include <QMessageBox>
|
2018-07-30 13:40:58 +02:00
|
|
|
#include <QSettings>
|
2018-08-07 20:39:15 +02:00
|
|
|
#include <QStandardPaths>
|
|
|
|
#include <QtGui/QDesktopServices>
|
2018-07-23 12:49:19 +02:00
|
|
|
|
2018-08-09 16:37:56 +02:00
|
|
|
namespace fs = std::filesystem;
|
|
|
|
|
2018-07-17 10:37:21 +02:00
|
|
|
constexpr int STATUSBAR_TIMEOUT = 5000;
|
|
|
|
|
2018-07-14 14:03:35 +02:00
|
|
|
MainWindow::MainWindow()
|
|
|
|
{
|
2018-07-14 15:54:29 +02:00
|
|
|
ui_.setupUi(this);
|
|
|
|
|
|
|
|
marketplace_ = std::make_unique<Marketplace>();
|
2019-10-04 15:50:13 +02:00
|
|
|
Database::InitResult res = marketplace_->loadFromDb();
|
|
|
|
if (res == Database::InitResult::OUTDATED_REPLACED) {
|
|
|
|
QMessageBox(QMessageBox::Icon::Information, "Datenbankinformation",
|
|
|
|
"Es wurde eine <b>veraltete</b> Datenbankdatei erkannt.<br />Diese wurde "
|
|
|
|
"umbenannt und eine <b>neue</b> Datei wurde erstellt.")
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2019-10-04 15:50:13 +02:00
|
|
|
}
|
2018-07-17 10:37:21 +02:00
|
|
|
statusBar()->showMessage("Gespeicherte Daten wurden geladen.", STATUSBAR_TIMEOUT);
|
2018-07-22 20:10:22 +02:00
|
|
|
|
|
|
|
BasketModel* model = new BasketModel(getMarketplace(), ui_.basketView);
|
|
|
|
ui_.basketView->setModel(model);
|
|
|
|
ui_.basketView->setColumnHidden(0, true); // hide the uuid
|
2018-07-23 12:49:19 +02:00
|
|
|
|
2018-07-30 13:40:58 +02:00
|
|
|
setWindowTitle("KIMA2 - Kasse Nr. " + QSettings().value("global/cashPointNo").toString());
|
|
|
|
|
2019-04-08 10:49:49 +02:00
|
|
|
ui_.salesView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
2018-07-30 19:26:10 +02:00
|
|
|
setSaleModel();
|
|
|
|
|
2019-09-30 10:39:00 +02:00
|
|
|
connect(ui_.actionQuit, &QAction::triggered, qApp, QApplication::closeAllWindows,
|
|
|
|
Qt::QueuedConnection);
|
2018-08-08 10:22:38 +02:00
|
|
|
connect(ui_.newAction, &QAction::triggered, this, [=]() {
|
|
|
|
if (marketplace_->getSellers().size() == 0 && marketplace_->getSales().size() == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto dlgResult =
|
|
|
|
QMessageBox(QMessageBox::Icon::Warning, "Sind Sie sicher?",
|
|
|
|
"Möchten Sie wirklich alle gespeicherten Daten verwerfen?",
|
|
|
|
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, this)
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2018-08-08 10:22:38 +02:00
|
|
|
|
|
|
|
if (dlgResult == QMessageBox::No)
|
|
|
|
return;
|
|
|
|
|
|
|
|
delete ui_.salesView->model();
|
|
|
|
dynamic_cast<BasketModel*>(ui_.basketView->model())->cancelSale();
|
|
|
|
marketplace_->clear();
|
|
|
|
setSaleModel();
|
2018-10-09 08:04:47 +02:00
|
|
|
updateStatLabel();
|
2018-08-08 10:22:38 +02:00
|
|
|
});
|
2018-08-08 13:36:49 +02:00
|
|
|
|
|
|
|
ui_.sellerNoEdit->installEventFilter(this);
|
|
|
|
ui_.givenSpinBox->installEventFilter(this);
|
|
|
|
|
2018-07-23 12:49:19 +02:00
|
|
|
connect(ui_.actionEditSeller, &QAction::triggered, this,
|
2018-07-27 10:16:07 +02:00
|
|
|
&MainWindow::onActionEditSellerTriggered);
|
|
|
|
connect(ui_.paidButton, &QPushButton::clicked, this, &MainWindow::onPaidButtonTriggered);
|
2018-08-08 13:36:49 +02:00
|
|
|
connect(ui_.givenSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
|
|
|
|
&MainWindow::onGivenSpinBoxValueChanged);
|
2018-07-23 12:49:19 +02:00
|
|
|
connect(ui_.basketView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
|
|
|
&MainWindow::onBasketViewSelectionChanged);
|
2018-07-23 13:39:49 +02:00
|
|
|
connect(ui_.cancelArticleButton, &QPushButton::clicked, this,
|
|
|
|
&MainWindow::onCancelArticleButtonClicked);
|
2018-07-27 16:04:01 +02:00
|
|
|
connect(ui_.cancelSaleButton, &QPushButton::clicked, this,
|
|
|
|
&MainWindow::onCancelSaleButtonClicked);
|
2018-08-06 16:14:45 +02:00
|
|
|
connect(ui_.printSaleReceiptButton, &QPushButton::clicked, this,
|
|
|
|
&MainWindow::onPrintSaleReceiptButtonClicked);
|
2018-07-23 13:39:49 +02:00
|
|
|
connect(ui_.cancelAllArticlesButton, &QPushButton::clicked, this,
|
|
|
|
&MainWindow::onCancelAllArticlesButtonClicked);
|
2018-07-29 09:56:37 +02:00
|
|
|
connect(ui_.aboutQtAction, &QAction::triggered, this, &MainWindow::onAboutQt);
|
2018-07-30 16:39:33 +02:00
|
|
|
connect(ui_.aboutAction, &QAction::triggered, this, &MainWindow::onAbout);
|
2018-08-07 20:39:15 +02:00
|
|
|
connect(ui_.openManualAction, &QAction::triggered, this, []() {
|
|
|
|
auto locations = QStandardPaths::standardLocations(QStandardPaths::DataLocation);
|
|
|
|
for (auto location : locations) {
|
|
|
|
if (QFile::exists(location + QString("/Benutzerhandbuch.pdf"))) {
|
2018-08-08 10:22:38 +02:00
|
|
|
QDesktopServices::openUrl(
|
|
|
|
QUrl(QString("file:///") + location + QString("/Benutzerhandbuch.pdf"),
|
|
|
|
QUrl::TolerantMode));
|
2018-08-07 20:39:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2018-08-13 14:26:34 +02:00
|
|
|
connect(ui_.licenseAction, &QAction::triggered, this, [=]() {
|
|
|
|
QString licenseText(
|
2021-09-20 07:39:37 +02:00
|
|
|
"Copyright © 2018-2021 Martin Brodbeck\n\n"
|
2018-08-13 14:26:34 +02:00
|
|
|
"Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der "
|
|
|
|
"zugehörigen Dokumentationen (die \"Software\") erhält, die Erlaubnis erteilt, "
|
|
|
|
"sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, "
|
|
|
|
"sie zu verwenden, zu kopieren, zu verändern, zusammenzufügen, zu "
|
|
|
|
"veröffentlichen, zu verbreiten, und Personen, denen diese Software überlassen "
|
|
|
|
"wird, diese Rechte zu verschaffen, unter den folgenden Bedingungen:\n\n"
|
|
|
|
"Der obige Urheberrechtsvermerk und dieser Erlaubnisvermerk sind in allen "
|
|
|
|
"Kopien oder Teilkopien der Software beizulegen.\n\n"
|
|
|
|
"DIE SOFTWARE WIRD OHNE JEDE AUSDRÜCKLICHE ODER IMPLIZIERTE "
|
|
|
|
"GARANTIE BEREITGESTELLT, EINSCHLIESSLICH DER GARANTIE ZUR BENUTZUNG "
|
|
|
|
"FÜR DEN VORGESEHENEN ODER EINEM BESTIMMTEN ZWECK SOWIE JEGLICHER "
|
|
|
|
"RECHTSVERLETZUNG, JEDOCH NICHT DARAUF BESCHRÄNKT. IN KEINEM FALL "
|
|
|
|
"SIND DIE AUTOREN ODER COPYRIGHTINHABER FÜR JEGLICHEN SCHADEN ODER "
|
|
|
|
"SONSTIGE ANSPRÜCHE HAFTBAR ZU MACHEN, OB INFOLGE DER ERFÜLLUNG "
|
|
|
|
"EINES VERTRAGES, EINES DELIKTES ODER ANDERS IM ZUSAMMENHANG MIT DER "
|
|
|
|
"SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN.");
|
|
|
|
QMessageBox::information(this, "Lizenzinformation", licenseText);
|
|
|
|
});
|
2020-10-15 16:43:00 +02:00
|
|
|
connect(ui_.reportAction, &QAction::triggered, this, [=]() {
|
|
|
|
ReportDialog(this).exec();
|
|
|
|
});
|
2018-07-30 13:40:58 +02:00
|
|
|
connect(ui_.configAction, &QAction::triggered, this, [=]() {
|
2018-07-30 19:26:10 +02:00
|
|
|
int result = SettingsDialog(this).exec();
|
|
|
|
if (result == QDialog::Accepted) {
|
|
|
|
delete ui_.salesView->model();
|
|
|
|
marketplace_->loadFromDb();
|
|
|
|
setSaleModel();
|
|
|
|
}
|
2018-07-30 13:40:58 +02:00
|
|
|
this->setWindowTitle("KIMA2 - Kasse Nr. " +
|
|
|
|
QSettings().value("global/cashPointNo").toString());
|
|
|
|
});
|
2018-08-02 12:34:56 +02:00
|
|
|
connect(ui_.importSellerExcelAction, &QAction::triggered, this,
|
2018-08-02 11:15:15 +02:00
|
|
|
&MainWindow::onImportSellerExcelActionTriggered);
|
2018-08-02 12:34:56 +02:00
|
|
|
connect(ui_.importSellerJsonAction, &QAction::triggered, this,
|
|
|
|
&MainWindow::onImportSellerJsonActionTriggered);
|
2018-08-02 11:15:15 +02:00
|
|
|
connect(ui_.exportSellerJsonAction, &QAction::triggered, this,
|
|
|
|
&MainWindow::onExportSellerJsonActionTriggered);
|
2018-08-02 15:06:35 +02:00
|
|
|
connect(ui_.exportSalesJsonAction, &QAction::triggered, this,
|
|
|
|
&MainWindow::onExportSalesJsonActionTriggered);
|
2018-08-02 15:28:35 +02:00
|
|
|
connect(ui_.importSalesJsonAction, &QAction::triggered, this,
|
|
|
|
&MainWindow::onImportSalesJsonActionTriggered);
|
2018-08-07 10:52:51 +02:00
|
|
|
|
|
|
|
readGeometry();
|
2018-08-07 16:06:01 +02:00
|
|
|
setWindowIcon(QIcon(":/misc/kima2.ico"));
|
2018-10-08 11:21:11 +02:00
|
|
|
|
|
|
|
updateStatLabel();
|
2019-09-30 10:28:03 +02:00
|
|
|
ui_.lastPriceLabel1->setText(formatCentAsEuroString(0).c_str());
|
|
|
|
ui_.lastPriceLabel2->setText(formatCentAsEuroString(0).c_str());
|
2018-07-14 15:54:29 +02:00
|
|
|
}
|
|
|
|
|
2018-07-27 10:16:07 +02:00
|
|
|
void MainWindow::onActionEditSellerTriggered()
|
2018-07-16 12:00:17 +02:00
|
|
|
{
|
|
|
|
auto dialog = std::make_unique<SellerDialog>(this);
|
2018-07-16 18:04:25 +02:00
|
|
|
int retCode = dialog->exec();
|
2018-07-26 08:55:03 +02:00
|
|
|
|
2018-07-30 19:26:10 +02:00
|
|
|
delete ui_.salesView->model();
|
2018-07-26 08:55:03 +02:00
|
|
|
|
2018-07-16 18:04:25 +02:00
|
|
|
if (retCode == QDialog::Accepted) {
|
2018-07-18 09:00:46 +02:00
|
|
|
marketplace_->sortSellers();
|
2018-07-16 18:04:25 +02:00
|
|
|
marketplace_->storeToDb();
|
2018-07-17 10:37:21 +02:00
|
|
|
statusBar()->showMessage("Änderungen an den Verkäufer-Stammdaten gespeichert.",
|
|
|
|
STATUSBAR_TIMEOUT);
|
2018-07-16 18:04:25 +02:00
|
|
|
} else {
|
2018-07-17 11:09:35 +02:00
|
|
|
statusBar()->showMessage("Änderungen an den Verkäufer-Stammdaten verworfen!",
|
2018-07-17 10:37:21 +02:00
|
|
|
STATUSBAR_TIMEOUT);
|
2018-07-16 18:04:25 +02:00
|
|
|
}
|
2018-07-26 08:55:03 +02:00
|
|
|
|
2018-07-30 19:26:10 +02:00
|
|
|
setSaleModel();
|
2018-10-08 11:21:11 +02:00
|
|
|
updateStatLabel();
|
2018-07-30 19:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::setSaleModel()
|
|
|
|
{
|
2018-07-26 08:55:03 +02:00
|
|
|
ui_.salesView->setModel(new SaleModel(getMarketplace(), ui_.salesView));
|
|
|
|
ui_.salesView->setColumnHidden(2, true);
|
|
|
|
ui_.salesView->resizeColumnToContents(0);
|
2019-04-05 15:10:23 +02:00
|
|
|
ui_.salesView->resizeColumnToContents(1);
|
2018-08-15 10:51:57 +02:00
|
|
|
|
|
|
|
ui_.printSaleReceiptButton->setEnabled(false);
|
|
|
|
ui_.cancelSaleButton->setEnabled(false);
|
|
|
|
|
2018-07-26 08:55:03 +02:00
|
|
|
connect(static_cast<BasketModel*>(ui_.basketView->model()), &BasketModel::basketDataChanged,
|
|
|
|
static_cast<SaleModel*>(ui_.salesView->model()), &SaleModel::onBasketDataChanged);
|
2018-07-28 17:38:45 +02:00
|
|
|
connect(ui_.salesView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
|
|
|
&MainWindow::onSalesViewSelectionChanged);
|
2018-07-20 22:07:42 +02:00
|
|
|
}
|
|
|
|
|
2018-07-27 10:16:07 +02:00
|
|
|
void MainWindow::onPaidButtonTriggered()
|
2018-07-23 08:21:28 +02:00
|
|
|
{
|
|
|
|
if (marketplace_->basketSize() > 0) {
|
2018-07-23 14:18:24 +02:00
|
|
|
QString lastPrice{marketplace_->getBasketSumAsString().c_str()};
|
2018-07-23 08:21:28 +02:00
|
|
|
dynamic_cast<BasketModel*>(ui_.basketView->model())->finishSale();
|
2018-08-14 15:12:58 +02:00
|
|
|
ui_.salesView->resizeColumnToContents(0);
|
2018-07-23 14:18:24 +02:00
|
|
|
ui_.lastPriceLabel1->setText(lastPrice);
|
|
|
|
ui_.lastPriceLabel2->setText(lastPrice);
|
2018-08-08 13:36:49 +02:00
|
|
|
ui_.basketSumLabel->setText(formatCentAsEuroString(0).c_str());
|
|
|
|
ui_.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
|
|
|
ui_.drawbackContainerWidget->setEnabled(false);
|
|
|
|
ui_.sellerNoEdit->setFocus();
|
2018-07-26 08:59:54 +02:00
|
|
|
statusBar()->showMessage("Verkaufsvorgang erfolgreich durchgeführt.", STATUSBAR_TIMEOUT);
|
2018-10-08 11:21:11 +02:00
|
|
|
updateStatLabel();
|
2018-07-23 08:21:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-08 13:36:49 +02:00
|
|
|
bool MainWindow::eventFilter(QObject* target, QEvent* event)
|
|
|
|
{
|
|
|
|
if (target == ui_.sellerNoEdit) {
|
|
|
|
if (event->type() == QEvent::KeyPress) {
|
|
|
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
|
|
|
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
|
2019-09-28 15:02:55 +02:00
|
|
|
if (keyEvent->modifiers() & Qt::ControlModifier) {
|
2018-08-08 13:36:49 +02:00
|
|
|
checkSellerNo(true);
|
|
|
|
} else {
|
|
|
|
checkSellerNo(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (target == ui_.givenSpinBox) {
|
|
|
|
if (event->type() == QEvent::KeyPress) {
|
|
|
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
|
|
|
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
|
2019-09-28 15:02:55 +02:00
|
|
|
if (keyEvent->modifiers() & Qt::ControlModifier) {
|
2018-08-08 13:36:49 +02:00
|
|
|
onPaidButtonTriggered();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else if (keyEvent->key() == Qt::Key::Key_Escape) {
|
|
|
|
ui_.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
|
|
|
ui_.drawbackContainerWidget->setEnabled(false);
|
|
|
|
ui_.sellerNoEdit->setFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QMainWindow::eventFilter(target, event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::checkSellerNo(bool ctrlPressed)
|
2018-07-20 22:07:42 +02:00
|
|
|
{
|
|
|
|
using std::regex, std::regex_match, std::smatch;
|
|
|
|
|
|
|
|
auto inputText = ui_.sellerNoEdit->text().toStdString();
|
|
|
|
|
|
|
|
if (inputText.empty()) {
|
2018-08-08 13:36:49 +02:00
|
|
|
if (ctrlPressed == false) {
|
|
|
|
onPaidButtonTriggered();
|
|
|
|
} else if (marketplace_->getBasket().size() > 0) {
|
|
|
|
ui_.drawbackContainerWidget->setEnabled(true);
|
|
|
|
ui_.givenSpinBox->setFocus();
|
|
|
|
ui_.givenSpinBox->selectAll();
|
|
|
|
}
|
2018-07-20 22:07:42 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
regex pattern{R"(\d{1,5})"};
|
|
|
|
smatch result;
|
2018-07-22 20:10:22 +02:00
|
|
|
|
2018-07-20 22:07:42 +02:00
|
|
|
if (!regex_match(inputText, result, pattern)) {
|
2018-07-23 14:18:24 +02:00
|
|
|
ui_.sellerNoEdit->clear();
|
2018-07-20 22:07:42 +02:00
|
|
|
return;
|
|
|
|
}
|
2018-07-21 21:18:22 +02:00
|
|
|
|
2018-07-20 22:07:42 +02:00
|
|
|
int sellerNo = std::stoi(result[0]);
|
|
|
|
|
|
|
|
auto seller = marketplace_->findSellerWithSellerNo(sellerNo);
|
|
|
|
if (seller) {
|
2018-07-21 19:24:56 +02:00
|
|
|
PriceDialog priceDialog(this);
|
2018-10-18 14:50:15 +02:00
|
|
|
if (sellerNo == 0) {
|
2018-10-17 09:09:54 +02:00
|
|
|
priceDialog.setForceDesc(true);
|
|
|
|
}
|
2018-07-21 19:24:56 +02:00
|
|
|
auto dialogResult = priceDialog.exec();
|
2018-07-21 21:18:22 +02:00
|
|
|
if (dialogResult == QDialog::Accepted) {
|
2018-07-21 19:24:56 +02:00
|
|
|
int price = priceDialog.getPrice();
|
2018-08-07 09:27:15 +02:00
|
|
|
std::string desc = priceDialog.getDescription();
|
|
|
|
dynamic_cast<BasketModel*>(ui_.basketView->model())->addArticle(seller, price, desc);
|
2018-10-08 09:39:24 +02:00
|
|
|
ui_.basketView->resizeColumnToContents(1);
|
2018-07-30 14:43:02 +02:00
|
|
|
ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str());
|
2018-07-21 19:24:56 +02:00
|
|
|
}
|
2018-07-20 22:07:42 +02:00
|
|
|
}
|
2018-07-20 22:10:05 +02:00
|
|
|
|
2018-07-20 22:07:42 +02:00
|
|
|
ui_.sellerNoEdit->clear();
|
2018-07-23 12:49:19 +02:00
|
|
|
}
|
|
|
|
|
2018-08-08 13:36:49 +02:00
|
|
|
void MainWindow::onGivenSpinBoxValueChanged(double value)
|
|
|
|
{
|
|
|
|
int givenInCent = std::round(value * 100);
|
|
|
|
int basketSumInCent = marketplace_->getBasketSumInCent();
|
|
|
|
int drawback = givenInCent - basketSumInCent;
|
|
|
|
ui_.drawbackLabel->setText(formatCentAsEuroString(drawback).c_str());
|
|
|
|
}
|
|
|
|
|
2018-07-23 12:49:19 +02:00
|
|
|
void MainWindow::onBasketViewSelectionChanged(const QItemSelection& selected,
|
2020-10-15 16:43:00 +02:00
|
|
|
[[maybe_unused]] const QItemSelection& deselected)
|
2018-07-23 12:49:19 +02:00
|
|
|
{
|
|
|
|
if (selected.size() > 0) {
|
|
|
|
ui_.cancelArticleButton->setEnabled(true);
|
|
|
|
} else {
|
|
|
|
ui_.cancelArticleButton->setEnabled(false);
|
|
|
|
}
|
2018-07-23 13:39:49 +02:00
|
|
|
}
|
|
|
|
|
2018-07-27 16:04:01 +02:00
|
|
|
void MainWindow::onSalesViewSelectionChanged(const QItemSelection& selected,
|
2020-10-15 16:43:00 +02:00
|
|
|
[[maybe_unused]] const QItemSelection& deselected)
|
2018-07-27 16:04:01 +02:00
|
|
|
{
|
|
|
|
if (selected.size() > 0) {
|
|
|
|
ui_.cancelSaleButton->setEnabled(true);
|
2018-08-06 16:14:45 +02:00
|
|
|
if (!selected.indexes()[0].parent().isValid())
|
|
|
|
ui_.printSaleReceiptButton->setEnabled(true);
|
|
|
|
else
|
|
|
|
ui_.printSaleReceiptButton->setEnabled(false);
|
|
|
|
|
2018-07-27 16:04:01 +02:00
|
|
|
} else {
|
|
|
|
ui_.cancelSaleButton->setEnabled(false);
|
2018-08-06 16:14:45 +02:00
|
|
|
ui_.printSaleReceiptButton->setEnabled(false);
|
2018-07-27 16:04:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-23 13:39:49 +02:00
|
|
|
void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
|
|
|
|
{
|
|
|
|
auto selModel = ui_.basketView->selectionModel();
|
|
|
|
if (selModel->hasSelection() == false)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto dlgResult =
|
|
|
|
QMessageBox(QMessageBox::Icon::Warning, "Sind Sie sicher?",
|
|
|
|
"Möchten Sie wirklich den Artikel stornieren?",
|
|
|
|
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, this)
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2018-07-23 13:39:49 +02:00
|
|
|
if (dlgResult == QMessageBox::No)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto indexes = selModel->selectedRows();
|
|
|
|
std::sort(indexes.begin(), indexes.end());
|
|
|
|
|
|
|
|
// Deleting the rows, beginning with the last one!
|
|
|
|
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
|
|
|
ui_.basketView->model()->removeRow(iter->row());
|
|
|
|
}
|
2018-10-08 08:52:39 +02:00
|
|
|
|
|
|
|
ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str()); // Update basket sum
|
2018-10-17 09:25:10 +02:00
|
|
|
ui_.sellerNoEdit->setFocus();
|
2018-07-23 13:39:49 +02:00
|
|
|
}
|
|
|
|
|
2018-07-27 16:04:01 +02:00
|
|
|
void MainWindow::onCancelSaleButtonClicked([[maybe_unused]] bool checked)
|
|
|
|
{
|
|
|
|
auto selModel = ui_.salesView->selectionModel();
|
|
|
|
if (selModel->hasSelection() == false)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto dlgResult =
|
|
|
|
QMessageBox(QMessageBox::Icon::Warning, "Sind Sie sicher?",
|
2019-10-01 08:33:36 +02:00
|
|
|
"Möchten Sie wirklich aus abgeschlossenen Verkäufen stornieren?",
|
2018-07-27 16:04:01 +02:00
|
|
|
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, this)
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2018-07-27 16:04:01 +02:00
|
|
|
if (dlgResult == QMessageBox::No)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto indexes = selModel->selectedRows();
|
|
|
|
std::sort(indexes.begin(), indexes.end());
|
|
|
|
|
|
|
|
// Deleting the rows, beginning with the last one!
|
|
|
|
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
2018-07-27 16:41:34 +02:00
|
|
|
ui_.salesView->model()->removeRow(iter->row(), iter->parent());
|
2018-07-27 16:04:01 +02:00
|
|
|
}
|
2018-10-08 09:23:03 +02:00
|
|
|
|
|
|
|
ui_.salesView->collapseAll();
|
2019-09-30 10:39:00 +02:00
|
|
|
|
2019-09-30 10:28:03 +02:00
|
|
|
QString lastPriceValue(formatCentAsEuroString(0).c_str());
|
|
|
|
if (ui_.salesView->model()->rowCount() > 0) {
|
2019-09-30 10:39:00 +02:00
|
|
|
lastPriceValue =
|
|
|
|
ui_.salesView->model()->data(ui_.salesView->model()->index(0, 1)).toString();
|
2019-09-30 10:28:03 +02:00
|
|
|
}
|
|
|
|
ui_.lastPriceLabel1->setText(lastPriceValue);
|
|
|
|
ui_.lastPriceLabel2->setText(lastPriceValue);
|
2019-09-30 10:39:00 +02:00
|
|
|
|
2018-10-08 11:21:11 +02:00
|
|
|
updateStatLabel();
|
2018-07-27 16:04:01 +02:00
|
|
|
}
|
|
|
|
|
2018-08-06 16:14:45 +02:00
|
|
|
void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
|
|
|
|
{
|
|
|
|
auto selModel = ui_.salesView->selectionModel();
|
|
|
|
if (selModel->hasSelection() == false)
|
|
|
|
return;
|
|
|
|
|
2018-08-15 10:51:57 +02:00
|
|
|
QSettings settings{};
|
|
|
|
QString posPrinterDevice = settings.value("global/posPrinterDevice", "").toString();
|
|
|
|
QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString();
|
|
|
|
|
2018-08-06 16:14:45 +02:00
|
|
|
auto indexes = selModel->selectedRows();
|
|
|
|
auto& sale = marketplace_->getSales().at(indexes[0].row());
|
2018-08-15 10:51:57 +02:00
|
|
|
|
2018-08-16 12:40:19 +02:00
|
|
|
auto printerDevice =
|
|
|
|
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
|
2018-08-15 10:51:57 +02:00
|
|
|
|
|
|
|
std::unique_ptr<PosPrinter> printer;
|
|
|
|
|
|
|
|
if (printerDevice) {
|
|
|
|
printer = std::make_unique<PosPrinter>(*printerDevice);
|
|
|
|
} else {
|
|
|
|
printer = std::make_unique<PosPrinter>();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (printer->isValid())
|
2019-02-25 09:26:21 +01:00
|
|
|
printer->printSaleReceipt(
|
|
|
|
sale.get(), settings.value("global/commune", "Dettingen").toString().toStdString());
|
2018-08-06 16:14:45 +02:00
|
|
|
}
|
|
|
|
|
2018-07-23 13:39:49 +02:00
|
|
|
void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked)
|
|
|
|
{
|
|
|
|
if (ui_.basketView->model()->rowCount() == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto dlgResult =
|
|
|
|
QMessageBox(QMessageBox::Icon::Warning, "Sind Sie sicher?",
|
|
|
|
"Möchten Sie wirklich *alle* Artikel des aktuellen Einkaufs stornieren?",
|
|
|
|
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, this)
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2018-07-23 13:39:49 +02:00
|
|
|
if (dlgResult == QMessageBox::No)
|
|
|
|
return;
|
2018-07-23 14:18:24 +02:00
|
|
|
|
2018-07-23 13:39:49 +02:00
|
|
|
dynamic_cast<BasketModel*>(ui_.basketView->model())->cancelSale();
|
2018-10-09 19:15:34 +02:00
|
|
|
|
|
|
|
ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str()); // Update basket sum
|
2018-10-17 09:25:10 +02:00
|
|
|
ui_.sellerNoEdit->setFocus();
|
2018-07-29 09:56:37 +02:00
|
|
|
}
|
|
|
|
|
2020-10-15 16:43:00 +02:00
|
|
|
void MainWindow::onAboutQt() {
|
|
|
|
QMessageBox::aboutQt(this);
|
|
|
|
}
|
2018-07-30 16:39:33 +02:00
|
|
|
|
|
|
|
void MainWindow::onAbout()
|
|
|
|
{
|
|
|
|
QMessageBox::about(
|
|
|
|
this, "Über",
|
2018-07-30 19:29:16 +02:00
|
|
|
QString("<p style='text-align:center;'><b>KIMA2</b> - Version ") + PROJECT_VERSION +
|
2020-10-15 16:43:00 +02:00
|
|
|
"</p>"
|
|
|
|
"<p>KIMA2 ist ein kleines Kassenprogramm für Kindersachenmärkte.<p />"
|
|
|
|
"<p>Copyright © Martin Brodbeck <<a href=mailto:martin@brodbeck-online.de"
|
|
|
|
">info@rustysoft.de</a>></p>");
|
2018-08-01 15:36:41 +02:00
|
|
|
}
|
|
|
|
|
2018-08-02 11:15:15 +02:00
|
|
|
void MainWindow::onImportSellerExcelActionTriggered()
|
2018-08-01 15:36:41 +02:00
|
|
|
{
|
|
|
|
if (!marketplace_->getSales().empty()) {
|
|
|
|
QMessageBox(QMessageBox::Icon::Information, "Import nicht möglich",
|
|
|
|
"Der Import ist nicht möglich, da schon Verkäufe getätigt wurden.",
|
|
|
|
QMessageBox::StandardButton::Ok, this)
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2018-08-01 15:36:41 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-09-30 10:39:00 +02:00
|
|
|
auto filename = QFileDialog::getOpenFileName(
|
2020-10-15 16:43:00 +02:00
|
|
|
this, "Verkäufer importieren", QString(),
|
|
|
|
"Alle unterstützte Dateien (*.xlsx *.csv);;Excel Dateien (*.xlsx);;CSV Dateien (*.csv)");
|
2018-08-01 15:36:41 +02:00
|
|
|
|
2018-08-08 10:22:38 +02:00
|
|
|
if (filename.isEmpty())
|
|
|
|
return;
|
2018-08-09 12:58:11 +02:00
|
|
|
|
2019-10-07 08:32:51 +02:00
|
|
|
#if defined(_WIN64) || defined(_WIN32)
|
2018-08-09 16:37:56 +02:00
|
|
|
fs::path filePath(filename.toStdWString());
|
2019-10-07 08:32:51 +02:00
|
|
|
#else
|
|
|
|
fs::path filePath(filename.toStdString());
|
|
|
|
#endif
|
2018-08-09 12:58:11 +02:00
|
|
|
|
2019-09-26 16:41:39 +02:00
|
|
|
std::size_t numImported{};
|
2019-09-27 08:37:18 +02:00
|
|
|
if (case_insensitive_match(filePath.extension().string(), std::string(".xlsx"))) {
|
2020-10-15 16:43:00 +02:00
|
|
|
try {
|
|
|
|
numImported = ExcelReader::readSellersFromFile(filePath, marketplace_.get());
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
QMessageBox(QMessageBox::Icon::Critical, "Fehler beim Importieren",
|
|
|
|
"Beim Import aus der Excel-Datei ist ein Fehler aufgetreten. "
|
|
|
|
"Sie könnten ggf. versuchen, die Daten aus einer .csv Datei zu imporieren.",
|
|
|
|
QMessageBox::StandardButton::Ok, this).exec();
|
|
|
|
std::cerr << e.what() << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
2019-09-26 16:41:39 +02:00
|
|
|
} else {
|
|
|
|
numImported = CsvReader::readSellersFromFile(filePath, marketplace_.get());
|
|
|
|
}
|
2019-09-30 10:39:00 +02:00
|
|
|
|
2018-10-08 11:21:11 +02:00
|
|
|
updateStatLabel();
|
2019-02-25 09:26:21 +01:00
|
|
|
|
|
|
|
using namespace std::string_literals;
|
|
|
|
std::ostringstream msg;
|
2019-10-01 11:47:53 +02:00
|
|
|
msg << "Aus der Excel/CSV-Datei wurden <b>"s << std::to_string(numImported)
|
2019-02-25 09:26:21 +01:00
|
|
|
<< "</b> Verkäufer importiert.";
|
|
|
|
QMessageBox(QMessageBox::Icon::Information, "Verkäufer erfolgreich importiert",
|
|
|
|
msg.str().c_str(), QMessageBox::StandardButton::Ok, this)
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2018-08-02 11:15:15 +02:00
|
|
|
}
|
|
|
|
|
2018-08-02 12:34:56 +02:00
|
|
|
void MainWindow::onImportSellerJsonActionTriggered()
|
|
|
|
{
|
|
|
|
if (!marketplace_->getSales().empty()) {
|
|
|
|
QMessageBox(QMessageBox::Icon::Information, "Import nicht möglich",
|
|
|
|
"Der Import ist nicht möglich, da schon Verkäufe getätigt wurden.",
|
|
|
|
QMessageBox::StandardButton::Ok, this)
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2018-08-02 12:34:56 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto filename = QFileDialog::getOpenFileName(this, "Verkäufer importieren", QString(),
|
2020-10-15 16:43:00 +02:00
|
|
|
"JSON Dateien (*.json)");
|
2018-08-02 12:34:56 +02:00
|
|
|
|
2018-08-05 14:52:34 +02:00
|
|
|
if (filename.isEmpty())
|
|
|
|
return;
|
|
|
|
|
2019-10-07 08:32:51 +02:00
|
|
|
#if defined(_WIN64) || defined(_WIN32)
|
2018-08-09 16:37:56 +02:00
|
|
|
fs::path filePath(filename.toStdWString());
|
2019-10-07 08:32:51 +02:00
|
|
|
#else
|
|
|
|
fs::path filePath(filename.toStdString());
|
|
|
|
#endif
|
2018-08-09 12:58:11 +02:00
|
|
|
|
2019-10-07 10:29:14 +02:00
|
|
|
std::size_t numImported{};
|
|
|
|
numImported = JsonUtil::importSellers(filePath, marketplace_.get());
|
|
|
|
|
2018-10-08 11:21:11 +02:00
|
|
|
updateStatLabel();
|
2019-10-07 10:29:14 +02:00
|
|
|
|
|
|
|
using namespace std::string_literals;
|
|
|
|
std::ostringstream msg;
|
|
|
|
msg << "Aus der JSON-Datei wurden <b>"s << std::to_string(numImported)
|
|
|
|
<< "</b> Verkäufer importiert.";
|
|
|
|
QMessageBox(QMessageBox::Icon::Information, "Verkäufer erfolgreich importiert",
|
|
|
|
msg.str().c_str(), QMessageBox::StandardButton::Ok, this)
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2018-08-02 12:34:56 +02:00
|
|
|
}
|
|
|
|
|
2018-08-02 11:15:15 +02:00
|
|
|
void MainWindow::onExportSellerJsonActionTriggered()
|
|
|
|
{
|
2018-10-18 14:50:15 +02:00
|
|
|
auto filename = QFileDialog::getSaveFileName(
|
2020-10-15 16:43:00 +02:00
|
|
|
this, "Verkäufer exportieren", QString("kima2_verkaeufer.json"), "JSON Dateien (*.json)");
|
2018-08-02 11:15:15 +02:00
|
|
|
|
2018-08-05 14:52:34 +02:00
|
|
|
if (filename.isEmpty())
|
|
|
|
return;
|
|
|
|
|
2019-10-07 10:29:14 +02:00
|
|
|
#if defined(_WIN64) || defined(_WIN32)
|
2018-08-09 16:37:56 +02:00
|
|
|
fs::path filePath(filename.toStdWString());
|
2019-10-07 10:29:14 +02:00
|
|
|
#else
|
|
|
|
fs::path filePath(filename.toStdString());
|
|
|
|
#endif
|
2018-08-09 13:16:00 +02:00
|
|
|
|
|
|
|
JsonUtil::exportSellers(filePath, marketplace_.get());
|
2018-08-02 15:06:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::onExportSalesJsonActionTriggered()
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
|
2018-10-09 11:55:20 +02:00
|
|
|
auto filename = QFileDialog::getSaveFileName(
|
2020-10-15 16:43:00 +02:00
|
|
|
this, "Umsätze/Transaktionen exportieren",
|
|
|
|
QString("kima2_umsaetze_kasse") + settings.value("global/cashPointNo").toString() + ".json",
|
|
|
|
"JSON Dateien (*.json)");
|
2018-08-05 14:52:34 +02:00
|
|
|
|
|
|
|
if (filename.isEmpty())
|
|
|
|
return;
|
|
|
|
|
2019-10-07 08:32:51 +02:00
|
|
|
#if defined(_WIN64) || defined(_WIN32)
|
2018-08-09 16:37:56 +02:00
|
|
|
fs::path filePath(filename.toStdWString());
|
2019-10-07 08:32:51 +02:00
|
|
|
#else
|
|
|
|
fs::path filePath(filename.toStdString());
|
|
|
|
#endif
|
2018-08-09 13:11:23 +02:00
|
|
|
|
|
|
|
JsonUtil::exportSales(filePath, marketplace_.get(),
|
2018-08-02 15:28:35 +02:00
|
|
|
settings.value("global/cashPointNo").toInt());
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::onImportSalesJsonActionTriggered()
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
|
|
|
|
auto filename = QFileDialog::getOpenFileName(this, "Umsätze/Transaktionen importieren",
|
2020-10-15 16:43:00 +02:00
|
|
|
QString(), "JSON Dateien (*.json)");
|
2018-08-02 15:28:35 +02:00
|
|
|
|
2018-08-05 14:52:34 +02:00
|
|
|
if (filename.isEmpty())
|
|
|
|
return;
|
|
|
|
|
2019-10-07 08:32:51 +02:00
|
|
|
#if defined(_WIN64) || defined(_WIN32)
|
2018-08-09 16:37:56 +02:00
|
|
|
fs::path filePath(filename.toStdWString());
|
2019-10-07 08:32:51 +02:00
|
|
|
#else
|
|
|
|
fs::path filePath(filename.toStdString());
|
|
|
|
#endif
|
2018-08-09 13:02:33 +02:00
|
|
|
|
2018-08-05 14:52:34 +02:00
|
|
|
delete ui_.salesView->model();
|
2018-08-02 15:28:35 +02:00
|
|
|
try {
|
2018-08-09 13:02:33 +02:00
|
|
|
JsonUtil::importSales(filePath, marketplace_.get(),
|
2018-08-05 14:52:34 +02:00
|
|
|
settings.value("global/cashPointNo").toInt());
|
2018-08-02 15:28:35 +02:00
|
|
|
} catch (std::runtime_error& err) {
|
|
|
|
QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok,
|
|
|
|
this)
|
2020-10-15 16:43:00 +02:00
|
|
|
.exec();
|
2018-08-02 15:28:35 +02:00
|
|
|
}
|
2018-08-05 14:52:34 +02:00
|
|
|
setSaleModel();
|
2018-10-08 11:21:11 +02:00
|
|
|
updateStatLabel();
|
2018-08-02 15:28:35 +02:00
|
|
|
}
|
2018-08-07 10:52:51 +02:00
|
|
|
|
|
|
|
void MainWindow::writeGeometry()
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
|
|
|
|
settings.beginGroup("mainwindow");
|
|
|
|
settings.setValue("size", size());
|
|
|
|
settings.setValue("pos", pos());
|
|
|
|
settings.endGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::readGeometry()
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
|
|
|
|
settings.beginGroup("mainwindow");
|
|
|
|
resize(settings.value("size", QSize(800, 600)).toSize());
|
|
|
|
move(settings.value("pos", QPoint(200, 200)).toPoint());
|
|
|
|
settings.endGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::closeEvent(QCloseEvent* event)
|
|
|
|
{
|
|
|
|
writeGeometry();
|
|
|
|
event->accept();
|
2018-08-08 08:19:19 +02:00
|
|
|
}
|
2018-10-08 11:21:11 +02:00
|
|
|
|
|
|
|
void MainWindow::updateStatLabel()
|
|
|
|
{
|
|
|
|
std::string statistics("<b>KIMA2 - Version ");
|
|
|
|
statistics += PROJECT_VERSION;
|
|
|
|
statistics += "</b><br />Verkäufer: " + std::to_string(marketplace_->getSellers().size() - 1);
|
|
|
|
statistics += "<br />Kunden: " + std::to_string(marketplace_->getSales().size());
|
|
|
|
statistics += "<br />Umsatz: " + marketplace_->getOverallSumAsString();
|
|
|
|
|
|
|
|
ui_.statLabel->setText(statistics.c_str());
|
2019-02-25 13:32:34 +01:00
|
|
|
}
|