Compare commits

...

37 commits

Author SHA1 Message Date
Martin Brodbeck ab7b14f12e get rid of fmt 2024-05-22 13:09:44 +02:00
Martin Brodbeck 0c7f071b9d include dir for boost added. 2024-03-05 14:38:02 +01:00
Martin Brodbeck d0c50c9b9a qsingleapplication version bumped 2024-01-23 11:25:07 +01:00
Martin Brodbeck a17cb22e05 2023 → 2024 2024-01-23 11:22:51 +01:00
Martin Brodbeck 205dac5326 nlohmann updateted to 3.11.3 2024-01-23 11:20:39 +01:00
Martin Brodbeck b0d2d6b284 update to version 1.8 2024-01-23 10:46:49 +01:00
Martin Brodbeck 7f11ba4e5d new version 1.8.0 2024-01-23 10:42:04 +01:00
Martin Brodbeck 32d0ec7749 Allow import of multiple sales at once. 2024-01-23 10:39:43 +01:00
Martin Brodbeck 54e5c70447 Changed minimum versions 2024-01-23 10:06:01 +01:00
Martin Brodbeck 379fd4a73c Lib references for Windows updated 2023-09-21 15:00:18 +02:00
Martin Brodbeck 8a94b53379 Push boost version. 2023-05-02 11:07:15 +02:00
Martin Brodbeck d9b13d0e1a README updated. 2023-05-02 11:03:22 +02:00
Martin Brodbeck 6f885dd64e more on metainfo 2023-04-28 10:29:39 +02:00
Martin Brodbeck 1a698a6cd2 metainfo added 2023-04-28 10:12:10 +02:00
Martin Brodbeck ac9ae8b34e Add metainfo 2023-04-28 10:08:02 +02:00
Martin Brodbeck 4385624988 Merge branch 'master' of ssh://git.rustysoft.de/martin/kima2 2023-04-26 12:47:45 +02:00
Martin Brodbeck 4cfd8d5572 2022 → 2023 2023-04-26 12:47:41 +02:00
Martin Brodbeck 528ae1ff31 use QUrl::fromLocalFile 2023-04-26 12:46:35 +02:00
Martin Brodbeck 649c26db4b Updated for Windows installation 2023-04-26 08:53:13 +02:00
Martin Brodbeck 13a1d26d96 description updated 2023-04-26 08:36:03 +02:00
Martin Brodbeck f898844c7c remove obsolete lstdc++fs flag 2023-04-25 16:19:27 +02:00
Martin Brodbeck e6b71a7e4d Get rid of csv-parser 2023-04-25 16:11:34 +02:00
Martin Brodbeck f4b4ccbbea Revert "Remove fmt dependency"
This reverts commit 8efdf7b6fe.
2023-04-25 15:22:06 +02:00
Martin Brodbeck e79a81797c Increase version number 2023-04-21 21:35:46 +02:00
Martin Brodbeck 8efdf7b6fe Remove fmt dependency 2023-04-21 21:33:59 +02:00
Martin Brodbeck a46e8d89c9 remove xlnt stuff 2023-01-18 19:41:53 +01:00
Martin Brodbeck 3e293ba447 updated 2023-01-18 17:08:09 +01:00
Martin Brodbeck 245e41bbf0 Push to new version. 2023-01-18 17:06:02 +01:00
Martin Brodbeck b0444112a8 seller menu simplified. 2023-01-18 17:05:21 +01:00
Martin Brodbeck c4ccd43b45 Push to new version 2023-01-18 16:46:44 +01:00
Martin Brodbeck 16745a248c Update manual 2023-01-18 16:46:30 +01:00
Martin Brodbeck 19ea7f27de Excel stuff removed. 2023-01-18 16:35:28 +01:00
Martin Brodbeck 42bf036f85 Merge branch 'master' of ssh://git.rustysoft.de/martin/kima2 2022-09-27 09:01:55 +02:00
Martin Brodbeck 9d7492c745 Version 1.6.1 2022-09-27 09:01:27 +02:00
Martin Brodbeck 9fcfb8e3ba Loading translation improved. 2022-09-26 20:47:23 +02:00
Martin Brodbeck a23de4dcf0 README updated 2022-09-26 14:04:57 +02:00
Martin Brodbeck 77f45fa55f improved Arch Linux build file 2022-09-26 13:48:48 +02:00
29 changed files with 184 additions and 293 deletions

