diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 823c7b2..55543d5 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -25,10 +25,10 @@ set(CORE_SOURCES add_library(core STATIC ${CORE_SOURCES}) if (WIN32) - target_link_libraries(core Boost::boost Boost::date_time sqlite3 ${XLNT_LIBRARY} ${JSONCPP_LIBRARY}) + target_link_libraries(core printer Boost::boost Boost::date_time sqlite3 ${XLNT_LIBRARY} ${JSONCPP_LIBRARY}) target_link_libraries(core bcrypt) else() - target_link_libraries(core Boost::boost Boost::date_time sqlite3 ${XLNT_LIBRARIES} ${JSONCPP_LIBRARIES}) + target_link_libraries(core printer Boost::boost Boost::date_time sqlite3 ${XLNT_LIBRARIES} ${JSONCPP_LIBRARIES}) endif() target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/core/utils.cpp b/src/core/utils.cpp index f505cfd..824533e 100644 --- a/src/core/utils.cpp +++ b/src/core/utils.cpp @@ -1,8 +1,8 @@ #include "utils.h" +#include #include #include -#include std::string formatCentAsEuroString(const int cent, int width) { @@ -21,10 +21,36 @@ std::string formatCentAsEuroString(const int cent, int width) return currStream.str(); } +std::optional convertToPosPrinterDevice(const std::string& device, + const std::string& endpoint) +{ + if (device.empty()) { + return std::nullopt; + } + + PrinterDevice printerDevice; + std::string delimiter = ":"; + try { + printerDevice.idVendor = std::stoi(device.substr(0, device.find(delimiter)), 0, 16); + printerDevice.idProduct = std::stoi(device.substr(device.find(delimiter) + 1), 0, 16); + if (endpoint.empty()) { + printerDevice.endpoint = 0x03; + } else { + printerDevice.endpoint = std::stoi(endpoint, 0, 16); + } + + } catch (std::exception& ex) { + throw ex; + } + + return printerDevice; +} + #ifdef _WIN32 std::string convertFromUtf16ToUtf8(std::u16string& utf16String) { - std::string u8_conv = std::wstring_convert, char16_t>{}.to_bytes(utf16String); - return u8_conv; + std::string u8_conv = + std::wstring_convert, char16_t>{}.to_bytes(utf16String); + return u8_conv; } #endif diff --git a/src/core/utils.h b/src/core/utils.h index d3e8e62..5e8f108 100644 --- a/src/core/utils.h +++ b/src/core/utils.h @@ -1,10 +1,15 @@ #ifndef UTILS_H #define UTILS_H -#include +#include "posprinter.h" + #include +#include +#include std::string formatCentAsEuroString(const int cent, int width = 10); +std::optional convertToPosPrinterDevice(const std::string& vendor, + const std::string& endpoint); #ifdef __WIN32 std::string convertFromUtf16ToUtf8(std::u16string& utf16String); diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 80ad9e8..356918c 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -166,6 +166,10 @@ void MainWindow::setSaleModel() ui_.salesView->setModel(new SaleModel(getMarketplace(), ui_.salesView)); ui_.salesView->setColumnHidden(2, true); ui_.salesView->resizeColumnToContents(0); + + ui_.printSaleReceiptButton->setEnabled(false); + ui_.cancelSaleButton->setEnabled(false); + connect(static_cast(ui_.basketView->model()), &BasketModel::basketDataChanged, static_cast(ui_.salesView->model()), &SaleModel::onBasketDataChanged); connect(ui_.salesView->selectionModel(), &QItemSelectionModel::selectionChanged, this, @@ -349,11 +353,25 @@ void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked) if (selModel->hasSelection() == false) return; + QSettings settings{}; + QString posPrinterDevice = settings.value("global/posPrinterDevice", "").toString(); + QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString(); + auto indexes = selModel->selectedRows(); auto& sale = marketplace_->getSales().at(indexes[0].row()); - PosPrinter printer; - if (printer.isValid()) - printer.printSaleReceipt(sale.get()); + + auto printerDevice = convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString()); + + std::unique_ptr printer; + + if (printerDevice) { + printer = std::make_unique(*printerDevice); + } else { + printer = std::make_unique(); + } + + if (printer->isValid()) + printer->printSaleReceipt(sale.get()); } void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked) diff --git a/src/gui/reportdialog.cpp b/src/gui/reportdialog.cpp index 5eb3d01..d55daae 100644 --- a/src/gui/reportdialog.cpp +++ b/src/gui/reportdialog.cpp @@ -3,6 +3,7 @@ #include "mainwindow.h" #include +#include #include #include @@ -90,7 +91,8 @@ void ReportDialog::onPrintReportButtonClicked() .arg("Auszahlung\n", -11); content.append( "---------------------------------------------------------------------------\n"); - for (unsigned int j = 0; j < ENTRIES_PER_PAGE && (i - 1) * ENTRIES_PER_PAGE + j < sellers.size(); ++j) { + for (unsigned int j = 0; + j < ENTRIES_PER_PAGE && (i - 1) * ENTRIES_PER_PAGE + j < sellers.size(); ++j) { int idx = (i - 1) * ENTRIES_PER_PAGE + j; if (sellers.at(idx)->getUuidAsString() == "11111111-1111-1111-1111-111111111111") { continue; @@ -168,6 +170,8 @@ void ReportDialog::onPrintSellerReceiptButtonClicked() QSettings settings; int feeInPercent = settings.value("global/feeInPercent").toInt(); int maxFeeInEuro = settings.value("global/maxFeeInEuro").toInt(); + QString posPrinterDevice = settings.value("global/posPrinterDevice", "").toString(); + QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString(); auto selModel = ui_.reportView->selectionModel(); if (selModel->hasSelection() == false) @@ -175,9 +179,20 @@ void ReportDialog::onPrintSellerReceiptButtonClicked() auto indexes = selModel->selectedRows(); auto& seller = market_->getSellers().at(indexes[0].row()); - PosPrinter printer; - if (printer.isValid()) - printer.printSellerReceipt(seller.get(), feeInPercent, maxFeeInEuro * 100); + + auto printerDevice = + convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString()); + + std::unique_ptr printer; + + if (printerDevice) { + printer = std::make_unique(*printerDevice); + } else { + printer = std::make_unique(); + } + + if (printer->isValid()) + printer->printSellerReceipt(seller.get(), feeInPercent, maxFeeInEuro * 100); } void ReportDialog::onReportViewSelectionChanged(const QItemSelection& selected, diff --git a/src/gui/settingsdialog.cpp b/src/gui/settingsdialog.cpp index a7533fb..ea01532 100644 --- a/src/gui/settingsdialog.cpp +++ b/src/gui/settingsdialog.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -18,6 +19,7 @@ SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(par QSettings settings{}; int cashPointNo = settings.value("global/cashPointNo").toInt(); QString posPrinterDevice = settings.value("global/posPrinterDevice").toString(); + QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint").toString(); int feeInPercent = settings.value("global/feeInPercent").toInt(); int maxFeeInEuro = settings.value("global/maxFeeInEuro").toInt(); @@ -26,6 +28,7 @@ SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(par ui_.cashPointNoSpinBox->setValue(cashPointNo); ui_.posPrinterDeviceEdit->setText(posPrinterDevice); + ui_.posPrinterEndpointEdit->setText(posPrinterEndpoint); ui_.feePercentSpinBox->setValue(feeInPercent); ui_.maxFeeSpinBox->setValue(maxFeeInEuro); @@ -37,26 +40,27 @@ SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(par printer.printTest(); } else { std::string posPrinterDeviceString = ui_.posPrinterDeviceEdit->text().toStdString(); - std::string delimiter = ":"; - PrinterDevice printerDevice; + std::string posPrinterEndpointString = + ui_.posPrinterEndpointEdit->text().toStdString(); + try { - printerDevice.idVendor = std::stoi( - posPrinterDeviceString.substr(0, posPrinterDeviceString.find(delimiter)), 0, - 16); - printerDevice.idProduct = std::stoi( - posPrinterDeviceString.substr(posPrinterDeviceString.find(delimiter) + 1), - 0, 16); + auto printerDevice = + convertToPosPrinterDevice(posPrinterDeviceString, posPrinterEndpointString); + + if (printerDevice) { + PosPrinter printer(*printerDevice); + printer.printTest(); + } + } catch (std::exception&) { QMessageBox(QMessageBox::Icon::Warning, "Falsche Eingabe", - QString("Eingabeformat für den Bondrucker (hexadezimale IDs): " - ":\nBeispiel: 0416:5011"), + QString("Eingabeformat für Device (hexadezimale IDs): " + ":\nBeispiel: 0416:5011\n " + "Eingabeformat für Endpoint: Hexadezimale Adresse"), QMessageBox::StandardButton::Ok, this) .exec(); return; } - - PosPrinter printer(printerDevice); - printer.printTest(); } } catch (std::runtime_error& err) { QMessageBox(QMessageBox::Icon::Warning, "Bondrucker Fehler", @@ -75,7 +79,8 @@ void SettingsDialog::accept() int oldCashPointNo = settings.value("global/cashPointNo").toInt(); int newCashPointNo = ui_.cashPointNoSpinBox->value(); - settings.setValue("global/posPrinterDevice", ui_.posPrinterDeviceEdit->text()); + settings.setValue("global/posPrinterDevice", ui_.posPrinterDeviceEdit->text().trimmed()); + settings.setValue("global/posPrinterEndpoint", ui_.posPrinterEndpointEdit->text().trimmed()); settings.setValue("global/feeInPercent", ui_.feePercentSpinBox->value()); settings.setValue("global/maxFeeInEuro", ui_.maxFeeSpinBox->value()); diff --git a/src/gui/settingsdialog.ui b/src/gui/settingsdialog.ui index d965f7f..2df8cd2 100644 --- a/src/gui/settingsdialog.ui +++ b/src/gui/settingsdialog.ui @@ -6,14 +6,17 @@ 0 0 - 400 - 203 + 392 + 242 Einstellungen + + + @@ -21,51 +24,65 @@ - - - - Bondrucker Gerätedatei: + Bondrucker: + + + 0 + 0 + + <idVendor>:<idProduct> + + VendorId:ProductId + - + Testen - + Gebühr in %: - - + + + + 20 + + - + max. Gebühr in €: - - + + + + 50 + + - + Qt::Horizontal @@ -75,6 +92,13 @@ + + + + Endpoint Address + + + diff --git a/src/printer/posprinter.cpp b/src/printer/posprinter.cpp index 9c6609d..fe49502 100644 --- a/src/printer/posprinter.cpp +++ b/src/printer/posprinter.cpp @@ -46,8 +46,9 @@ PosPrinter::PosPrinter(const PrinterDevice& printerDevice) : printerDevice_(prin if (printerDevice_.idVendor == 0) { for (const auto& supported : supportedPrinters_.models) { - if (desc.idVendor == supported.first && desc.idProduct == supported.second) { + if (desc.idVendor == std::get<0>(supported) && desc.idProduct == std::get<1>(supported)) { numDevice = i; + printerEndpoint_ = std::get<2>(supported); break; } } @@ -55,6 +56,7 @@ PosPrinter::PosPrinter(const PrinterDevice& printerDevice) : printerDevice_(prin if (desc.idVendor == printerDevice_.idVendor && desc.idProduct == printerDevice_.idProduct) { numDevice = i; + printerEndpoint_ = printerDevice.endpoint; break; } } @@ -122,7 +124,7 @@ void PosPrinter::write(const std::string& text) int length = text_escaped.length(); int actual{0}; int retValue = - libusb_bulk_transfer(devicePtr_, (0x03 | LIBUSB_ENDPOINT_OUT), + libusb_bulk_transfer(devicePtr_, (printerEndpoint_ | LIBUSB_ENDPOINT_OUT), (unsigned char*)text_escaped.c_str(), length, &actual, 10000); if (retValue != 0 || actual != length) std::cerr << "Write Error" << std::endl; diff --git a/src/printer/posprinter.h b/src/printer/posprinter.h index 04db2f1..e9ca7df 100644 --- a/src/printer/posprinter.h +++ b/src/printer/posprinter.h @@ -9,16 +9,17 @@ #include struct SupportedPrinters { - std::array, 2> models{ - // {Vendor ID, Model ID} - std::make_pair(0x0456, 0x0808), - std::make_pair(0x0416, 0x5011), + std::array, 2> models{ + // {Vendor ID, Model ID, Endpoint} + std::make_tuple(0x0456, 0x0808, 0x03), + std::tuple(0x0416, 0x5011, 0x03), }; }; struct PrinterDevice { int idVendor{}; int idProduct{}; + int endpoint{}; }; class PosPrinter @@ -50,6 +51,7 @@ class PosPrinter libusb_device_handle* devicePtr_{}; SupportedPrinters supportedPrinters_; PrinterDevice printerDevice_{}; + int printerEndpoint_{0x03}; }; #endif \ No newline at end of file