5
.gitmodules vendored
View file

@ -3,7 +3,4 @@
url = https://github.com/nlohmann/json.git
[submodule "subprojects/singleapplication"]
path = subprojects/singleapplication/singleapplication.git
url = https://github.com/itay-grudev/SingleApplication.git
[submodule "subprojects/csv-parser"]
path = subprojects/csv-parser
url = https://github.com/vincentlaucsb/csv-parser.git
url = https://github.com/itay-grudev/SingleApplication.git

32
.vscode/settings.json vendored
View file

@ -65,7 +65,37 @@
"condition_variable": "cpp",
"mutex": "cpp",
"hash_map": "cpp",
"future": "cpp"
"future": "cpp",
"bit": "cpp",
"compare": "cpp",
"concepts": "cpp",
"forward_list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_set": "cpp",
"iterator": "cpp",
"memory_resource": "cpp",
"random": "cpp",
"semaphore": "cpp",
"stop_token": "cpp",
"__bit_reference": "cpp",
"__bits": "cpp",
"__config": "cpp",
"__debug": "cpp",
"__errc": "cpp",
"__hash_table": "cpp",
"__locale": "cpp",
"__mutex_base": "cpp",
"__node_handle": "cpp",
"__split_buffer": "cpp",
"__threading_support": "cpp",
"__tree": "cpp",
"__tuple": "cpp",
"__verbose_abort": "cpp",
"format": "cpp",
"ios": "cpp",
"locale": "cpp"
},
"C_Cpp.clang_format_path": "/usr/bin/clang-format",
"cmake.configureOnOpen": true,

View file

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.8)
cmake_minimum_required(VERSION 3.10)
project(kima2 VERSION 1.6.0)
project(kima2 VERSION 1.8.1)
set(CMAKE_MODULE_PATH "${CMAKE_HOME_DIRECTORY}/cmake")
@ -17,6 +17,7 @@ else()
endif()
configure_file(config.h.in ${PROJECT_BINARY_DIR}/config.h)
configure_file(de.rustysoft.kima2.metainfo.xml.in ${PROJECT_BINARY_DIR}/de.rustysoft.kima2.metainfo.xml)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
@ -79,6 +80,8 @@ else(WIN32 AND NOT UNIX)
DESTINATION share/${PROJECT_NAME})
install(FILES "${CMAKE_SOURCE_DIR}/misc/kima2.svg"
DESTINATION share/icons/hicolor/scalable/apps)
install(FILES de.rustysoft.kima2.metainfo.xml
DESTINATION share/metainfo)
endif (WIN32 AND NOT UNIX)
if( MINGW )
@ -95,10 +98,9 @@ if( MINGW )
${MINGW_PATH}/libwinpthread-1.dll
${MINGW_PATH}/libsqlite3-0.dll
${MINGW_PATH}/libusb-1.0.dll
${MINGW_PATH}/libxlnt.dll
${MINGW_PATH}/libicuuc71.dll
${MINGW_PATH}/libicuin71.dll
${MINGW_PATH}/libicudt71.dll
${MINGW_PATH}/libicuuc73.dll
${MINGW_PATH}/libicuin73.dll
${MINGW_PATH}/libicudt73.dll
${MINGW_PATH}/libpcre2-16-0.dll
${MINGW_PATH}/libpcre2-8-0.dll
${MINGW_PATH}/zlib1.dll
@ -115,7 +117,7 @@ if( MINGW )
${MINGW_PATH}/libmd4c.dll
${MINGW_PATH}/libbrotlicommon.dll
${MINGW_PATH}/libbrotlidec.dll
${MINGW_PATH}/libfmt.dll
#${MINGW_PATH}/libfmt.dll
${MINGW_PATH}/libb2-1.dll
${MINGW_PATH}/libiconv-2.dll)
install(FILES ${MINGW_PATH}/../share/qt6/plugins/platforms/qwindows.dll
@ -123,7 +125,7 @@ if( MINGW )
DESTINATION bin/platforms)
#install(FILES ${MINGW_PATH}/../share/qt6/plugins/printsupport/windowsprintersupport.dll
# DESTINATION bin/printsupport)
install(FILES ${MINGW_PATH}/../share/qt5/translations/qtbase_de.qm
install(FILES ${MINGW_PATH}/../share/qt6/translations/qtbase_de.qm
${MINGW_PATH}/../share/qt6/translations/qt_de.qm
${MINGW_PATH}/../share/qt6/translations/qt_help_de.qm
${MINGW_PATH}/../share/qt6/translations/qtmultimedia_de.qm

View file

@ -1,4 +1,4 @@
Copyright © 2018-2022 Martin Brodbeck
Copyright © 2018-2024 Martin Brodbeck
Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der
zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt,

View file

@ -18,14 +18,12 @@ Ubuntu, Windows) angeboten. Bitte die Hinweise dort beachten.
### Selbst compilieren
KIMA2 benötigt folgende Libraries:
* Qt5
* boost >= 1.62
* Qt 6
* boost >= 1.80
* libusb-1.0
* xlnt >= 1.3.0
* nlohmann-json (als 3rdparty submodule vorhanden)
Da Features aus C++17 verwendet werden sowie std::filesystem, sollte als Compiler mindestens
GCC 8 verwendet werden.
Da Features aus C++20 verwendet werden, sollte als Compiler mindestens GCC 12 verwendet werden.
Die Installationsschritte unter Linux sind wie folgt:
```
@ -37,4 +35,4 @@ sudo make install
```
Unter Windows muss vorab MinGW eingerichtet werden (z. B. MSYS2). Nach der Compilierung kann mit
`cpack -G NSIS` ein Installationspaket erstellt werden.
`cpack -G NSIS` ein Installationspaket erstellt werden.

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>de.rustysoft.kima2</id>
<name>KIMA2</name>
<summary>A small cash point program for childrens stuff markets</summary>
<metadata_license>MIT</metadata_license>
<project_license>GPL-3.0-or-later</project_license>
<releases>
<release version="@PROJECT_VERSION@" type="stable" date="2024-01-23" />
</releases>
<description>
<p>
A small cash point program for children's stuff markets. German language only.
</p>
</description>
<launchable type="desktop-id">de.rustysoft.kima2.desktop</launchable>
<screenshots>
<screenshot type="default">
<image>https://rustysoft.de/images/software/kima2/screenshot.png</image>
</screenshot>
</screenshots>
</component>

Binary file not shown.

Binary file not shown.

View file

@ -1,4 +1,4 @@
project('kima2', 'cpp', default_options : ['cpp_std=c++20'], version : '1.6.0')
project('kima2', 'cpp', default_options : ['cpp_std=c++20'], version : '1.8.0')
conf_data = configuration_data()
conf_data.set('PROJECT_VERSION', '"' + meson.project_version() + '"')

View file

@ -1,21 +1,27 @@
# Maintainer: Martin Brodbeck <martin at brodbeck-online dot de>
pkgname=kima2
pkgver=1.5.0
pkgver=1.7.1
pkgrel=1
pkgdesc="A small cash point program for children's things markets (German only)"
arch=('i686' 'x86_64')
url="http://www.rustysoft.de/?01_kima2"
url="http://www.rustysoft.de/software/kima2"
license=('custom')
depends=('glibc' 'libusb' 'qt5-base' 'sqlite3' 'xlnt')
depends=('glibc' 'libusb' 'qt6-base' 'sqlite3')
makedepends=('boost>=1.62')
source=($pkgname-$pkgver.tar.gz)
md5sums=('c0e6a64b5037675edce4ba8bc4639bd3')
source=(git+https://git.rustysoft.de/martin/kima2)
sha256sums=('SKIP')
build() {
if [ ! -d $pkgname/build ]; then
mkdir $pkgname/build
cd $pkgname
git checkout v$pkgver
git submodule init
git submodule update
if [ -d build ]; then
rm -rf build
fi
cd $pkgname/build
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DKIMA2_USE_EXTERNAL_JSON=OFF ..
make

View file

@ -3,8 +3,8 @@ Type=Application
Name=KIMA2
GenericName=Cash Point Program
GenericName[de]=Kassenprogramm
Comment=A small cash point program
Comment[de]=Ein kleines Kassenprogramm
Comment=A small cash point program for children's stuff markets
Comment[de]=Ein kleines Kassenprogramm für Kindersachenmärkte
Exec=kima2
Icon=kima2
Categories=Office;

View file

@ -13,7 +13,6 @@ BuildRequires: boost-date-time
BuildRequires: sqlite-devel
BuildRequires: libusb-devel
BuildRequires: qt5-qtdeclarative-devel
#BuildRequires: pkgconfig(xlnt)
#BuildRequires: pkgconfig(pthreads)
%description

View file

@ -1,22 +1,12 @@
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost 1.62 REQUIRED)
find_package(Boost 1.78 REQUIRED)
find_package(SQLite3 REQUIRED)
# Because csv-parser needs threads:
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
find_package(fmt)
if (MINGW)
find_package(XLNT REQUIRED STATIC)
else (MINGW)
find_package(PkgConfig REQUIRED)
pkg_check_modules(XLNT REQUIRED xlnt>=1.3)
endif (MINGW)
set(CORE_SOURCES
database.cpp
entity.cpp
@ -26,7 +16,6 @@ set(CORE_SOURCES
article.cpp
sale.cpp
marketplace.cpp
excelreader.cpp
csvreader.cpp
jsonutil.cpp
utils.cpp
@ -34,12 +23,12 @@ set(CORE_SOURCES
add_library(core STATIC ${CORE_SOURCES})
target_include_directories(core PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/csv-parser/single_include)
#target_include_directories(core PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/csv-parser/single_include)
if (WIN32)
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARY} Threads::Threads fmt::fmt)
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json)
target_link_libraries(core PRIVATE bcrypt)
else()
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARIES} Threads::Threads fmt::fmt)
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json)
endif()
target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)

View file

@ -3,7 +3,8 @@
#include <fstream>
#include <csv.hpp>
// #include <csv.hpp>
#include <boost/algorithm/string.hpp>
#ifdef DELETE
#undef DELETE
@ -13,17 +14,16 @@ namespace fs = std::filesystem;
std::size_t CsvReader::readSellersFromFile(const fs::path &filePath, Marketplace *market)
{
csv::CSVFormat format;
format.delimiter(';');
#if defined(_WIN64) || defined(_WIN32)
// Windows: Somhow this is necessary in order to open file names with umlauts
auto wide = filePath.wstring();
std::string fileName(wide.begin(), wide.end());
csv::CSVReader csvReader(fileName, format);
std::ifstream infile(fileName);
#else
csv::CSVReader csvReader(filePath.string(), format);
// csv::CSVReader csvReader(filePath.string(), format);
std::ifstream infile(filePath.string());
#endif
for (auto &seller : market->getSellers()) {
@ -32,28 +32,35 @@ std::size_t CsvReader::readSellersFromFile(const fs::path &filePath, Marketplace
market->storeToDb(true);
for (csv::CSVRow &row : csvReader) {
if (!row[0].is_int()) {
std::string line;
while (getline(infile, line)) {
std::vector<std::string> strs;
boost::split(strs, line, boost::is_any_of(";"));
auto seller = std::make_unique<Seller>();
try {
int sellerNo = std::stoi(strs[0]);
seller->setSellerNo(sellerNo);
} catch (std::invalid_argument const &ex) {
continue;
}
auto seller = std::make_unique<Seller>();
seller->setSellerNo(row[0].get<int>());
if (row[1].is_int()) {
seller->setNumArticlesOffered(row[1].get<int>());
} else {
if (isNumber(strs[1]))
seller->setNumArticlesOffered(std::stoi(strs[1]));
else
seller->setNumArticlesOffered(0);
}
// If both, first name and last name, are empty, use N. N.
// Else, use the real values.
if (row[2].get<std::string>().empty() && row[3].get<std::string>().empty()) {
if (strs[2].empty() && strs[2].empty()) {
seller->setFirstName("N.");
seller->setLastName("N.");
} else {
std::string firstName = row[2].get<std::string>();
std::string firstName = strs[2];
seller->setFirstName(trim(firstName));
std::string lastName = row[3].get<std::string>();
std::string lastName = strs[3];
seller->setLastName(trim(lastName));
}

View file

@ -2,7 +2,7 @@
#include <chrono>
#include <filesystem>
#include <fmt/chrono.h>
#include <format>
#include <iostream>
#include <stdexcept>
#include <vector>
@ -47,7 +47,7 @@ void Database::newDb()
fs::path destPath = sourcePath.parent_path() / sourcePath.stem();
auto chronoTime = std::chrono::system_clock::now();
std::string timeString = fmt::format("{0:%FT%H-%M-%S}", chronoTime);
std::string timeString = std::format("{0:%FT%H-%M-%S}", chronoTime);
destPath += std::string("_") += timeString += ".db";

View file

@ -1,72 +0,0 @@
#include "excelreader.h"
#include "utils.h"
#include <fstream>
#include <xlnt/xlnt.hpp>
namespace fs = std::filesystem;
std::size_t ExcelReader::readSellersFromFile(const fs::path &filePath, Marketplace *market)
{
xlnt::workbook wb;
std::ifstream mystream(filePath, std::ios::binary);
if (!mystream.is_open()) {
throw std::runtime_error("Could not open Excel file");
}
wb.load(mystream);
for (auto &seller : market->getSellers()) {
seller->setState(Seller::State::DELETE);
}
market->storeToDb(true);
auto ws = wb.sheet_by_index(0);
for (auto row : ws.rows(true)) {
// Skip the row if the first value is not a number (= seller no)
if (row[0].data_type() != xlnt::cell::type::number) {
continue;
}
auto seller = std::make_unique<Seller>();
seller->setSellerNo(row[0].value<int>());
seller->setNumArticlesOffered(row[1].value<int>());
// If both, first name and last name, are empty, use N. N.
// Else, use the real values.
if (row[2].value<std::string>().empty() && row[3].value<std::string>().empty()) {
seller->setFirstName("N.");
seller->setLastName("N.");
} else {
std::string firstName = row[2].value<std::string>();
seller->setFirstName(trim(firstName));
std::string lastName = row[3].value<std::string>();
seller->setLastName(trim(lastName));
}
market->getSellers().push_back(std::move(seller));
}
// Add one additional seller "RESERVE RESERVE"
auto seller = std::make_unique<Seller>();
seller->setSellerNo(market->getNextSellerNo());
seller->setFirstName("RESERVE");
seller->setLastName("RESERVE");
market->getSellers().push_back(std::move(seller));
// If there was no special seller "Sonderkonto" in import data, then create one
auto specialSeller = market->findSellerWithSellerNo(0);
if (!specialSeller) {
auto seller = std::make_unique<Seller>();
seller->setSellerNo(0);
seller->setLastName("Sonderkonto");
seller->setFirstName("Sonderkonto");
seller->setNumArticlesOffered(0);
market->getSellers().push_back(std::move(seller));
}
market->sortSellers();
market->storeToDb();
return market->getSellers().size() - 1; // minus 1 because we don't count the "special" seller
}

View file

@ -1,19 +0,0 @@
#ifndef EXCEL_READER_H
#define EXCEL_READER_H
#include "marketplace.h"
#include "seller.h"
#include <filesystem>
#include <memory>
#include <string>
#include <vector>
class ExcelReader
{
public:
static std::size_t readSellersFromFile(const std::filesystem::path &filePath,
Marketplace *market);
};
#endif

View file

@ -102,8 +102,10 @@ void JsonUtil::importSales(const std::filesystem::path &filePath, Marketplace *m
int source_no = jsonValues["source_no"];
if (source_no == cashPointNo) {
throw std::runtime_error("Die Kassen-Nr. der zu imporierenden Daten wird von dieser Kasse "
"hier bereits verwendet.");
std::string ret = "Die Kassen-Nr. ";
ret += std::to_string(source_no);
ret += " der zu imporierenden Daten wird von dieser Kasse hier bereits verwendet.";
throw std::runtime_error(ret);
}
market->setSalesToDelete(jsonValues["source_no"]);

View file

@ -2,13 +2,13 @@
#include <algorithm>
#include <clocale>
#include <fmt/format.h>
#include <format>
#include <iomanip>
#include <numeric>
#include <iostream>
using namespace fmt;
//using namespace fmt;
std::string formatCentAsEuroString(const int cent, int width)
{
@ -32,7 +32,7 @@ std::string formatCentAsEuroString(const int cent, int width)
#else
std::locale myLocale{"de_DE.utf8"};
#endif
return fmt::format(myLocale, "{:{}.2Lf} €", cent / 100.0L, width);
return std::format(myLocale, "{:{}.2Lf} €", cent / 100.0L, width);
}
std::string &ltrim(std::string &str, const std::string &chars)
@ -61,3 +61,10 @@ bool case_insensitive_match(std::string s1, std::string s2)
return true; // The strings are same
return false; // not matched
}
bool isNumber(const std::string &str)
{
return !str.empty() && std::find_if(str.begin(), str.end(), [](unsigned char c) {
return !std::isdigit(c);
}) == str.end();
}

View file

@ -10,5 +10,6 @@ std::string &ltrim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
std::string &rtrim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
std::string &trim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
bool case_insensitive_match(std::string s1, std::string s2);
bool isNumber(const std::string &str);
#endif

View file

@ -42,7 +42,7 @@ add_executable(kima2 ${GUI_SOURCES} kima2.rc)
target_include_directories(kima2 PRIVATE ${PROJECT_BINARY_DIR})
target_include_directories(kima2 PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git)
# target_link_libraries(kima2 core printer Qt5::Widgets Qt5::PrintSupport Qt5::Network stdc++fs)
target_link_libraries(kima2 core printer Qt::Core Qt::PrintSupport Qt::Network stdc++fs)
target_link_libraries(kima2 core printer Qt::Core Qt::PrintSupport Qt::Network)
if(WIN32)
set_target_properties(kima2 PROPERTIES LINK_FLAGS "-mwindows")

View file

@ -21,21 +21,12 @@ int main(int argc, char *argv[])
QCoreApplication::setOrganizationDomain("rustysoft.de");
QCoreApplication::setApplicationName("kima2");
QTranslator qTranslator;
QLocale german(QLocale::German);
#ifdef __linux__
bool retVal =
qTranslator.load("qt_" + german.name(), QLibraryInfo::path(QLibraryInfo::TranslationsPath));
if (!retVal) {
throw std::runtime_error("Could not load translation.");
QTranslator qtTranslator;
if (qtTranslator.load(QLocale::system(), u"qtbase"_qs, u"_"_qs,
QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
kimaApp.installTranslator(&qtTranslator);
}
#endif
#ifdef _WIN32
QApplication::setStyle(QStyleFactory::create("Fusion"));
qTranslator.load("qt_" + german.name(),
QApplication::applicationDirPath() + QDir::separator() + "translations");
#endif
kimaApp.installTranslator(&qTranslator);
QSettings settings{};
while (!settings.contains("global/cashPointNo")) {

View file

@ -9,7 +9,6 @@
#include <config.h>
#include <core/csvreader.h>
#include <core/excelreader.h>
#include <core/jsonutil.h>
#include <core/utils.h>
#include <printer/posprinter.h>
@ -100,14 +99,13 @@ MainWindow::MainWindow()
for (auto location : locations) {
if (QFile::exists(location + QString("/Benutzerhandbuch.pdf"))) {
QDesktopServices::openUrl(
QUrl(QString("file:///") + location + QString("/Benutzerhandbuch.pdf"),
QUrl::TolerantMode));
QUrl::fromLocalFile(location + QString("/Benutzerhandbuch.pdf")));
}
}
});
connect(m_ui.licenseAction, &QAction::triggered, this, [this]() {
QString licenseText(
"Copyright © 2018-2022 Martin Brodbeck\n\n"
"Copyright © 2018-2024 Martin Brodbeck\n\n"
"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, "
@ -137,12 +135,8 @@ MainWindow::MainWindow()
this->setWindowTitle("KIMA2 - Kasse Nr. " +
QSettings().value("global/cashPointNo").toString());
});
connect(m_ui.importSellerExcelAction, &QAction::triggered, this,
&MainWindow::onImportSellerExcelActionTriggered);
connect(m_ui.importSellerJsonAction, &QAction::triggered, this,
&MainWindow::onImportSellerJsonActionTriggered);
connect(m_ui.exportSellerJsonAction, &QAction::triggered, this,
&MainWindow::onExportSellerJsonActionTriggered);
connect(m_ui.importSellerAction, &QAction::triggered, this,
&MainWindow::onImportSellerActionTriggered);
connect(m_ui.exportSalesJsonAction, &QAction::triggered, this,
&MainWindow::onExportSalesJsonActionTriggered);
connect(m_ui.importSalesJsonAction, &QAction::triggered, this,
@ -345,7 +339,8 @@ void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
m_ui.basketView->model()->removeRow(iter->row());
}
m_ui.basketSumLabel->setText(m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
m_ui.basketSumLabel->setText(
m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
m_ui.sellerNoEdit->setFocus();
}
@ -428,7 +423,8 @@ void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked)
dynamic_cast<BasketModel *>(m_ui.basketView->model())->cancelSale();
m_ui.basketSumLabel->setText(m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
m_ui.basketSumLabel->setText(
m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
m_ui.sellerNoEdit->setFocus();
}
@ -445,7 +441,7 @@ void MainWindow::onAbout()
">info@rustysoft.de</a>&gt;</p>");
}
void MainWindow::onImportSellerExcelActionTriggered()
void MainWindow::onImportSellerActionTriggered()
{
if (!m_marketplace->getSales().empty()) {
QMessageBox(QMessageBox::Icon::Information, "Import nicht möglich",
@ -455,9 +451,9 @@ void MainWindow::onImportSellerExcelActionTriggered()
return;
}
auto filename = QFileDialog::getOpenFileName(
this, "Verkäufer importieren", QString(),
"Alle unterstützte Dateien (*.xlsx *.csv);;Excel Dateien (*.xlsx);;CSV Dateien (*.csv)");
auto filename =
QFileDialog::getOpenFileName(this, "Verkäufer importieren", QString(),
"Alle unterstützte Dateien (*.csv);;CSV Dateien (*.csv)");
if (filename.isEmpty())
return;
@ -469,86 +465,19 @@ void MainWindow::onImportSellerExcelActionTriggered()
#endif
std::size_t numImported{};
if (case_insensitive_match(filePath.extension().string(), std::string(".xlsx"))) {
try {
numImported = ExcelReader::readSellersFromFile(filePath, m_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;
}
} else {
numImported = CsvReader::readSellersFromFile(filePath, m_marketplace.get());
}
numImported = CsvReader::readSellersFromFile(filePath, m_marketplace.get());
updateStatLabel();
using namespace std::string_literals;
std::ostringstream msg;
msg << "Aus der Excel/CSV-Datei wurden <b>"s << std::to_string(numImported)
msg << "Aus der CSV-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)
.exec();
}
void MainWindow::onImportSellerJsonActionTriggered()
{
if (!m_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)
.exec();
return;
}
auto filename = QFileDialog::getOpenFileName(this, "Verkäufer importieren", QString(),
"JSON Dateien (*.json)");
if (filename.isEmpty())
return;
#if defined(_WIN64) || defined(_WIN32)
fs::path filePath(filename.toStdWString());
#else
fs::path filePath(filename.toStdString());
#endif
std::size_t numImported{};
numImported = JsonUtil::importSellers(filePath, m_marketplace.get());
updateStatLabel();
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)
.exec();
}
void MainWindow::onExportSellerJsonActionTriggered()
{
auto filename = QFileDialog::getSaveFileName(
this, "Verkäufer exportieren", QString("kima2_verkaeufer.json"), "JSON Dateien (*.json)");
if (filename.isEmpty())
return;
#if defined(_WIN64) || defined(_WIN32)
fs::path filePath(filename.toStdWString());
#else
fs::path filePath(filename.toStdString());
#endif
JsonUtil::exportSellers(filePath, m_marketplace.get());
}
void MainWindow::onExportSalesJsonActionTriggered()
{
QSettings settings;
@ -575,27 +504,30 @@ void MainWindow::onImportSalesJsonActionTriggered()
{
QSettings settings;
auto filename = QFileDialog::getOpenFileName(this, "Umsätze/Transaktionen importieren",
auto filenames = QFileDialog::getOpenFileNames(this, "Umsätze/Transaktionen importieren",
QString(), "JSON Dateien (*.json)");
if (filename.isEmpty())
if (filenames.isEmpty())
return;
for(auto filename: filenames) {
#if defined(_WIN64) || defined(_WIN32)
fs::path filePath(filename.toStdWString());
fs::path filePath(filename.toStdWString());
#else
fs::path filePath(filename.toStdString());
fs::path filePath(filename.toStdString());
#endif
delete m_ui.salesView->model();
try {
JsonUtil::importSales(filePath, m_marketplace.get(),
settings.value("global/cashPointNo").toInt());
} catch (std::runtime_error &err) {
QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok,
this)
.exec();
delete m_ui.salesView->model();
try {
JsonUtil::importSales(filePath, m_marketplace.get(),
settings.value("global/cashPointNo").toInt());
} catch (std::runtime_error &err) {
QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok,
this)
.exec();
}
}
setSaleModel();
updateStatLabel();
}

View file

@ -39,9 +39,7 @@ class MainWindow : public QMainWindow
void checkSellerNo(bool ctrlPressed = false);
void onPaidButtonTriggered();
void onGivenSpinBoxValueChanged(double value);
void onImportSellerExcelActionTriggered();
void onImportSellerJsonActionTriggered();
void onExportSellerJsonActionTriggered();
void onImportSellerActionTriggered();
void onExportSalesJsonActionTriggered();
void onImportSalesJsonActionTriggered();
void setSaleModel();

View file

@ -423,7 +423,7 @@ drucken</string>
<x>0</x>
<y>0</y>
<width>817</width>
<height>30</height>
<height>24</height>
</rect>
</property>
<widget class="QMenu" name="menu_Datei">
@ -440,16 +440,8 @@ drucken</string>
<property name="title">
<string>&amp;Verkäufer</string>
</property>
<widget class="QMenu" name="importSellerMenu">
<property name="title">
<string>Importieren</string>
</property>
<addaction name="importSellerExcelAction"/>
<addaction name="importSellerJsonAction"/>
</widget>
<addaction name="actionEditSeller"/>
<addaction name="importSellerMenu"/>
<addaction name="exportSellerJsonAction"/>
<addaction name="importSellerAction"/>
</widget>
<widget class="QMenu" name="menuHilfe">
<property name="title">
@ -513,9 +505,9 @@ drucken</string>
<string>Exportieren für andere Kasse (JSON)</string>
</property>
</action>
<action name="importSellerExcelAction">
<action name="importSellerActionX">
<property name="text">
<string>Aus Excel/CSV-Datei (initial)</string>
<string>Aus CSV-Datei (initial)</string>
</property>
</action>
<action name="importSellerJsonAction">
@ -548,6 +540,11 @@ drucken</string>
<string>Lizenz</string>
</property>
</action>
<action name="importSellerAction">
<property name="text">
<string>Importieren (aus CSV-Datei)</string>
</property>
</action>
</widget>
<resources/>
<connections/>

View file

@ -1,6 +1,6 @@
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost 1.62 REQUIRED)
find_package(Boost 1.78 REQUIRED)
if(WIN32)
find_package(LIBUSB REQUIRED)
@ -20,4 +20,4 @@ if(WIN32)
else()
target_link_libraries(printer core ${LibUSB_LIBRARIES})
endif()
target_include_directories(printer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
target_include_directories(printer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/.. ${Boost_INCLUDE_DIRS})

@ -1 +0,0 @@
Subproject commit ea547fdb16c7baf99bd9ced5febba52cc5da3ca3

@ -1 +1 @@
Subproject commit bc889afb4c5bf1c0d8ee29ef35eaaf4c8bef8a5d
Subproject commit 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03

@ -1 +1 @@
Subproject commit a3ed916f591c300e97b873fde36863fa37b49fa9
Subproject commit 8c48163c4d3fbba603cfe8a5b94046c9dad71825