Compare commits

..

No commits in common. "master" and "v1.5.0" have entirely different histories.

77 changed files with 904 additions and 1112 deletions

View file

@ -1,38 +1,27 @@
---
Language: Cpp Language: Cpp
# BasedOnStyle: LLVM # BasedOnStyle: LLVM
AccessModifierOffset: -4 AccessModifierOffset: -2
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignArrayOfStructures: None AlignConsecutiveAssignments: false
AlignConsecutiveMacros: None AlignConsecutiveDeclarations: false
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Right AlignEscapedNewlines: Right
AlignOperands: Align AlignOperands: true
AlignTrailingComments: true AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true AllowShortBlocksOnASingleLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All AllowShortIfStatementsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine AlwaysBreakTemplateDeclarations: false
AttributeMacros:
- __capability
BinPackArguments: true BinPackArguments: true
BinPackParameters: true BinPackParameters: true
BraceWrapping: BraceWrapping:
AfterCaseLabel: false AfterClass: true
AfterClass: false AfterControlStatement: false
AfterControlStatement: Never
AfterEnum: false AfterEnum: false
AfterFunction: false AfterFunction: false
AfterNamespace: false AfterNamespace: false
@ -42,21 +31,13 @@ BraceWrapping:
AfterExternBlock: false AfterExternBlock: false
BeforeCatch: false BeforeCatch: false
BeforeElse: false BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false IndentBraces: false
SplitEmptyFunction: true SplitEmptyFunction: true
SplitEmptyRecord: true SplitEmptyRecord: true
SplitEmptyNamespace: true SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: true BreakBeforeBraces: Linux
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterFunction: true
AfterNamespace: true
BreakBeforeInheritanceComma: false BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon BreakConstructorInitializers: BeforeColon
@ -69,56 +50,35 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4 ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4 ContinuationIndentWidth: 4
Cpp11BracedListStyle: true Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false DerivePointerAlignment: false
DisableFormat: false DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true FixNamespaceComments: true
ForEachMacros: ForEachMacros:
- foreach - foreach
- Q_FOREACH - Q_FOREACH
- BOOST_FOREACH - BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve IncludeBlocks: Preserve
IncludeCategories: IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2 Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)' - Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3 Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*' - Regex: '.*'
Priority: 1 Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$' IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseLabels: false IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 4 IndentWidth: 4
IndentWrappedFunctionNames: false IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave JavaScriptQuotes: Leave
JavaScriptWrapImports: true JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature
MacroBlockBegin: '' MacroBlockBegin: ''
MacroBlockEnd: '' MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1
NamespaceIndentation: None NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2 ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2 PenaltyBreakAssignment: 2
@ -126,57 +86,24 @@ PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300 PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120 PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000 PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000 PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60 PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0 PointerAlignment: Left
PointerAlignment: Right
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: true ReflowComments: true
ShortNamespaceLines: 1 SortIncludes: true
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true SortUsingDeclarations: true
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements SpaceBeforeParens: ControlStatements
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1 SpacesBeforeTrailingComments: 1
SpacesInAngles: Never SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false SpacesInParentheses: false
SpacesInSquareBrackets: false SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false Standard: Auto
BitFieldColonSpacing: Both
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8 TabWidth: 8
UseCRLF: false
UseTab: Never UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...

1
.gitignore vendored
View file

@ -1,4 +1,3 @@
build build
.vscode/ipch/* .vscode/ipch/*
.kdev4 .kdev4
.cache

11
.gitmodules vendored
View file

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

3
.vscode/launch.json vendored
View file

@ -21,8 +21,7 @@
"text": "-enable-pretty-printing", "text": "-enable-pretty-printing",
"ignoreFailures": true "ignoreFailures": true
} }
], ]
"visualizerFile": "/home/brodbemn/.config/Code - OSS/User/workspaceStorage/d64ec049841ecb3d43e402bb3c167cb5/tonka3000.qtvsctools/qt.natvis.xml"
} }
] ]
} }

42
.vscode/settings.json vendored
View file

@ -65,47 +65,9 @@
"condition_variable": "cpp", "condition_variable": "cpp",
"mutex": "cpp", "mutex": "cpp",
"hash_map": "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", "C_Cpp.clang_format_path": "/usr/bin/clang-format",
"cmake.configureOnOpen": true, "cmake.configureOnOpen": true,
"C_Cpp.configurationWarnings": "Disabled", "C_Cpp.configurationWarnings": "Disabled"
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/*/**": true,
"**/.hg/store/**": true,
".flatpak/**": true,
"_build/**": true
}
} }

View file

@ -2,4 +2,4 @@ if(NOT KIMA2_USE_EXTERNAL_JSON)
set(JSON_BuildTests OFF CACHE INTERNAL "") set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json EXCLUDE_FROM_ALL) add_subdirectory(nlohmann_json EXCLUDE_FROM_ALL)
endif() endif()
#add_subdirectory(csv-parser) add_subdirectory(csv-parser)

1
3rdparty/csv-parser vendored Submodule

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

1
3rdparty/nlohmann_json vendored Submodule

@ -0,0 +1 @@
Subproject commit 53c3eefa2cf790a7130fed3e13a3be35c2f2ace2

1
3rdparty/singleapplication vendored Submodule

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

View file

@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.8)
project(kima2 VERSION 1.8.3) project(kima2 VERSION 1.5.0)
set(CMAKE_MODULE_PATH "${CMAKE_HOME_DIRECTORY}/cmake") set(CMAKE_MODULE_PATH "${CMAKE_HOME_DIRECTORY}/cmake")
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
#include(InstallRequiredSystemLibraries) #include(InstallRequiredSystemLibraries)
@ -17,7 +17,6 @@ else()
endif() endif()
configure_file(config.h.in ${PROJECT_BINARY_DIR}/config.h) 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_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
@ -29,7 +28,7 @@ if(KIMA2_USE_EXTERNAL_JSON)
find_package(nlohmann_json REQUIRED) find_package(nlohmann_json REQUIRED)
endif() endif()
add_subdirectory(subprojects) add_subdirectory(3rdparty)
add_subdirectory(src) add_subdirectory(src)
#if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE MATCHES Debug) #if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE MATCHES Debug)
@ -80,8 +79,6 @@ else(WIN32 AND NOT UNIX)
DESTINATION share/${PROJECT_NAME}) DESTINATION share/${PROJECT_NAME})
install(FILES "${CMAKE_SOURCE_DIR}/misc/kima2.svg" install(FILES "${CMAKE_SOURCE_DIR}/misc/kima2.svg"
DESTINATION share/icons/hicolor/scalable/apps) DESTINATION share/icons/hicolor/scalable/apps)
install(FILES de.rustysoft.kima2.metainfo.xml
DESTINATION share/metainfo)
endif (WIN32 AND NOT UNIX) endif (WIN32 AND NOT UNIX)
if( MINGW ) if( MINGW )
@ -90,19 +87,18 @@ if( MINGW )
set( CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS set( CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
${MINGW_PATH}/libstdc++-6.dll ${MINGW_PATH}/libstdc++-6.dll
${MINGW_PATH}/libgcc_s_seh-1.dll ${MINGW_PATH}/libgcc_s_seh-1.dll
${MINGW_PATH}/Qt6Core.dll ${MINGW_PATH}/Qt5Core.dll
${MINGW_PATH}/Qt6Gui.dll ${MINGW_PATH}/Qt5Gui.dll
${MINGW_PATH}/Qt6Widgets.dll ${MINGW_PATH}/Qt5Widgets.dll
${MINGW_PATH}/Qt6PrintSupport.dll ${MINGW_PATH}/Qt5PrintSupport.dll
${MINGW_PATH}/Qt6Network.dll
${MINGW_PATH}/libwinpthread-1.dll ${MINGW_PATH}/libwinpthread-1.dll
${MINGW_PATH}/libsqlite3-0.dll ${MINGW_PATH}/libsqlite3-0.dll
${MINGW_PATH}/libusb-1.0.dll ${MINGW_PATH}/libusb-1.0.dll
${MINGW_PATH}/libicuuc75.dll ${MINGW_PATH}/libxlnt.dll
${MINGW_PATH}/libicuin75.dll ${MINGW_PATH}/libicuuc64.dll
${MINGW_PATH}/libicudt75.dll ${MINGW_PATH}/libicuin64.dll
${MINGW_PATH}/libicudt64.dll
${MINGW_PATH}/libpcre2-16-0.dll ${MINGW_PATH}/libpcre2-16-0.dll
${MINGW_PATH}/libpcre2-8-0.dll
${MINGW_PATH}/zlib1.dll ${MINGW_PATH}/zlib1.dll
${MINGW_PATH}/libharfbuzz-0.dll ${MINGW_PATH}/libharfbuzz-0.dll
${MINGW_PATH}/libpng16-16.dll ${MINGW_PATH}/libpng16-16.dll
@ -112,26 +108,20 @@ if( MINGW )
${MINGW_PATH}/libbz2-1.dll ${MINGW_PATH}/libbz2-1.dll
${MINGW_PATH}/libintl-8.dll ${MINGW_PATH}/libintl-8.dll
${MINGW_PATH}/libpcre-1.dll ${MINGW_PATH}/libpcre-1.dll
${MINGW_PATH}/libdouble-conversion.dll
${MINGW_PATH}/libzstd.dll
${MINGW_PATH}/libmd4c.dll
${MINGW_PATH}/libbrotlicommon.dll
${MINGW_PATH}/libbrotlidec.dll
#${MINGW_PATH}/libfmt.dll
${MINGW_PATH}/libb2-1.dll
${MINGW_PATH}/libiconv-2.dll) ${MINGW_PATH}/libiconv-2.dll)
install(FILES ${MINGW_PATH}/../share/qt6/plugins/platforms/qwindows.dll install(FILES ${MINGW_PATH}/../share/qt5/plugins/platforms/qwindows.dll
${MINGW_PATH}/../share/qt6/plugins/platforms/qminimal.dll ${MINGW_PATH}/../share/qt5/plugins/platforms/qminimal.dll
DESTINATION bin/platforms) DESTINATION bin/platforms)
#install(FILES ${MINGW_PATH}/../share/qt6/plugins/printsupport/windowsprintersupport.dll install(FILES ${MINGW_PATH}/../share/qt5/plugins/printsupport/windowsprintersupport.dll
# DESTINATION bin/printsupport) DESTINATION bin/printsupport)
install(FILES ${MINGW_PATH}/../share/qt6/translations/qtbase_de.qm install(FILES ${MINGW_PATH}/../share/qt5/translations/qtbase_de.qm
${MINGW_PATH}/../share/qt6/translations/qt_de.qm ${MINGW_PATH}/../share/qt5/translations/qt_de.qm
${MINGW_PATH}/../share/qt6/translations/qt_help_de.qm ${MINGW_PATH}/../share/qt5/translations/qt_help_de.qm
${MINGW_PATH}/../share/qt6/translations/qtmultimedia_de.qm ${MINGW_PATH}/../share/qt5/translations/qtmultimedia_de.qm
DESTINATION bin/share/qt6/translations) ${MINGW_PATH}/../share/qt5/translations/qtquickcontrols_de.qm
install(FILES ${MINGW_PATH}/../share/qt6/plugins/styles/qmodernwindowsstyle.dll ${MINGW_PATH}/../share/qt5/translations/qtscript_de.qm
DESTINATION bin/styles) ${MINGW_PATH}/../share/qt5/translations/qtxmlpatterns_de.qm
DESTINATION bin/translations)
endif( MINGW ) endif( MINGW )
include(InstallRequiredSystemLibraries) include(InstallRequiredSystemLibraries)

View file

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

View file

@ -13,16 +13,19 @@ Verkaufsdaten nach dem Verkaufsende auszutauschen.
Ebenso können über einen ESC/POS-Drucker Quittungen ausgestellt werden. Ebenso können über einen ESC/POS-Drucker Quittungen ausgestellt werden.
## Installation ## Installation
Auf [rustysoft.de](https://www.rustysoft.de/software/kima2/) werden die Installationsmöglichkeiten (Flatpak, Windows-Installer) erläutert. Bitte die Hinweise dort beachten. Auf [rustysoft.de](https://www.rustysoft.de/?01_kima2) werden verschiedene Installationspakete (Arch Linux,
Ubuntu, Windows) angeboten. Bitte die Hinweise dort beachten.
## Selbst compilieren ### Selbst compilieren
KIMA2 benötigt folgende Libraries: KIMA2 benötigt folgende Libraries:
* Qt 6 * Qt5
* boost >= 1.80 * boost >= 1.62
* libusb-1.0 * libusb-1.0
* xlnt >= 1.3.0
* nlohmann-json (als 3rdparty submodule vorhanden) * nlohmann-json (als 3rdparty submodule vorhanden)
Da Features aus C++20 sowie von neueren Compilern verwendet werden, sollte als Compiler mindestens GCC 14 verwendet werden. Da Features aus C++17 verwendet werden sowie std::filesystem, sollte als Compiler mindestens
GCC 8 verwendet werden.
Die Installationsschritte unter Linux sind wie folgt: Die Installationsschritte unter Linux sind wie folgt:
``` ```

View file

@ -1,27 +0,0 @@
<?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,33 +0,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() + '"')
configure_file(output : 'config.h',
configuration : conf_data)
configuration_inc = include_directories('.')
#csv = cmake.subproject('csv-parser')
#csv_lib = csv.dependency('csv')
nlohmann_lib = dependency('nlohmann_json', version : '>=3.5.0', required : false)
if not nlohmann_lib.found()
nlohmann_inc = include_directories('subprojects/nlohmann_json/single_include')
nlohmann_lib = declare_dependency(include_directories : nlohmann_inc)
endif
csv_inc = include_directories('subprojects/csv-parser/single_include')
csv_dep = declare_dependency(include_directories : csv_inc)
singleapp_proj = subproject('singleapplication')
singleapp_lib = singleapp_proj.get_variable('singleapp_lib')
singleapp_dep = singleapp_proj.get_variable('singleapp_dep')
subdir('src')
if build_machine.system() == 'linux'
install_data('misc/kima2.svg', install_dir : get_option('datadir') / 'icons/hicolor/scalable/apps')
install_data('misc/kima2.desktop', install_dir : get_option('datadir') / 'applications')
install_data('manual/Benutzerhandbuch.pdf', install_dir : get_option('datadir') / 'kima2')
endif

View file

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

View file

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

View file

@ -1,43 +0,0 @@
Name: kima2
Version: 1.6.0
Release: 1%{?dist}
Summary: A small cash point program for children's things markets
License: custom
Source0: %{name}-%{version}.tar.gz
BuildRequires: meson
BuildRequires: gcc-c++
#BuildRequires: pkgconfig(nlohmann_json)
BuildRequires: boost-date-time
BuildRequires: sqlite-devel
BuildRequires: libusb-devel
BuildRequires: qt5-qtdeclarative-devel
#BuildRequires: pkgconfig(pthreads)
%description
%prep
%autosetup
%build
%meson
%meson_build
%install
%meson_install
%check
%meson_test
%files
%{_bindir}/kima2
%{_datadir}/applications/kima2.desktop
%{_datadir}/icons/hicolor/scalable/apps/kima2.svg
%{_datadir}/kima2/Benutzerhandbuch.pdf
%changelog
* Fri Oct 11 2019 Martin Brodbeck <infor@rustysoft.de> - dev builds
-

View file

@ -1,11 +1,14 @@
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_LIBS ON)
find_package(Boost 1.78 REQUIRED) find_package(Boost 1.62 COMPONENTS date_time REQUIRED)
find_package(SQLite3 REQUIRED) find_package(SQLite3 REQUIRED)
# Because csv-parser needs threads: if (MINGW)
find_package(XLNT REQUIRED STATIC)
find_package(fmt) else (MINGW)
find_package(PkgConfig REQUIRED)
pkg_check_modules(XLNT REQUIRED xlnt>=1.3)
endif (MINGW)
set(CORE_SOURCES set(CORE_SOURCES
database.cpp database.cpp
@ -16,6 +19,7 @@ set(CORE_SOURCES
article.cpp article.cpp
sale.cpp sale.cpp
marketplace.cpp marketplace.cpp
excelreader.cpp
csvreader.cpp csvreader.cpp
jsonutil.cpp jsonutil.cpp
utils.cpp utils.cpp
@ -23,12 +27,13 @@ set(CORE_SOURCES
add_library(core STATIC ${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}/3rdparty/csv-parser/include)
if (WIN32) if (WIN32)
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json) target_link_libraries(core PRIVATE printer Boost::boost Boost::date_time sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARY} csv)
target_link_libraries(core PRIVATE bcrypt) target_link_libraries(core PRIVATE bcrypt)
else() else()
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json) target_link_libraries(core PRIVATE printer Boost::boost Boost::date_time sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARIES} csv)
endif() endif()
target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..) #target_include_directories(core PRIVATE ${PROJECT_SOURCE_DIR}/3rdparty/csv-parser)
target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View file

@ -1,38 +1,37 @@
#include "article.h" #include "article.h"
#include "seller.h"
#include "utils.h" #include "utils.h"
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
Article::Article(int price) : m_price(price) {} Article::Article(int price) : price_(price) {}
void Article::setArticleNo(int articleNo) { m_articleNo = articleNo; } void Article::setArticleNo(int articleNo) { articleNo_ = articleNo; }
void Article::setPrice(int price) { m_price = price; } void Article::setPrice(int price) { price_ = price; }
void Article::setDescription(const std::string &description) { m_description = description; } void Article::setDescription(const std::string& description) { description_ = description; }
void Article::setSale(Sale *salePtr) { m_salePtr = salePtr; } void Article::setSale(Sale* salePtr) { salePtr_ = salePtr; }
void Article::setSeller(Seller *sellerPtr) { m_sellerPtr = sellerPtr; } void Article::setSeller(Seller* sellerPtr) { sellerPtr_ = sellerPtr; }
bool Article::isSold() { return m_salePtr ? true : false; } bool Article::isSold() { return salePtr_ ? true : false; }
std::string Article::getDescription() { return m_description; } std::string Article::getDescription() { return description_; }
Seller *Article::getSeller() { return m_sellerPtr; } Seller* Article::getSeller() { return sellerPtr_; }
Sale *Article::getSale() { return m_salePtr; } Sale* Article::getSale() { return salePtr_; }
int Article::getPrice() const { return m_price; } int Article::getPrice() const { return price_; }
std::string Article::getPriceAsString() const { return formatCentAsEuroString(m_price); } std::string Article::getPriceAsString() const { return formatCentAsEuroString(price_); }
int Article::getArticleNo() const { return m_articleNo; } int Article::getArticleNo() const { return articleNo_; }
std::string Article::getCompleteArticleNo() const std::string Article::getCompleteArticleNo() const
{ {
std::stringstream artNoStream; std::stringstream artNoStream;
artNoStream << m_sourceNo << "K" << std::setfill('0') << std::setw(5) << m_articleNo; artNoStream << sourceNo_ << "K" << std::setfill('0') << std::setw(5) << articleNo_;
return artNoStream.str(); return artNoStream.str();
} }

View file

@ -2,6 +2,8 @@
#define ARTICLE_H #define ARTICLE_H
#include "entityuuid.h" #include "entityuuid.h"
//#include "sale.h"
//#include "seller.h"
#include <memory> #include <memory>
#include <string> #include <string>
@ -33,11 +35,11 @@ public:
std::string getPriceAsString() const; std::string getPriceAsString() const;
private: private:
Seller *m_sellerPtr{}; Seller* sellerPtr_{};
Sale *m_salePtr{}; Sale* salePtr_{};
int m_articleNo{}; int articleNo_{};
int m_price{}; int price_{};
std::string m_description{}; std::string description_{};
}; };
#endif #endif

View file

@ -2,28 +2,23 @@
#include "utils.h" #include "utils.h"
#include <fstream> #include <fstream>
#include <csv.hpp>
// #include <csv.hpp>
#include <boost/algorithm/string.hpp>
#ifdef DELETE
#undef DELETE
#endif
namespace fs = std::filesystem; namespace fs = std::filesystem;
std::size_t CsvReader::readSellersFromFile(const fs::path& filePath, Marketplace* market) std::size_t CsvReader::readSellersFromFile(const fs::path& filePath, Marketplace* market)
{ {
csv::CSVFormat format;
format.delimiter(';');
#if defined(_WIN64) || defined(_WIN32) #if defined(_WIN64) || defined(_WIN32)
// Windows: Somhow this is necessary in order to open file names with umlauts // Windows: Somhow this is necessary in order to open file names with umlauts
auto wide = filePath.wstring(); auto wide = filePath.wstring();
std::string fileName(wide.begin(), wide.end()); std::string fileName(wide.begin(), wide.end());
std::ifstream infile(fileName); csv::CSVReader csvReader(fileName, format);
#else #else
// csv::CSVReader csvReader(filePath.string(), format); csv::CSVReader csvReader(filePath.string(), format);
std::ifstream infile(filePath.string());
#endif #endif
for (auto& seller : market->getSellers()) { for (auto& seller : market->getSellers()) {
@ -32,47 +27,32 @@ std::size_t CsvReader::readSellersFromFile(const fs::path &filePath, Marketplace
market->storeToDb(true); market->storeToDb(true);
std::string line; int rowCount{};
for (csv::CSVRow &row : csvReader) {
while (getline(infile, line)) { if (!row[0].is_int()) {
std::vector<std::string> strs; ++rowCount;
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; continue;
} }
if (isNumber(strs[1])) if (row[2].get<std::string>().empty() && row[3].get<std::string>().empty()) {
seller->setNumArticlesOffered(std::stoi(strs[1])); ++rowCount;
else continue;
seller->setNumArticlesOffered(0);
// If both, first name and last name, are empty, use N. N.
// Else, use the real values.
if (strs[2].empty() && strs[2].empty()) {
seller->setFirstName("N.");
seller->setLastName("N.");
} else {
std::string firstName = strs[2];
seller->setFirstName(trim(firstName));
std::string lastName = strs[3];
seller->setLastName(trim(lastName));
} }
market->getSellers().push_back(std::move(seller));
}
// Add one additional seller "RESERVE RESERVE"
auto seller = std::make_unique<Seller>(); auto seller = std::make_unique<Seller>();
seller->setSellerNo(market->getNextSellerNo()); seller->setSellerNo(row[0].get<int>());
seller->setFirstName("RESERVE"); if (row[1].is_int()) {
seller->setLastName("RESERVE"); seller->setNumArticlesOffered(row[1].get<int>());
} else {
seller->setNumArticlesOffered(0);
}
std::string firstName = row[2].get<std::string>();
seller->setFirstName(trim(firstName));
std::string lastName = row[3].get<std::string>();
seller->setLastName(trim(lastName));
market->getSellers().push_back(std::move(seller)); market->getSellers().push_back(std::move(seller));
rowCount++;
}
// If there was no special seller "Sonderkonto" in import data, then create one // If there was no special seller "Sonderkonto" in import data, then create one
auto specialSeller = market->findSellerWithSellerNo(0); auto specialSeller = market->findSellerWithSellerNo(0);

View file

@ -1,12 +1,12 @@
#include "database.h" #include "database.h"
#include <chrono>
#include <filesystem> #include <filesystem>
#include <format>
#include <iostream> #include <iostream>
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
#include "boost/date_time/posix_time/posix_time.hpp"
Database::Database(const std::string& dbname) Database::Database(const std::string& dbname)
{ {
dbname_ = dbname; dbname_ = dbname;
@ -45,11 +45,8 @@ void Database::newDb()
fs::path sourcePath = dbname_; fs::path sourcePath = dbname_;
fs::path destPath = sourcePath.parent_path() / sourcePath.stem(); fs::path destPath = sourcePath.parent_path() / sourcePath.stem();
destPath += std::string("_") +=
auto chronoTime = std::chrono::system_clock::now(); boost::posix_time::to_iso_string(boost::posix_time::second_clock::local_time()) += ".db";
std::string timeString = std::format("{0:%FT%H-%M-%S}", chronoTime);
destPath += std::string("_") += timeString += ".db";
fs::copy_file(sourcePath, destPath, fs::copy_options::overwrite_existing); fs::copy_file(sourcePath, destPath, fs::copy_options::overwrite_existing);
@ -597,8 +594,7 @@ unsigned int Database::loadSellers(std::vector<std::unique_ptr<Seller>> &sellers
while (retCode != SQLITE_DONE) { while (retCode != SQLITE_DONE) {
++count; ++count;
auto article = std::make_unique<Article>(); auto article = std::make_unique<Article>();
article->setUuidFromString( article->setUuidFromString(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)));
article->setSeller(seller.get()); article->setSeller(seller.get());
article->setSourceNo(sqlite3_column_int(stmt, 1)); article->setSourceNo(sqlite3_column_int(stmt, 1));
article->setArticleNo(sqlite3_column_int(stmt, 2)); article->setArticleNo(sqlite3_column_int(stmt, 2));

View file

@ -1,3 +1,6 @@
#include "entity.h" #include "entity.h"
Entity::State Entity::getState() const { return m_state; } Entity::State Entity::getState() const
{
return state_;
}

View file

@ -6,11 +6,11 @@ class Entity
public: public:
enum class State { NEW, UPDATE, DELETE, OK }; enum class State { NEW, UPDATE, DELETE, OK };
virtual ~Entity() = default; virtual ~Entity() = default;
void setState(State state) { m_state = state; } void setState(State state) { state_ = state; }
virtual State getState() const; virtual State getState() const;
private: private:
State m_state{State::NEW}; State state_{State::NEW};
}; };
#endif // ENTITY_H #endif // ENTITY_H

View file

@ -1,5 +1,5 @@
#include "entityint.h" #include "entityint.h"
EntityInt::EntityInt(int id) { m_id = id; } EntityInt::EntityInt(int id) { id_ = id; }
void EntityInt::setId(int id) { m_id = id; } void EntityInt::setId(int id) { id_ = id; }

View file

@ -10,10 +10,10 @@ public:
virtual ~EntityInt() = default; virtual ~EntityInt() = default;
EntityInt(int id); EntityInt(int id);
void setId(int id); void setId(int id);
int getId() const { return m_id; }; int getId() const { return id_; };
protected: protected:
int m_id{}; int id_{};
}; };
#endif // ENTITY_INT_H #endif // ENTITY_INT_H

View file

@ -8,15 +8,15 @@
void EntityUuid::createUuid() void EntityUuid::createUuid()
{ {
static boost::uuids::random_generator generator{}; static boost::uuids::random_generator generator{};
m_uuid = generator(); uuid_ = generator();
} }
void EntityUuid::setUuidFromString(const std::string& uuidString) void EntityUuid::setUuidFromString(const std::string& uuidString)
{ {
boost::uuids::string_generator generator{}; boost::uuids::string_generator generator{};
m_uuid = generator(uuidString); uuid_ = generator(uuidString);
} }
void EntityUuid::setSourceNo(int sourceNo) { m_sourceNo = sourceNo; } void EntityUuid::setSourceNo(int sourceNo) { sourceNo_ = sourceNo; }
int EntityUuid::getSourceNo() const { return m_sourceNo; } int EntityUuid::getSourceNo() const { return sourceNo_; }

View file

@ -18,15 +18,15 @@ public:
void setUuidFromString(const std::string& uuidString); void setUuidFromString(const std::string& uuidString);
void setSourceNo(int sourceNo); void setSourceNo(int sourceNo);
const boost::uuids::uuid &getUuid() const { return m_uuid; }; const boost::uuids::uuid& getUuid() const { return uuid_; };
std::string getUuidAsString() const { return boost::uuids::to_string(m_uuid); } std::string getUuidAsString() const { return boost::uuids::to_string(uuid_); }
virtual int getSourceNo() const; virtual int getSourceNo() const;
protected: protected:
int m_sourceNo{}; int sourceNo_{};
private: private:
boost::uuids::uuid m_uuid{}; boost::uuids::uuid uuid_{};
}; };
#endif // ENTITY_UUID_H #endif // ENTITY_UUID_H

67
src/core/excelreader.cpp Normal file
View file

@ -0,0 +1,67 @@
#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);
const int START_ROW = 5;
const int END_ROW = 504;
int rowCount{};
for (const auto& row : ws.rows(false)) {
if (rowCount < START_ROW) {
++rowCount;
continue;
} else if (rowCount > END_ROW) {
break;
}
if (row[2].value<std::string>().empty() && row[3].value<std::string>().empty()) {
++rowCount;
continue;
}
auto seller = std::make_unique<Seller>();
seller->setSellerNo(row[0].value<int>());
seller->setNumArticlesOffered(row[1].value<int>());
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));
rowCount++;
}
// 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
}

19
src/core/excelreader.h Normal file
View file

@ -0,0 +1,19 @@
#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

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

View file

@ -1,13 +0,0 @@
boost = dependency('boost', modules: ['date_time'], static: true)
xlnt = dependency('xlnt')
sqlite = dependency('sqlite3')
src = ['database.cpp', 'entity.cpp', 'entityint.cpp', 'entityuuid.cpp',
'seller.cpp', 'article.cpp', 'sale.cpp', 'marketplace.cpp',
'excelreader.cpp', 'csvreader.cpp', 'jsonutil.cpp', 'utils.cpp']
core_inc = include_directories('..')
core_lib = static_library('core', src, dependencies: [boost, xlnt, sqlite, nlohmann_lib, csv_dep])
core_dep = declare_dependency(link_with: core_lib, include_directories : core_inc)

View file

@ -6,38 +6,38 @@
void Sale::addArticle(Article* articlePtr) void Sale::addArticle(Article* articlePtr)
{ {
articlePtr->setSale(this); articlePtr->setSale(this);
m_articles.push_back(articlePtr); articles_.push_back(articlePtr);
} }
ArticlesVec &Sale::getArticles() { return m_articles; } ArticlesVec& Sale::getArticles() { return articles_; }
void Sale::removeArticle(const Article* articlePtr) void Sale::removeArticle(const Article* articlePtr)
{ {
auto it = std::find(m_articles.begin(), m_articles.end(), articlePtr); auto it = std::find(articles_.begin(), articles_.end(), articlePtr);
if (it != m_articles.end()) { if (it != articles_.end()) {
(*it)->setSale(nullptr); (*it)->setSale(nullptr);
(*it)->setState( (*it)->setState(
Article::State::DELETE); // since we only have ad-hoc articles, that have all been sold Article::State::DELETE); // since we only have ad-hoc articles, that have all been sold
m_articles.erase(it); articles_.erase(it);
} }
} }
int Sale::sumInCents() int Sale::sumInCents()
{ {
int sum = std::accumulate(m_articles.begin(), m_articles.end(), 0, int sum = std::accumulate(articles_.begin(), articles_.end(), 0,
[](int a, const Article* b) { return a + b->getPrice(); }); [](int a, const Article* b) { return a + b->getPrice(); });
return sum; return sum;
} }
std::string Sale::sumAsString() { return formatCentAsEuroString(sumInCents()); } std::string Sale::sumAsString() { return formatCentAsEuroString(sumInCents()); }
std::string Sale::getTimestamp() const { return m_timestamp; } std::string Sale::getTimestamp() const { return timestamp_; }
void Sale::setTimestamp(const std::string &timestamp) { m_timestamp = timestamp; } void Sale::setTimestamp(const std::string& timestamp) { timestamp_ = timestamp; }
std::string Sale::getTimestampFormatted() const std::string Sale::getTimestampFormatted() const
{ {
boost::posix_time::ptime time = boost::posix_time::from_iso_extended_string(m_timestamp); boost::posix_time::ptime time = boost::posix_time::from_iso_extended_string(timestamp_);
return boost::posix_time::to_simple_string(time); return boost::posix_time::to_simple_string(time);
} }

View file

@ -32,9 +32,9 @@ public:
void removeArticle(const Article* articlePtr); void removeArticle(const Article* articlePtr);
private: private:
std::string m_timestamp{ std::string timestamp_{
boost::posix_time::to_iso_extended_string(boost::posix_time::second_clock::local_time())}; boost::posix_time::to_iso_extended_string(boost::posix_time::second_clock::local_time())};
mutable ArticlesVec m_articles{}; mutable ArticlesVec articles_{};
}; };
#endif #endif

View file

@ -9,28 +9,28 @@ Seller::Seller(const std::string &firstName, const std::string &lastName, int se
int numArticlesOffered) int numArticlesOffered)
: EntityInt(sellerNo) : EntityInt(sellerNo)
{ {
m_firstName = firstName; firstName_ = firstName;
m_lastName = lastName; lastName_ = lastName;
m_numArticlesOffered = numArticlesOffered; numArticlesOffered_ = numArticlesOffered;
} }
void Seller::setSellerNo(int seller_no) { setId(seller_no); } void Seller::setSellerNo(int seller_no) { setId(seller_no); }
void Seller::setFirstName(const std::string &firstName) { m_firstName = firstName; } void Seller::setFirstName(const std::string& firstName) { firstName_ = firstName; }
void Seller::setLastName(const std::string &lastName) { m_lastName = lastName; } void Seller::setLastName(const std::string& lastName) { lastName_ = lastName; }
void Seller::setNumArticlesOffered(int number) { m_numArticlesOffered = number; } void Seller::setNumArticlesOffered(int number) { numArticlesOffered_ = number; }
void Seller::addArticle(std::unique_ptr<Article> article) void Seller::addArticle(std::unique_ptr<Article> article)
{ {
article->setSeller(this); article->setSeller(this);
m_articles.push_back(std::move(article)); articles_.push_back(std::move(article));
} }
std::string Seller::getFirstName() const { return m_firstName; } std::string Seller::getFirstName() const { return firstName_; }
std::string Seller::getLastName() const { return m_lastName; } std::string Seller::getLastName() const { return lastName_; }
int Seller::getSellerNo() const { return getId(); } int Seller::getSellerNo() const { return getId(); }
@ -38,7 +38,7 @@ std::string Seller::getSellerNoAsString() const
{ {
std::stringstream selNoStr; std::stringstream selNoStr;
selNoStr << std::setfill('0') << std::setw(3) << m_id; selNoStr << std::setfill('0') << std::setw(3) << id_;
return selNoStr.str(); return selNoStr.str();
; ;
@ -47,7 +47,7 @@ std::string Seller::getSellerNoAsString() const
std::vector<Article*> Seller::getArticles(bool onlySold) const std::vector<Article*> Seller::getArticles(bool onlySold) const
{ {
std::vector<Article*> articles; std::vector<Article*> articles;
for (const auto &article : m_articles) { for (const auto& article : articles_) {
if (onlySold && article->isSold()) { if (onlySold && article->isSold()) {
articles.push_back(article.get()); articles.push_back(article.get());
} else if (!onlySold) { } else if (!onlySold) {
@ -59,52 +59,52 @@ std::vector<Article *> Seller::getArticles(bool onlySold) const
Article* Seller::getArticleByUuid(const std::string& uuidString) Article* Seller::getArticleByUuid(const std::string& uuidString)
{ {
auto iter = std::find_if(m_articles.begin(), m_articles.end(), [&uuidString](const auto &art) { auto iter = std::find_if(articles_.begin(), articles_.end(), [&uuidString](const auto& art) {
return art->getUuidAsString() == uuidString; return art->getUuidAsString() == uuidString;
}); });
if (iter == m_articles.end()) if (iter == articles_.end())
return nullptr; return nullptr;
return (*iter).get(); return (*iter).get();
} }
int Seller::numArticlesSold() const { return static_cast<int>(getArticles(true).size()); } int Seller::numArticlesSold() const { return static_cast<int>(getArticles(true).size()); }
int Seller::numArticlesOffered() const { return m_numArticlesOffered; } int Seller::numArticlesOffered() const { return numArticlesOffered_; }
int Seller::getMaxArticleNo() const int Seller::getMaxArticleNo() const
{ {
auto iter = std::max_element( auto iter = std::max_element(
m_articles.begin(), m_articles.end(), articles_.begin(), articles_.end(),
[](const auto& a, const auto& b) -> bool { return a->getArticleNo() < b->getArticleNo(); }); [](const auto& a, const auto& b) -> bool { return a->getArticleNo() < b->getArticleNo(); });
if (iter == m_articles.end()) if (iter == articles_.end())
return 0; return 0;
return (*iter)->getArticleNo(); return (*iter)->getArticleNo();
} }
void Seller::cleanupArticles() void Seller::cleanupArticles()
{ {
m_articles.erase(std::remove_if(m_articles.begin(), m_articles.end(), articles_.erase(std::remove_if(articles_.begin(), articles_.end(),
[](const auto& article) { [](const auto& article) {
return article->getState() == Article::State::DELETE; return article->getState() == Article::State::DELETE;
}), }),
m_articles.end()); articles_.end());
for (auto &article : m_articles) { for (auto& article : articles_) {
article->setState(Article::State::OK); article->setState(Article::State::OK);
} }
} }
int Seller::sumInCents() int Seller::sumInCents()
{ {
int sum = std::accumulate(m_articles.begin(), m_articles.end(), 0, int sum = std::accumulate(articles_.begin(), articles_.end(), 0,
[](int a, const auto& b) { return a + b->getPrice(); }); [](int a, const auto& b) { return a + b->getPrice(); });
return sum; return sum;
} }
std::string Seller::sumAsString() { return formatCentAsEuroString(sumInCents()); } std::string Seller::sumAsString() { return formatCentAsEuroString(sumInCents()); }
bool operator<(const Seller &li, const Seller &re) { return li.m_id < re.m_id; } bool operator<(const Seller& li, const Seller& re) { return li.id_ < re.id_; }
bool operator<(const std::unique_ptr<Seller>& li, const std::unique_ptr<Seller>& re) bool operator<(const std::unique_ptr<Seller>& li, const std::unique_ptr<Seller>& re)
{ {
return li->m_id < re->m_id; return li->id_ < re->id_;
} }

View file

@ -42,10 +42,10 @@ public:
friend bool operator<(const std::unique_ptr<Seller>& li, const std::unique_ptr<Seller>& re); friend bool operator<(const std::unique_ptr<Seller>& li, const std::unique_ptr<Seller>& re);
private: private:
int m_numArticlesOffered{}; int numArticlesOffered_{};
std::string m_firstName{}; std::string firstName_{};
std::string m_lastName{}; std::string lastName_{};
std::vector<std::unique_ptr<Article>> m_articles{}; std::vector<std::unique_ptr<Article>> articles_{};
}; };
#endif #endif

View file

@ -1,23 +1,16 @@
#include "utils.h" #include "utils.h"
#include <algorithm> #include <algorithm>
#include <clocale>
#include <format>
#include <iomanip> #include <iomanip>
#include <numeric> #include <numeric>
#include <iostream>
//using namespace fmt;
std::string formatCentAsEuroString(const int cent, int width) std::string formatCentAsEuroString(const int cent, int width)
{ {
/*std::stringstream currStream; std::stringstream currStream;
try { try {
std::locale myLocale("de_DE.utf8"); std::locale myLocale("de_DE.utf8");
currStream.imbue(myLocale); currStream.imbue(myLocale);
std::cout << ">>> " << fmt::format(myLocale, "{:6.2Lf}", 1.12345) << '\n';
currStream << std::right << std::setw(width) << std::showbase currStream << std::right << std::setw(width) << std::showbase
<< std::put_money(cent, false); << std::put_money(cent, false);
} catch (std::runtime_error& err) { } catch (std::runtime_error& err) {
@ -25,14 +18,32 @@ std::string formatCentAsEuroString(const int cent, int width)
<< std::setprecision(2) << cent / 100.0L << ""; << std::setprecision(2) << cent / 100.0L << "";
} }
return currStream.str();*/ return currStream.str();
}
#if defined(_WIN64) || defined(_WIN32) std::optional<PrinterDevice> convertToPosPrinterDevice(const std::string& device,
std::locale myLocale; const std::string& endpoint)
#else {
std::locale myLocale{"de_DE.utf8"}; if (device.empty()) {
#endif return std::nullopt;
return std::format(myLocale, "{:{}.2Lf} €", cent / 100.0L, width); }
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;
} }
std::string& ltrim(std::string& str, const std::string& chars) std::string& ltrim(std::string& str, const std::string& chars)
@ -61,10 +72,3 @@ bool case_insensitive_match(std::string s1, std::string s2)
return true; // The strings are same return true; // The strings are same
return false; // not matched 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

@ -1,15 +1,18 @@
#ifndef CORE_UTILS_H #ifndef UTILS_H
#define CORE_UTILS_H #define UTILS_H
#include "posprinter.h"
#include <locale> #include <locale>
#include <optional> #include <optional>
#include <string> #include <string>
std::string formatCentAsEuroString(const int cent, int width = 6); std::string formatCentAsEuroString(const int cent, int width = 10);
std::optional<PrinterDevice> convertToPosPrinterDevice(const std::string& vendor,
const std::string& endpoint);
std::string& ltrim(std::string& str, const std::string& chars = "\t\n\v\f\r "); 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& 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 "); 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 case_insensitive_match(std::string s1, std::string s2);
bool isNumber(const std::string &str);
#endif #endif

View file

@ -8,12 +8,11 @@ set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
# Find the QtWidgets library # Find the QtWidgets library
find_package(Qt6 COMPONENTS Widgets Network PrintSupport CONFIG REQUIRED) find_package(Qt5Widgets CONFIG REQUIRED)
#find_package(Qt5Widgets CONFIG REQUIRED) find_package(Qt5PrintSupport CONFIG REQUIRED)
#find_package(Qt5PrintSupport CONFIG REQUIRED)
# For SingleApplication: # For SingleApplication:
#find_package(Qt5Network CONFIG REQUIRED) find_package(Qt5Network CONFIG REQUIRED)
set(QAPPLICATION_CLASS QApplication) set(QAPPLICATION_CLASS QApplication)
add_compile_definitions(QAPPLICATION_CLASS=${QAPPLICATION_CLASS}) add_compile_definitions(QAPPLICATION_CLASS=${QAPPLICATION_CLASS})
@ -34,16 +33,14 @@ set(GUI_SOURCES
settingsdialog.cpp settingsdialog.cpp
settingsdialog.ui settingsdialog.ui
../../kima2.qrc ../../kima2.qrc
${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git/singleapplication.cpp ${PROJECT_SOURCE_DIR}/3rdparty/singleapplication/singleapplication.cpp
${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git/singleapplication_p.cpp ${PROJECT_SOURCE_DIR}/3rdparty/singleapplication/singleapplication_p.cpp
) )
add_executable(kima2 ${GUI_SOURCES} kima2.rc) add_executable(kima2 ${GUI_SOURCES} kima2.rc)
target_include_directories(kima2 PRIVATE ${PROJECT_BINARY_DIR}) target_include_directories(kima2 PRIVATE ${PROJECT_BINARY_DIR})
target_include_directories(kima2 PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git) target_include_directories(kima2 PRIVATE ${PROJECT_SOURCE_DIR}/3rdparty/singleapplication)
# target_link_libraries(kima2 core printer Qt5::Widgets Qt5::PrintSupport Qt5::Network stdc++fs) 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)
if(WIN32) if(WIN32)
set_target_properties(kima2 PROPERTIES LINK_FLAGS "-mwindows") set_target_properties(kima2 PROPERTIES LINK_FLAGS "-mwindows")
endif(WIN32) endif(WIN32)

View file

@ -5,13 +5,13 @@
#include <QSettings> #include <QSettings>
BasketModel::BasketModel(Marketplace* market, QObject* parent) BasketModel::BasketModel(Marketplace* market, QObject* parent)
: QAbstractTableModel(parent), m_marketplace(market) : QAbstractTableModel(parent), marketplace_(market)
{ {
} }
int BasketModel::rowCount([[maybe_unused]] const QModelIndex& parent) const int BasketModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
{ {
return static_cast<int>(m_marketplace->basketSize()); return static_cast<int>(marketplace_->basketSize());
} }
int BasketModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 4; } int BasketModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 4; }
@ -46,10 +46,10 @@ QVariant BasketModel::data(const QModelIndex& index, int role) const
if (role != Qt::DisplayRole) if (role != Qt::DisplayRole)
return QVariant(); return QVariant();
if (m_marketplace->basketSize() == 0) if (marketplace_->basketSize() == 0)
return QVariant(); return QVariant();
Article* article = m_marketplace->getBasket().at(index.row()).get(); Article* article = marketplace_->getBasket().at(index.row()).get();
switch (index.column()) { switch (index.column()) {
case 0: case 0:
@ -92,45 +92,45 @@ QVariant BasketModel::headerData(int section, Qt::Orientation orientation, int r
void BasketModel::addArticle(Seller* seller, int price, const std::string& desc) void BasketModel::addArticle(Seller* seller, int price, const std::string& desc)
{ {
emit beginInsertRows(QModelIndex(), m_marketplace->getBasket().size(), emit beginInsertRows(QModelIndex(), marketplace_->getBasket().size(),
m_marketplace->getBasket().size()); marketplace_->getBasket().size());
auto article = std::make_unique<Article>(price); auto article = std::make_unique<Article>(price);
article->createUuid(); article->createUuid();
article->setDescription(desc); article->setDescription(desc);
article->setArticleNo(m_marketplace->getNextArticleNo()); article->setArticleNo(marketplace_->getNextArticleNo());
article->setSourceNo(QSettings().value("global/cashPointNo").toInt()); article->setSourceNo(QSettings().value("global/cashPointNo").toInt());
article->setSeller(seller); article->setSeller(seller);
m_marketplace->addArticleToBasket(std::move(article)); marketplace_->addArticleToBasket(std::move(article));
emit endInsertRows(); emit endInsertRows();
} }
void BasketModel::finishSale() void BasketModel::finishSale()
{ {
emit beginRemoveRows(QModelIndex(), 0, m_marketplace->getBasket().size() - 1); emit beginRemoveRows(QModelIndex(), 0, marketplace_->getBasket().size() - 1);
auto sale = std::make_unique<Sale>(); auto sale = std::make_unique<Sale>();
sale->createUuid(); sale->createUuid();
sale->setSourceNo(QSettings().value("global/cashPointNo").toInt()); sale->setSourceNo(QSettings().value("global/cashPointNo").toInt());
m_marketplace->finishCurrentSale(std::move(sale)); marketplace_->finishCurrentSale(std::move(sale));
emit endRemoveRows(); emit endRemoveRows();
emit basketDataChanged(); emit basketDataChanged();
} }
void BasketModel::cancelSale() void BasketModel::cancelSale()
{ {
emit beginRemoveRows(QModelIndex(), 0, m_marketplace->getBasket().size() - 1); emit beginRemoveRows(QModelIndex(), 0, marketplace_->getBasket().size() - 1);
m_marketplace->getBasket().clear(); marketplace_->getBasket().clear();
emit endRemoveRows(); emit endRemoveRows();
} }
bool BasketModel::removeRows(int row, int count, const QModelIndex& parent) bool BasketModel::removeRows(int row, int count, const QModelIndex& parent)
{ {
auto article = m_marketplace->getBasket().at(row).get(); auto article = marketplace_->getBasket().at(row).get();
emit beginRemoveRows(parent, row, row + count - 1); emit beginRemoveRows(parent, row, row + count - 1);
m_marketplace->getBasket().erase( marketplace_->getBasket().erase(
std::remove_if(m_marketplace->getBasket().begin(), m_marketplace->getBasket().end(), std::remove_if(marketplace_->getBasket().begin(), marketplace_->getBasket().end(),
[&article](const auto& a) { return a->getUuid() == article->getUuid(); }), [&article](const auto& a) { return a->getUuid() == article->getUuid(); }),
m_marketplace->getBasket().end()); marketplace_->getBasket().end());
emit endRemoveRows(); emit endRemoveRows();
return true; return true;
} }

View file

@ -1,7 +1,7 @@
#ifndef BASKET_MODEL_H #ifndef BASKET_MODEL_H
#define BASKET_MODEL_H #define BASKET_MODEL_H
#include <core/marketplace.h> #include <marketplace.h>
#include <QAbstractTableModel> #include <QAbstractTableModel>
@ -24,7 +24,7 @@ class BasketModel : public QAbstractTableModel
void basketDataChanged(); void basketDataChanged();
private: private:
Marketplace* m_marketplace; Marketplace* marketplace_;
}; };
#endif #endif

View file

@ -7,26 +7,28 @@
#include <QMessageBox> #include <QMessageBox>
#include <QSettings> #include <QSettings>
#include <QSharedMemory> #include <QSharedMemory>
#include <QStyleFactory>
#include <QTranslator> #include <QTranslator>
#include <singleapplication.h> #include <singleapplication.h>
#include <stdexcept>
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
SingleApplication kimaApp(argc, argv, false, SingleApplication::Mode::User | SingleApplication::ExcludeAppPath | SingleApplication::ExcludeAppVersion); SingleApplication kimaApp(argc, argv);
// QCoreApplication::setOrganizationName("RustySoft"); // QCoreApplication::setOrganizationName("RustySoft");
QCoreApplication::setOrganizationDomain("rustysoft.de"); QCoreApplication::setOrganizationDomain("rustysoft.de");
QCoreApplication::setApplicationName("kima2"); QCoreApplication::setApplicationName("kima2");
QTranslator qtTranslator; QTranslator qTranslator;
QLocale german(QLocale::German);
if (qtTranslator.load(QLocale::system(), u"qtbase"_qs, u"_"_qs, #ifdef __linux__
QLibraryInfo::path(QLibraryInfo::TranslationsPath))) { qTranslator.load("qt_" + german.name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
kimaApp.installTranslator(&qtTranslator); #endif
} #ifdef _WIN32
qTranslator.load("qt_" + german.name(),
QApplication::applicationDirPath() + QDir::separator() + "translations");
#endif
kimaApp.installTranslator(&qTranslator);
QSettings settings{}; QSettings settings{};
while (!settings.contains("global/cashPointNo")) { while (!settings.contains("global/cashPointNo")) {

View file

@ -1,18 +1,19 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "basketmodel.h" #include "basketmodel.h"
#include "config.h"
#include "jsonutil.h"
#include "pricedialog.h" #include "pricedialog.h"
#include "reportdialog.h" #include "reportdialog.h"
#include "salemodel.h" #include "salemodel.h"
#include "sellerdialog.h" #include "sellerdialog.h"
#include "settingsdialog.h" #include "settingsdialog.h"
#include <config.h>
#include <core/csvreader.h> #include <utils.h>
#include <core/jsonutil.h>
#include <core/utils.h> #include <csvreader.h>
#include <printer/posprinter.h> #include <excelreader.h>
#include <printer/utils.h> #include <posprinter.h>
#include <exception> #include <exception>
#include <filesystem> #include <filesystem>
@ -31,10 +32,10 @@ constexpr int STATUSBAR_TIMEOUT = 5000;
MainWindow::MainWindow() MainWindow::MainWindow()
{ {
m_ui.setupUi(this); ui_.setupUi(this);
m_marketplace = std::make_unique<Marketplace>(); marketplace_ = std::make_unique<Marketplace>();
Database::InitResult res = m_marketplace->loadFromDb(); Database::InitResult res = marketplace_->loadFromDb();
if (res == Database::InitResult::OUTDATED_REPLACED) { if (res == Database::InitResult::OUTDATED_REPLACED) {
QMessageBox(QMessageBox::Icon::Information, "Datenbankinformation", QMessageBox(QMessageBox::Icon::Information, "Datenbankinformation",
"Es wurde eine <b>veraltete</b> Datenbankdatei erkannt.<br />Diese wurde " "Es wurde eine <b>veraltete</b> Datenbankdatei erkannt.<br />Diese wurde "
@ -43,19 +44,19 @@ MainWindow::MainWindow()
} }
statusBar()->showMessage("Gespeicherte Daten wurden geladen.", STATUSBAR_TIMEOUT); statusBar()->showMessage("Gespeicherte Daten wurden geladen.", STATUSBAR_TIMEOUT);
BasketModel *model = new BasketModel(getMarketplace(), m_ui.basketView); BasketModel* model = new BasketModel(getMarketplace(), ui_.basketView);
m_ui.basketView->setModel(model); ui_.basketView->setModel(model);
m_ui.basketView->setColumnHidden(0, true); // hide the uuid ui_.basketView->setColumnHidden(0, true); // hide the uuid
setWindowTitle("KIMA2 - Kasse Nr. " + QSettings().value("global/cashPointNo").toString()); setWindowTitle("KIMA2 - Kasse Nr. " + QSettings().value("global/cashPointNo").toString());
m_ui.salesView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); ui_.salesView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
setSaleModel(); setSaleModel();
connect(m_ui.actionQuit, &QAction::triggered, qApp, QApplication::closeAllWindows, connect(ui_.actionQuit, &QAction::triggered, qApp, QApplication::closeAllWindows,
Qt::QueuedConnection); Qt::QueuedConnection);
connect(m_ui.newAction, &QAction::triggered, this, [this]() { connect(ui_.newAction, &QAction::triggered, this, [=]() {
if (m_marketplace->getSellers().size() == 0 && m_marketplace->getSales().size() == 0) { if (marketplace_->getSellers().size() == 0 && marketplace_->getSales().size() == 0) {
return; return;
} }
auto dlgResult = auto dlgResult =
@ -67,45 +68,46 @@ MainWindow::MainWindow()
if (dlgResult == QMessageBox::No) if (dlgResult == QMessageBox::No)
return; return;
delete m_ui.salesView->model(); delete ui_.salesView->model();
dynamic_cast<BasketModel *>(m_ui.basketView->model())->cancelSale(); dynamic_cast<BasketModel*>(ui_.basketView->model())->cancelSale();
m_marketplace->clear(); marketplace_->clear();
setSaleModel(); setSaleModel();
updateStatLabel(); updateStatLabel();
}); });
m_ui.sellerNoEdit->installEventFilter(this); ui_.sellerNoEdit->installEventFilter(this);
m_ui.givenSpinBox->installEventFilter(this); ui_.givenSpinBox->installEventFilter(this);
connect(m_ui.actionEditSeller, &QAction::triggered, this, connect(ui_.actionEditSeller, &QAction::triggered, this,
&MainWindow::onActionEditSellerTriggered); &MainWindow::onActionEditSellerTriggered);
connect(m_ui.paidButton, &QPushButton::clicked, this, &MainWindow::onPaidButtonTriggered); connect(ui_.paidButton, &QPushButton::clicked, this, &MainWindow::onPaidButtonTriggered);
connect(m_ui.givenSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, connect(ui_.givenSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
&MainWindow::onGivenSpinBoxValueChanged); &MainWindow::onGivenSpinBoxValueChanged);
connect(m_ui.basketView->selectionModel(), &QItemSelectionModel::selectionChanged, this, connect(ui_.basketView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
&MainWindow::onBasketViewSelectionChanged); &MainWindow::onBasketViewSelectionChanged);
connect(m_ui.cancelArticleButton, &QPushButton::clicked, this, connect(ui_.cancelArticleButton, &QPushButton::clicked, this,
&MainWindow::onCancelArticleButtonClicked); &MainWindow::onCancelArticleButtonClicked);
connect(m_ui.cancelSaleButton, &QPushButton::clicked, this, connect(ui_.cancelSaleButton, &QPushButton::clicked, this,
&MainWindow::onCancelSaleButtonClicked); &MainWindow::onCancelSaleButtonClicked);
connect(m_ui.printSaleReceiptButton, &QPushButton::clicked, this, connect(ui_.printSaleReceiptButton, &QPushButton::clicked, this,
&MainWindow::onPrintSaleReceiptButtonClicked); &MainWindow::onPrintSaleReceiptButtonClicked);
connect(m_ui.cancelAllArticlesButton, &QPushButton::clicked, this, connect(ui_.cancelAllArticlesButton, &QPushButton::clicked, this,
&MainWindow::onCancelAllArticlesButtonClicked); &MainWindow::onCancelAllArticlesButtonClicked);
connect(m_ui.aboutQtAction, &QAction::triggered, this, &MainWindow::onAboutQt); connect(ui_.aboutQtAction, &QAction::triggered, this, &MainWindow::onAboutQt);
connect(m_ui.aboutAction, &QAction::triggered, this, &MainWindow::onAbout); connect(ui_.aboutAction, &QAction::triggered, this, &MainWindow::onAbout);
connect(m_ui.openManualAction, &QAction::triggered, this, []() { connect(ui_.openManualAction, &QAction::triggered, this, []() {
auto locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); auto locations = QStandardPaths::standardLocations(QStandardPaths::DataLocation);
for (auto location : locations) { for (auto location : locations) {
if (QFile::exists(location + QString("/Benutzerhandbuch.pdf"))) { if (QFile::exists(location + QString("/Benutzerhandbuch.pdf"))) {
QDesktopServices::openUrl( QDesktopServices::openUrl(
QUrl::fromLocalFile(location + QString("/Benutzerhandbuch.pdf"))); QUrl(QString("file:///") + location + QString("/Benutzerhandbuch.pdf"),
QUrl::TolerantMode));
} }
} }
}); });
connect(m_ui.licenseAction, &QAction::triggered, this, [this]() { connect(ui_.licenseAction, &QAction::triggered, this, [=]() {
QString licenseText( QString licenseText(
"Copyright © 2018-2024 Martin Brodbeck\n\n" "Copyright © 2018-2019 Martin Brodbeck\n\n"
"Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der " "Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der "
"zugehörigen Dokumentationen (die \"Software\") erhält, die Erlaubnis erteilt, " "zugehörigen Dokumentationen (die \"Software\") erhält, die Erlaubnis erteilt, "
"sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, " "sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, "
@ -124,30 +126,34 @@ MainWindow::MainWindow()
"SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN."); "SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN.");
QMessageBox::information(this, "Lizenzinformation", licenseText); QMessageBox::information(this, "Lizenzinformation", licenseText);
}); });
connect(m_ui.reportAction, &QAction::triggered, this, [this]() { ReportDialog(this).exec(); }); connect(ui_.reportAction, &QAction::triggered, this, [=]() { ReportDialog(this).exec(); });
connect(m_ui.configAction, &QAction::triggered, this, [this]() { connect(ui_.configAction, &QAction::triggered, this, [=]() {
int result = SettingsDialog(this).exec(); int result = SettingsDialog(this).exec();
if (result == QDialog::Accepted) { if (result == QDialog::Accepted) {
delete m_ui.salesView->model(); delete ui_.salesView->model();
m_marketplace->loadFromDb(); marketplace_->loadFromDb();
setSaleModel(); setSaleModel();
} }
this->setWindowTitle("KIMA2 - Kasse Nr. " + this->setWindowTitle("KIMA2 - Kasse Nr. " +
QSettings().value("global/cashPointNo").toString()); QSettings().value("global/cashPointNo").toString());
}); });
connect(m_ui.importSellerAction, &QAction::triggered, this, connect(ui_.importSellerExcelAction, &QAction::triggered, this,
&MainWindow::onImportSellerActionTriggered); &MainWindow::onImportSellerExcelActionTriggered);
connect(m_ui.exportSalesJsonAction, &QAction::triggered, this, connect(ui_.importSellerJsonAction, &QAction::triggered, this,
&MainWindow::onImportSellerJsonActionTriggered);
connect(ui_.exportSellerJsonAction, &QAction::triggered, this,
&MainWindow::onExportSellerJsonActionTriggered);
connect(ui_.exportSalesJsonAction, &QAction::triggered, this,
&MainWindow::onExportSalesJsonActionTriggered); &MainWindow::onExportSalesJsonActionTriggered);
connect(m_ui.importSalesJsonAction, &QAction::triggered, this, connect(ui_.importSalesJsonAction, &QAction::triggered, this,
&MainWindow::onImportSalesJsonActionTriggered); &MainWindow::onImportSalesJsonActionTriggered);
readGeometry(); readGeometry();
setWindowIcon(QIcon(":/misc/kima2.ico")); setWindowIcon(QIcon(":/misc/kima2.ico"));
updateStatLabel(); updateStatLabel();
m_ui.lastPriceLabel1->setText(formatCentAsEuroString(0).c_str()); ui_.lastPriceLabel1->setText(formatCentAsEuroString(0).c_str());
m_ui.lastPriceLabel2->setText(formatCentAsEuroString(0).c_str()); ui_.lastPriceLabel2->setText(formatCentAsEuroString(0).c_str());
} }
void MainWindow::onActionEditSellerTriggered() void MainWindow::onActionEditSellerTriggered()
@ -155,11 +161,11 @@ void MainWindow::onActionEditSellerTriggered()
auto dialog = std::make_unique<SellerDialog>(this); auto dialog = std::make_unique<SellerDialog>(this);
int retCode = dialog->exec(); int retCode = dialog->exec();
delete m_ui.salesView->model(); delete ui_.salesView->model();
if (retCode == QDialog::Accepted) { if (retCode == QDialog::Accepted) {
m_marketplace->sortSellers(); marketplace_->sortSellers();
m_marketplace->storeToDb(); marketplace_->storeToDb();
statusBar()->showMessage("Änderungen an den Verkäufer-Stammdaten gespeichert.", statusBar()->showMessage("Änderungen an den Verkäufer-Stammdaten gespeichert.",
STATUSBAR_TIMEOUT); STATUSBAR_TIMEOUT);
} else { } else {
@ -173,32 +179,32 @@ void MainWindow::onActionEditSellerTriggered()
void MainWindow::setSaleModel() void MainWindow::setSaleModel()
{ {
m_ui.salesView->setModel(new SaleModel(getMarketplace(), m_ui.salesView)); ui_.salesView->setModel(new SaleModel(getMarketplace(), ui_.salesView));
m_ui.salesView->setColumnHidden(2, true); ui_.salesView->setColumnHidden(2, true);
m_ui.salesView->resizeColumnToContents(0); ui_.salesView->resizeColumnToContents(0);
m_ui.salesView->resizeColumnToContents(1); ui_.salesView->resizeColumnToContents(1);
m_ui.printSaleReceiptButton->setEnabled(false); ui_.printSaleReceiptButton->setEnabled(false);
m_ui.cancelSaleButton->setEnabled(false); ui_.cancelSaleButton->setEnabled(false);
connect(static_cast<BasketModel *>(m_ui.basketView->model()), &BasketModel::basketDataChanged, connect(static_cast<BasketModel*>(ui_.basketView->model()), &BasketModel::basketDataChanged,
static_cast<SaleModel *>(m_ui.salesView->model()), &SaleModel::onBasketDataChanged); static_cast<SaleModel*>(ui_.salesView->model()), &SaleModel::onBasketDataChanged);
connect(m_ui.salesView->selectionModel(), &QItemSelectionModel::selectionChanged, this, connect(ui_.salesView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
&MainWindow::onSalesViewSelectionChanged); &MainWindow::onSalesViewSelectionChanged);
} }
void MainWindow::onPaidButtonTriggered() void MainWindow::onPaidButtonTriggered()
{ {
if (m_marketplace->basketSize() > 0) { if (marketplace_->basketSize() > 0) {
QString lastPrice{m_marketplace->getBasketSumAsString().c_str()}; QString lastPrice{marketplace_->getBasketSumAsString().c_str()};
dynamic_cast<BasketModel *>(m_ui.basketView->model())->finishSale(); dynamic_cast<BasketModel*>(ui_.basketView->model())->finishSale();
m_ui.salesView->resizeColumnToContents(0); ui_.salesView->resizeColumnToContents(0);
m_ui.lastPriceLabel1->setText(lastPrice); ui_.lastPriceLabel1->setText(lastPrice);
m_ui.lastPriceLabel2->setText(lastPrice); ui_.lastPriceLabel2->setText(lastPrice);
m_ui.basketSumLabel->setText(formatCentAsEuroString(0).c_str()); ui_.basketSumLabel->setText(formatCentAsEuroString(0).c_str());
m_ui.drawbackLabel->setText(formatCentAsEuroString(0).c_str()); ui_.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
m_ui.drawbackContainerWidget->setEnabled(false); ui_.drawbackContainerWidget->setEnabled(false);
m_ui.sellerNoEdit->setFocus(); ui_.sellerNoEdit->setFocus();
statusBar()->showMessage("Verkaufsvorgang erfolgreich durchgeführt.", STATUSBAR_TIMEOUT); statusBar()->showMessage("Verkaufsvorgang erfolgreich durchgeführt.", STATUSBAR_TIMEOUT);
updateStatLabel(); updateStatLabel();
} }
@ -206,7 +212,7 @@ void MainWindow::onPaidButtonTriggered()
bool MainWindow::eventFilter(QObject* target, QEvent* event) bool MainWindow::eventFilter(QObject* target, QEvent* event)
{ {
if (target == m_ui.sellerNoEdit) { if (target == ui_.sellerNoEdit) {
if (event->type() == QEvent::KeyPress) { if (event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) { if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
@ -219,7 +225,7 @@ bool MainWindow::eventFilter(QObject *target, QEvent *event)
return true; return true;
} }
} }
} else if (target == m_ui.givenSpinBox) { } else if (target == ui_.givenSpinBox) {
if (event->type() == QEvent::KeyPress) { if (event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) { if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
@ -228,9 +234,9 @@ bool MainWindow::eventFilter(QObject *target, QEvent *event)
return true; return true;
} }
} else if (keyEvent->key() == Qt::Key::Key_Escape) { } else if (keyEvent->key() == Qt::Key::Key_Escape) {
m_ui.drawbackLabel->setText(formatCentAsEuroString(0).c_str()); ui_.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
m_ui.drawbackContainerWidget->setEnabled(false); ui_.drawbackContainerWidget->setEnabled(false);
m_ui.sellerNoEdit->setFocus(); ui_.sellerNoEdit->setFocus();
} }
} }
} }
@ -241,15 +247,15 @@ void MainWindow::checkSellerNo(bool ctrlPressed)
{ {
using std::regex, std::regex_match, std::smatch; using std::regex, std::regex_match, std::smatch;
auto inputText = m_ui.sellerNoEdit->text().toStdString(); auto inputText = ui_.sellerNoEdit->text().toStdString();
if (inputText.empty()) { if (inputText.empty()) {
if (ctrlPressed == false) { if (ctrlPressed == false) {
onPaidButtonTriggered(); onPaidButtonTriggered();
} else if (m_marketplace->getBasket().size() > 0) { } else if (marketplace_->getBasket().size() > 0) {
m_ui.drawbackContainerWidget->setEnabled(true); ui_.drawbackContainerWidget->setEnabled(true);
m_ui.givenSpinBox->setFocus(); ui_.givenSpinBox->setFocus();
m_ui.givenSpinBox->selectAll(); ui_.givenSpinBox->selectAll();
} }
return; return;
} }
@ -258,13 +264,13 @@ void MainWindow::checkSellerNo(bool ctrlPressed)
smatch result; smatch result;
if (!regex_match(inputText, result, pattern)) { if (!regex_match(inputText, result, pattern)) {
m_ui.sellerNoEdit->clear(); ui_.sellerNoEdit->clear();
return; return;
} }
int sellerNo = std::stoi(result[0]); int sellerNo = std::stoi(result[0]);
auto seller = m_marketplace->findSellerWithSellerNo(sellerNo); auto seller = marketplace_->findSellerWithSellerNo(sellerNo);
if (seller) { if (seller) {
PriceDialog priceDialog(this); PriceDialog priceDialog(this);
if (sellerNo == 0) { if (sellerNo == 0) {
@ -274,30 +280,30 @@ void MainWindow::checkSellerNo(bool ctrlPressed)
if (dialogResult == QDialog::Accepted) { if (dialogResult == QDialog::Accepted) {
int price = priceDialog.getPrice(); int price = priceDialog.getPrice();
std::string desc = priceDialog.getDescription(); std::string desc = priceDialog.getDescription();
dynamic_cast<BasketModel *>(m_ui.basketView->model())->addArticle(seller, price, desc); dynamic_cast<BasketModel*>(ui_.basketView->model())->addArticle(seller, price, desc);
m_ui.basketView->resizeColumnToContents(1); ui_.basketView->resizeColumnToContents(1);
m_ui.basketSumLabel->setText(m_marketplace->getBasketSumAsString().c_str()); ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str());
} }
} }
m_ui.sellerNoEdit->clear(); ui_.sellerNoEdit->clear();
} }
void MainWindow::onGivenSpinBoxValueChanged(double value) void MainWindow::onGivenSpinBoxValueChanged(double value)
{ {
int givenInCent = std::round(value * 100); int givenInCent = std::round(value * 100);
int basketSumInCent = m_marketplace->getBasketSumInCent(); int basketSumInCent = marketplace_->getBasketSumInCent();
int drawback = givenInCent - basketSumInCent; int drawback = givenInCent - basketSumInCent;
m_ui.drawbackLabel->setText(formatCentAsEuroString(drawback).c_str()); ui_.drawbackLabel->setText(formatCentAsEuroString(drawback).c_str());
} }
void MainWindow::onBasketViewSelectionChanged(const QItemSelection& selected, void MainWindow::onBasketViewSelectionChanged(const QItemSelection& selected,
[[maybe_unused]] const QItemSelection& deselected) [[maybe_unused]] const QItemSelection& deselected)
{ {
if (selected.size() > 0) { if (selected.size() > 0) {
m_ui.cancelArticleButton->setEnabled(true); ui_.cancelArticleButton->setEnabled(true);
} else { } else {
m_ui.cancelArticleButton->setEnabled(false); ui_.cancelArticleButton->setEnabled(false);
} }
} }
@ -305,21 +311,21 @@ void MainWindow::onSalesViewSelectionChanged(const QItemSelection &selected,
[[maybe_unused]] const QItemSelection& deselected) [[maybe_unused]] const QItemSelection& deselected)
{ {
if (selected.size() > 0) { if (selected.size() > 0) {
m_ui.cancelSaleButton->setEnabled(true); ui_.cancelSaleButton->setEnabled(true);
if (!selected.indexes()[0].parent().isValid()) if (!selected.indexes()[0].parent().isValid())
m_ui.printSaleReceiptButton->setEnabled(true); ui_.printSaleReceiptButton->setEnabled(true);
else else
m_ui.printSaleReceiptButton->setEnabled(false); ui_.printSaleReceiptButton->setEnabled(false);
} else { } else {
m_ui.cancelSaleButton->setEnabled(false); ui_.cancelSaleButton->setEnabled(false);
m_ui.printSaleReceiptButton->setEnabled(false); ui_.printSaleReceiptButton->setEnabled(false);
} }
} }
void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked) void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
{ {
auto selModel = m_ui.basketView->selectionModel(); auto selModel = ui_.basketView->selectionModel();
if (selModel->hasSelection() == false) if (selModel->hasSelection() == false)
return; return;
@ -336,17 +342,16 @@ void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
// Deleting the rows, beginning with the last one! // Deleting the rows, beginning with the last one!
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) { for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
m_ui.basketView->model()->removeRow(iter->row()); ui_.basketView->model()->removeRow(iter->row());
} }
m_ui.basketSumLabel->setText( ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str()); // Update basket sum
m_marketplace->getBasketSumAsString().c_str()); // Update basket sum ui_.sellerNoEdit->setFocus();
m_ui.sellerNoEdit->setFocus();
} }
void MainWindow::onCancelSaleButtonClicked([[maybe_unused]] bool checked) void MainWindow::onCancelSaleButtonClicked([[maybe_unused]] bool checked)
{ {
auto selModel = m_ui.salesView->selectionModel(); auto selModel = ui_.salesView->selectionModel();
if (selModel->hasSelection() == false) if (selModel->hasSelection() == false)
return; return;
@ -363,25 +368,25 @@ void MainWindow::onCancelSaleButtonClicked([[maybe_unused]] bool checked)
// Deleting the rows, beginning with the last one! // Deleting the rows, beginning with the last one!
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) { for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
m_ui.salesView->model()->removeRow(iter->row(), iter->parent()); ui_.salesView->model()->removeRow(iter->row(), iter->parent());
} }
m_ui.salesView->collapseAll(); ui_.salesView->collapseAll();
QString lastPriceValue(formatCentAsEuroString(0).c_str()); QString lastPriceValue(formatCentAsEuroString(0).c_str());
if (m_ui.salesView->model()->rowCount() > 0) { if (ui_.salesView->model()->rowCount() > 0) {
lastPriceValue = lastPriceValue =
m_ui.salesView->model()->data(m_ui.salesView->model()->index(0, 1)).toString(); ui_.salesView->model()->data(ui_.salesView->model()->index(0, 1)).toString();
} }
m_ui.lastPriceLabel1->setText(lastPriceValue); ui_.lastPriceLabel1->setText(lastPriceValue);
m_ui.lastPriceLabel2->setText(lastPriceValue); ui_.lastPriceLabel2->setText(lastPriceValue);
updateStatLabel(); updateStatLabel();
} }
void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked) void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
{ {
auto selModel = m_ui.salesView->selectionModel(); auto selModel = ui_.salesView->selectionModel();
if (selModel->hasSelection() == false) if (selModel->hasSelection() == false)
return; return;
@ -390,7 +395,7 @@ void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString(); QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString();
auto indexes = selModel->selectedRows(); auto indexes = selModel->selectedRows();
auto &sale = m_marketplace->getSales().at(indexes[0].row()); auto& sale = marketplace_->getSales().at(indexes[0].row());
auto printerDevice = auto printerDevice =
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString()); convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
@ -410,7 +415,7 @@ void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked) void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked)
{ {
if (m_ui.basketView->model()->rowCount() == 0) if (ui_.basketView->model()->rowCount() == 0)
return; return;
auto dlgResult = auto dlgResult =
@ -421,11 +426,10 @@ void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked)
if (dlgResult == QMessageBox::No) if (dlgResult == QMessageBox::No)
return; return;
dynamic_cast<BasketModel *>(m_ui.basketView->model())->cancelSale(); dynamic_cast<BasketModel*>(ui_.basketView->model())->cancelSale();
m_ui.basketSumLabel->setText( ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str()); // Update basket sum
m_marketplace->getBasketSumAsString().c_str()); // Update basket sum ui_.sellerNoEdit->setFocus();
m_ui.sellerNoEdit->setFocus();
} }
void MainWindow::onAboutQt() { QMessageBox::aboutQt(this); } void MainWindow::onAboutQt() { QMessageBox::aboutQt(this); }
@ -441,9 +445,9 @@ void MainWindow::onAbout()
">info@rustysoft.de</a>&gt;</p>"); ">info@rustysoft.de</a>&gt;</p>");
} }
void MainWindow::onImportSellerActionTriggered() void MainWindow::onImportSellerExcelActionTriggered()
{ {
if (!m_marketplace->getSales().empty()) { if (!marketplace_->getSales().empty()) {
QMessageBox(QMessageBox::Icon::Information, "Import nicht möglich", QMessageBox(QMessageBox::Icon::Information, "Import nicht möglich",
"Der Import ist nicht möglich, da schon Verkäufe getätigt wurden.", "Der Import ist nicht möglich, da schon Verkäufe getätigt wurden.",
QMessageBox::StandardButton::Ok, this) QMessageBox::StandardButton::Ok, this)
@ -451,9 +455,9 @@ void MainWindow::onImportSellerActionTriggered()
return; return;
} }
auto filename = auto filename = QFileDialog::getOpenFileName(
QFileDialog::getOpenFileName(this, "Verkäufer importieren", QString(), this, "Verkäufer importieren", QString(),
"Alle unterstützte Dateien (*.csv);;CSV Dateien (*.csv)"); "Alle unterstützte Dateien (*.xlsx *.csv);;Excel Dateien (*.xlsx);;CSV Dateien (*.csv)");
if (filename.isEmpty()) if (filename.isEmpty())
return; return;
@ -465,19 +469,76 @@ void MainWindow::onImportSellerActionTriggered()
#endif #endif
std::size_t numImported{}; std::size_t numImported{};
numImported = CsvReader::readSellersFromFile(filePath, m_marketplace.get()); if (case_insensitive_match(filePath.extension().string(), std::string(".xlsx"))) {
numImported = ExcelReader::readSellersFromFile(filePath, marketplace_.get());
} else {
numImported = CsvReader::readSellersFromFile(filePath, marketplace_.get());
}
updateStatLabel(); updateStatLabel();
using namespace std::string_literals; using namespace std::string_literals;
std::ostringstream msg; std::ostringstream msg;
msg << "Aus der CSV-Datei wurden <b>"s << std::to_string(numImported) msg << "Aus der Excel/CSV-Datei wurden <b>"s << std::to_string(numImported)
<< "</b> Verkäufer importiert."; << "</b> Verkäufer importiert.";
QMessageBox(QMessageBox::Icon::Information, "Verkäufer erfolgreich importiert", QMessageBox(QMessageBox::Icon::Information, "Verkäufer erfolgreich importiert",
msg.str().c_str(), QMessageBox::StandardButton::Ok, this) msg.str().c_str(), QMessageBox::StandardButton::Ok, this)
.exec(); .exec();
} }
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)
.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, 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, marketplace_.get());
}
void MainWindow::onExportSalesJsonActionTriggered() void MainWindow::onExportSalesJsonActionTriggered()
{ {
QSettings settings; QSettings settings;
@ -496,7 +557,7 @@ void MainWindow::onExportSalesJsonActionTriggered()
fs::path filePath(filename.toStdString()); fs::path filePath(filename.toStdString());
#endif #endif
JsonUtil::exportSales(filePath, m_marketplace.get(), JsonUtil::exportSales(filePath, marketplace_.get(),
settings.value("global/cashPointNo").toInt()); settings.value("global/cashPointNo").toInt());
} }
@ -504,30 +565,27 @@ void MainWindow::onImportSalesJsonActionTriggered()
{ {
QSettings settings; QSettings settings;
auto filenames = QFileDialog::getOpenFileNames(this, "Umsätze/Transaktionen importieren", auto filename = QFileDialog::getOpenFileName(this, "Umsätze/Transaktionen importieren",
QString(), "JSON Dateien (*.json)"); QString(), "JSON Dateien (*.json)");
if (filenames.isEmpty()) if (filename.isEmpty())
return; return;
for(auto filename: filenames) {
#if defined(_WIN64) || defined(_WIN32) #if defined(_WIN64) || defined(_WIN32)
fs::path filePath(filename.toStdWString()); fs::path filePath(filename.toStdWString());
#else #else
fs::path filePath(filename.toStdString()); fs::path filePath(filename.toStdString());
#endif #endif
delete m_ui.salesView->model(); delete ui_.salesView->model();
try { try {
JsonUtil::importSales(filePath, m_marketplace.get(), JsonUtil::importSales(filePath, marketplace_.get(),
settings.value("global/cashPointNo").toInt()); settings.value("global/cashPointNo").toInt());
} catch (std::runtime_error& err) { } catch (std::runtime_error& err) {
QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok, QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok,
this) this)
.exec(); .exec();
} }
}
setSaleModel(); setSaleModel();
updateStatLabel(); updateStatLabel();
} }
@ -562,9 +620,9 @@ void MainWindow::updateStatLabel()
{ {
std::string statistics("<b>KIMA2 - Version "); std::string statistics("<b>KIMA2 - Version ");
statistics += PROJECT_VERSION; statistics += PROJECT_VERSION;
statistics += "</b><br />Verkäufer: " + std::to_string(m_marketplace->getSellers().size() - 1); statistics += "</b><br />Verkäufer: " + std::to_string(marketplace_->getSellers().size() - 1);
statistics += "<br />Kunden: " + std::to_string(m_marketplace->getSales().size()); statistics += "<br />Kunden: " + std::to_string(marketplace_->getSales().size());
statistics += "<br />Umsatz: " + m_marketplace->getOverallSumAsString(); statistics += "<br />Umsatz: " + marketplace_->getOverallSumAsString();
m_ui.statLabel->setText(statistics.c_str()); ui_.statLabel->setText(statistics.c_str());
} }

View file

@ -3,7 +3,7 @@
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include <core/marketplace.h> #include <marketplace.h>
#include <QMainWindow> #include <QMainWindow>
#include <QtGui/QCloseEvent> #include <QtGui/QCloseEvent>
@ -16,7 +16,7 @@ class MainWindow : public QMainWindow
public: public:
MainWindow(); MainWindow();
Marketplace* getMarketplace() { return m_marketplace.get(); } Marketplace* getMarketplace() { return marketplace_.get(); }
private slots: private slots:
void onBasketViewSelectionChanged(const QItemSelection& selected, void onBasketViewSelectionChanged(const QItemSelection& selected,
@ -39,7 +39,9 @@ class MainWindow : public QMainWindow
void checkSellerNo(bool ctrlPressed = false); void checkSellerNo(bool ctrlPressed = false);
void onPaidButtonTriggered(); void onPaidButtonTriggered();
void onGivenSpinBoxValueChanged(double value); void onGivenSpinBoxValueChanged(double value);
void onImportSellerActionTriggered(); void onImportSellerExcelActionTriggered();
void onImportSellerJsonActionTriggered();
void onExportSellerJsonActionTriggered();
void onExportSalesJsonActionTriggered(); void onExportSalesJsonActionTriggered();
void onImportSalesJsonActionTriggered(); void onImportSalesJsonActionTriggered();
void setSaleModel(); void setSaleModel();
@ -47,8 +49,8 @@ class MainWindow : public QMainWindow
void readGeometry(); void readGeometry();
void updateStatLabel(); void updateStatLabel();
Ui::MainWindow m_ui; Ui::MainWindow ui_;
std::unique_ptr<Marketplace> m_marketplace; std::unique_ptr<Marketplace> marketplace_;
}; };
#endif #endif

View file

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

View file

@ -1,23 +0,0 @@
qt5 = import('qt5')
qt5_dep = dependency('qt5', modules: ['Core', 'Gui', 'PrintSupport', 'Network'])
thread_dep = dependency('threads')
src = ['kima2.cpp', 'mainwindow.cpp', 'sellerdialog.cpp', 'sellermodel.cpp',
'pricedialog.cpp', 'basketmodel.cpp', 'salemodel.cpp', 'reportdialog.cpp',
'reportmodel.cpp', 'settingsdialog.cpp']
ui = ['mainwindow.ui', 'sellerdialog.ui', 'pricedialog.ui', 'reportdialog.ui', 'settingsdialog.ui']
processed = qt5.preprocess(moc_headers : ['basketmodel.h', 'mainwindow.h', 'pricedialog.h',
'reportdialog.h', 'sellerdialog.h', 'settingsdialog.h',
'sellermodel.h', 'salemodel.h'],
ui_files : ui,
qresources : '../../kima2.qrc',
dependencies: qt5_dep)
kima2 = executable('kima2', sources : [src, processed],
dependencies : [qt5_dep, singleapp_dep, core_dep, printer_dep, thread_dep],
include_directories : [configuration_inc],
install : true)

View file

@ -6,31 +6,31 @@
PriceDialog::PriceDialog(QWidget* parent, bool forceDesc, Qt::WindowFlags f) : QDialog(parent, f) PriceDialog::PriceDialog(QWidget* parent, bool forceDesc, Qt::WindowFlags f) : QDialog(parent, f)
{ {
m_forceDesc = forceDesc; forceDesc_ = forceDesc;
m_ui.setupUi(this); ui_.setupUi(this);
m_ui.priceSpinBox->setFocus(); ui_.priceSpinBox->setFocus();
} }
int PriceDialog::getPrice() const { return static_cast<int>(m_ui.priceSpinBox->value() * 100); } int PriceDialog::getPrice() const { return static_cast<int>(ui_.priceSpinBox->value() * 100); }
std::string PriceDialog::getDescription() const { return m_ui.descEdit->text().toStdString(); } std::string PriceDialog::getDescription() const { return ui_.descEdit->text().toStdString(); }
void PriceDialog::accept() void PriceDialog::accept()
{ {
if (static_cast<int>(std::round(m_ui.priceSpinBox->value() * 100.0L)) % 50 != 0) { if (static_cast<int>(std::round(ui_.priceSpinBox->value() * 100.0L)) % 50 != 0) {
QMessageBox(QMessageBox::Icon::Warning, "Falsche Preiseingabe", QMessageBox(QMessageBox::Icon::Warning, "Falsche Preiseingabe",
"Es sind nur 0,50 Cent-Schritte erlaubt.", QMessageBox::StandardButton::Ok, "Es sind nur 0,50 Cent-Schritte erlaubt.", QMessageBox::StandardButton::Ok,
this) this)
.exec(); .exec();
} else if (m_forceDesc && m_ui.descEdit->text().trimmed().isEmpty()) { } else if (forceDesc_ && ui_.descEdit->text().trimmed().isEmpty()) {
QMessageBox(QMessageBox::Icon::Warning, "Artikelbeschreibung fehlt", QMessageBox(QMessageBox::Icon::Warning, "Artikelbeschreibung fehlt",
"Da Sie auf das Sonderkonto buchen ist eine Artikelbeschreibung erforderlich.", "Da Sie auf das Sonderkonto buchen ist eine Artikelbeschreibung erforderlich.",
QMessageBox::StandardButton::Ok, this) QMessageBox::StandardButton::Ok, this)
.exec(); .exec();
m_ui.descEdit->setFocus(); ui_.descEdit->setFocus();
} else { } else {
QDialog::accept(); QDialog::accept();
} }
} }
void PriceDialog::setForceDesc(bool force) { m_forceDesc = force; } void PriceDialog::setForceDesc(bool force) { forceDesc_ = force; }

View file

@ -19,8 +19,8 @@ class PriceDialog : public QDialog
private: private:
void on_model_duplicateSellerNo(const QString& message); void on_model_duplicateSellerNo(const QString& message);
virtual void accept() override; virtual void accept() override;
Ui::PriceDialog m_ui; Ui::PriceDialog ui_;
bool m_forceDesc; bool forceDesc_;
}; };
#endif #endif

View file

@ -2,9 +2,8 @@
#include "mainwindow.h" #include "mainwindow.h"
#include <core/utils.h> #include <posprinter.h>
#include <printer/posprinter.h> #include <utils.h>
#include <printer/utils.h>
#include <filesystem> #include <filesystem>
@ -19,20 +18,20 @@ namespace fs = std::filesystem;
ReportDialog::ReportDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) ReportDialog::ReportDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f)
{ {
m_ui.setupUi(this); ui_.setupUi(this);
m_market = dynamic_cast<MainWindow *>(parent)->getMarketplace(); market_ = dynamic_cast<MainWindow*>(parent)->getMarketplace();
m_model = std::make_unique<ReportModel>(m_market, m_ui.reportView); model_ = std::make_unique<ReportModel>(market_, ui_.reportView);
m_ui.reportView->setModel(m_model.get()); ui_.reportView->setModel(model_.get());
m_ui.reportView->hideColumn(0); ui_.reportView->hideColumn(0);
m_ui.reportView->setRowHidden(0, true); // hide the special "Sonderkonto" user ui_.reportView->setRowHidden(0, true); // hide the special "Sonderkonto" user
connect(m_ui.exportCsvButton, &QPushButton::clicked, this, connect(ui_.exportCsvButton, &QPushButton::clicked, this,
&ReportDialog::onExportCsvButtonClicked); &ReportDialog::onExportCsvButtonClicked);
connect(m_ui.printReportButton, &QPushButton::clicked, this, connect(ui_.printReportButton, &QPushButton::clicked, this,
&ReportDialog::onPrintReportButtonClicked); &ReportDialog::onPrintReportButtonClicked);
connect(m_ui.printSellerReceiptButton, &QPushButton::clicked, this, connect(ui_.printSellerReceiptButton, &QPushButton::clicked, this,
&ReportDialog::onPrintSellerReceiptButtonClicked); &ReportDialog::onPrintSellerReceiptButtonClicked);
connect(m_ui.reportView->selectionModel(), &QItemSelectionModel::selectionChanged, this, connect(ui_.reportView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
&ReportDialog::onReportViewSelectionChanged); &ReportDialog::onReportViewSelectionChanged);
} }
@ -48,13 +47,9 @@ void ReportDialog::onExportCsvButtonClicked()
if (filename.isEmpty()) if (filename.isEmpty())
return; return;
#if defined(_WIN64) || defined(_WIN32)
fs::path filePath(filename.toStdWString()); fs::path filePath(filename.toStdWString());
#else
fs::path filePath(filename.toStdString());
#endif
m_market->exportReportToCSV(filePath, feeInPercent, maxFeeInEuro); market_->exportReportToCSV(filePath, feeInPercent, maxFeeInEuro);
} }
void ReportDialog::onPrintReportButtonClicked() void ReportDialog::onPrintReportButtonClicked()
@ -75,8 +70,8 @@ void ReportDialog::onPrintReportButtonClicked()
QPainter painter; QPainter painter;
int height = printer.height(); int height = printer.height();
int width = printer.width(); int width = printer.width();
const double ENTRIES_PER_PAGE = 45; const double ENTRIES_PER_PAGE = 51;
const auto &sellers = m_market->getSellers(); const auto& sellers = market_->getSellers();
unsigned int numPages = std::ceil(sellers.size() / ENTRIES_PER_PAGE); unsigned int numPages = std::ceil(sellers.size() / ENTRIES_PER_PAGE);
painter.begin(&printer); painter.begin(&printer);
@ -126,7 +121,7 @@ void ReportDialog::onPrintReportButtonClicked()
} }
// pieces booked on the special account "Sonderkonto" // pieces booked on the special account "Sonderkonto"
const auto specialSeller = m_market->findSellerWithSellerNo(0); const auto specialSeller = market_->findSellerWithSellerNo(0);
if (specialSeller && specialSeller->numArticlesSold() > 0) { if (specialSeller && specialSeller->numArticlesSold() > 0) {
printer.newPage(); printer.newPage();
painter.setFont(QFont("Arial", 16, QFont::Bold)); painter.setFont(QFont("Arial", 16, QFont::Bold));
@ -163,8 +158,8 @@ void ReportDialog::onPrintReportButtonClicked()
"Auswertung Kindersachenmarkt"); "Auswertung Kindersachenmarkt");
painter.setFont(fixedFont); painter.setFont(fixedFont);
QString content("Gesamtstatistik\n===============\n\n"); QString content("Gesamtstatistik\n===============\n\n");
int numArticlesOffered = m_market->getNumArticlesOffered(); int numArticlesOffered = market_->getNumArticlesOffered();
int numArticlesSold = m_market->getNumArticlesSold(); int numArticlesSold = market_->getNumArticlesSold();
double percentArticlesSold = double percentArticlesSold =
(static_cast<double>(numArticlesSold) / static_cast<double>(numArticlesOffered)) * 100; (static_cast<double>(numArticlesSold) / static_cast<double>(numArticlesOffered)) * 100;
content += QString("Registrierte Verkäufer: %1\n").arg(sellers.size() - 1, 6); content += QString("Registrierte Verkäufer: %1\n").arg(sellers.size() - 1, 6);
@ -172,14 +167,14 @@ void ReportDialog::onPrintReportButtonClicked()
content += QString("Verkaufte Artikel: %1 (%L2 %)\n") content += QString("Verkaufte Artikel: %1 (%L2 %)\n")
.arg(numArticlesSold, 6) .arg(numArticlesSold, 6)
.arg(percentArticlesSold, 0, 'f', 2); .arg(percentArticlesSold, 0, 'f', 2);
content += QString("Anzahl Kunden: %1\n\n").arg(m_market->getSales().size(), 6); content += QString("Anzahl Kunden: %1\n\n").arg(market_->getSales().size(), 6);
content += QString("Gesamtumsatz: %1\n").arg(m_market->getOverallSumAsString().c_str(), 10); content += QString("Gesamtumsatz: %1\n").arg(market_->getOverallSumAsString().c_str(), 10);
content += content +=
QString("Ausgezahlt: %1\n") QString("Ausgezahlt: %1\n")
.arg(m_market->getOverallPaymentAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10); .arg(market_->getOverallPaymentAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10);
content += content +=
QString("Verbleibend: %1\n\n") QString("Verbleibend: %1\n\n")
.arg(m_market->getOverallRevenueAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10); .arg(market_->getOverallRevenueAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10);
content += QString("(Einbehaltener Prozentsatz: %1 %)\n").arg(feeInPercent, 3); content += QString("(Einbehaltener Prozentsatz: %1 %)\n").arg(feeInPercent, 3);
content += QString("(Maximal einbehaltener Betrag: %1 €)\n").arg(maxFeeInEuro, 3); content += QString("(Maximal einbehaltener Betrag: %1 €)\n").arg(maxFeeInEuro, 3);
@ -196,12 +191,12 @@ void ReportDialog::onPrintSellerReceiptButtonClicked()
QString posPrinterDevice = settings.value("global/posPrinterDevice", "").toString(); QString posPrinterDevice = settings.value("global/posPrinterDevice", "").toString();
QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString(); QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString();
auto selModel = m_ui.reportView->selectionModel(); auto selModel = ui_.reportView->selectionModel();
if (selModel->hasSelection() == false) if (selModel->hasSelection() == false)
return; return;
auto indexes = selModel->selectedRows(); auto indexes = selModel->selectedRows();
auto &seller = m_market->getSellers().at(indexes[0].row()); auto& seller = market_->getSellers().at(indexes[0].row());
auto printerDevice = auto printerDevice =
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString()); convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
@ -224,8 +219,8 @@ void ReportDialog::onReportViewSelectionChanged(const QItemSelection &selected,
[[maybe_unused]] const QItemSelection& deselected) [[maybe_unused]] const QItemSelection& deselected)
{ {
if (selected.size() > 0) { if (selected.size() > 0) {
m_ui.printSellerReceiptButton->setEnabled(true); ui_.printSellerReceiptButton->setEnabled(true);
} else { } else {
m_ui.printSellerReceiptButton->setEnabled(false); ui_.printSellerReceiptButton->setEnabled(false);
} }
} }

View file

@ -5,7 +5,7 @@
#include "reportmodel.h" #include "reportmodel.h"
#include <core/marketplace.h> #include <marketplace.h>
#include <QDialog> #include <QDialog>
@ -25,9 +25,9 @@ class ReportDialog : public QDialog
const QItemSelection& deselected); const QItemSelection& deselected);
private: private:
Ui::ReportDialog m_ui; Ui::ReportDialog ui_;
Marketplace* m_market; Marketplace* market_;
std::unique_ptr<ReportModel> m_model; std::unique_ptr<ReportModel> model_;
}; };
#endif #endif

View file

@ -5,16 +5,16 @@
#include <QSettings> #include <QSettings>
ReportModel::ReportModel(Marketplace* market, QObject* parent) ReportModel::ReportModel(Marketplace* market, QObject* parent)
: QAbstractTableModel(parent), m_market(market) : QAbstractTableModel(parent), market_(market)
{ {
QSettings settings; QSettings settings;
m_feeInPercent = settings.value("global/feeInPercent").toInt(); feeInPercent_ = settings.value("global/feeInPercent").toInt();
m_maxFeeInCent = settings.value("global/maxFeeInEuro").toInt() * 100; maxFeeInCent_ = settings.value("global/maxFeeInEuro").toInt() * 100;
} }
int ReportModel::rowCount([[maybe_unused]] const QModelIndex& parent) const int ReportModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
{ {
return static_cast<int>(m_market->getSellers().size()); return static_cast<int>(market_->getSellers().size());
} }
int ReportModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 7; } int ReportModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 7; }
@ -52,10 +52,10 @@ QVariant ReportModel::data(const QModelIndex& index, int role) const
if (role != Qt::DisplayRole) if (role != Qt::DisplayRole)
return QVariant(); return QVariant();
if (m_market->getSellers().size() == 0) if (market_->getSellers().size() == 0)
return QVariant(); return QVariant();
Seller* seller = m_market->getSellers().at(index.row()).get(); Seller* seller = market_->getSellers().at(index.row()).get();
switch (index.column()) { switch (index.column()) {
case 0: case 0:
@ -71,7 +71,7 @@ QVariant ReportModel::data(const QModelIndex& index, int role) const
case 5: case 5:
return seller->sumAsString().c_str(); return seller->sumAsString().c_str();
case 6: case 6:
return paymentAsString(seller->sumInCents(), m_feeInPercent, m_maxFeeInCent).c_str(); return paymentAsString(seller->sumInCents(), feeInPercent_, maxFeeInCent_).c_str();
default: default:
return "???"; return "???";
} }

View file

@ -1,7 +1,7 @@
#ifndef REPORT_MODEL_H #ifndef REPORT_MODEL_H
#define REPORT_MODEL_H #define REPORT_MODEL_H
#include <core/marketplace.h> #include <marketplace.h>
#include <QAbstractTableModel> #include <QAbstractTableModel>
@ -15,9 +15,9 @@ class ReportModel : public QAbstractTableModel
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
private: private:
Marketplace* m_market; Marketplace* market_;
int m_feeInPercent{}; int feeInPercent_{};
int m_maxFeeInCent{}; int maxFeeInCent_{};
}; };
#endif #endif

View file

@ -1,6 +1,6 @@
#include "salemodel.h" #include "salemodel.h"
#include <core/article.h> #include <article.h>
#include <algorithm> #include <algorithm>
@ -9,7 +9,7 @@
SaleModel::SaleModel(Marketplace* market, QObject* parent) : QAbstractItemModel(parent) SaleModel::SaleModel(Marketplace* market, QObject* parent) : QAbstractItemModel(parent)
{ {
m_marketplace = market; marketplace_ = market;
} }
QModelIndex SaleModel::index(int row, int column, const QModelIndex& parent) const QModelIndex SaleModel::index(int row, int column, const QModelIndex& parent) const
@ -18,7 +18,7 @@ QModelIndex SaleModel::index(int row, int column, const QModelIndex& parent) con
return QModelIndex(); return QModelIndex();
if (!parent.isValid()) { if (!parent.isValid()) {
Sale* sale = m_marketplace->getSales().at(row).get(); Sale* sale = marketplace_->getSales().at(row).get();
return createIndex(row, column, sale); return createIndex(row, column, sale);
} else if (!parent.parent().isValid()) { } else if (!parent.parent().isValid()) {
Sale* sale = static_cast<Sale*>(parent.internalPointer()); Sale* sale = static_cast<Sale*>(parent.internalPointer());
@ -49,10 +49,10 @@ QModelIndex SaleModel::parent(const QModelIndex& index) const
sale = dynamic_cast<Sale*>(ent); sale = dynamic_cast<Sale*>(ent);
if (sale) { if (sale) {
if (sale == m_rootItem.get()) if (sale == rootItem.get())
return QModelIndex(); return QModelIndex();
else { else {
return createIndex(-1, 0, m_rootItem.get()); return createIndex(-1, 0, rootItem.get());
} }
} else { } else {
article = dynamic_cast<Article*>(ent); article = dynamic_cast<Article*>(ent);
@ -132,7 +132,7 @@ int SaleModel::rowCount(const QModelIndex& parent) const
return 0; return 0;
if (!parent.isValid()) { if (!parent.isValid()) {
return m_marketplace->getSales().size(); return marketplace_->getSales().size();
} else if (!parent.parent().isValid()) { } else if (!parent.parent().isValid()) {
Sale* sale = static_cast<Sale*>(parent.internalPointer()); Sale* sale = static_cast<Sale*>(parent.internalPointer());
return sale->getArticles().size(); return sale->getArticles().size();
@ -167,7 +167,7 @@ QVariant SaleModel::headerData(int section, Qt::Orientation orientation, int rol
void SaleModel::onBasketDataChanged() void SaleModel::onBasketDataChanged()
{ {
emit beginResetModel(); emit beginResetModel();
auto& sales = m_marketplace->getSales(); auto& sales = marketplace_->getSales();
std::sort(sales.begin(), sales.end(), [](const auto& lhs, const auto& rhs) { std::sort(sales.begin(), sales.end(), [](const auto& lhs, const auto& rhs) {
return lhs->getTimestamp() > rhs->getTimestamp(); return lhs->getTimestamp() > rhs->getTimestamp();
}); });
@ -179,11 +179,11 @@ bool SaleModel::removeRows(int row, int count, const QModelIndex& parent)
if (!parent.isValid()) { if (!parent.isValid()) {
// remove complete sale // remove complete sale
emit beginRemoveRows(parent, row, row + count - 1); emit beginRemoveRows(parent, row, row + count - 1);
auto& sale = m_marketplace->getSales().at(row); auto& sale = marketplace_->getSales().at(row);
sale->setState(Sale::State::DELETE); sale->setState(Sale::State::DELETE);
std::for_each(sale->getArticles().begin(), sale->getArticles().end(), std::for_each(sale->getArticles().begin(), sale->getArticles().end(),
[](auto& a) { a->setState(Article::State::DELETE); }); [](auto& a) { a->setState(Article::State::DELETE); });
m_marketplace->storeToDb(); marketplace_->storeToDb();
emit endRemoveRows(); emit endRemoveRows();
} else if (!parent.parent().isValid()) { } else if (!parent.parent().isValid()) {
@ -199,7 +199,7 @@ bool SaleModel::removeRows(int row, int count, const QModelIndex& parent)
sale->setState(Sale::State::DELETE); sale->setState(Sale::State::DELETE);
} }
emit beginRemoveRows(parent.parent(), 0, 0); emit beginRemoveRows(parent.parent(), 0, 0);
m_marketplace->storeToDb(); marketplace_->storeToDb();
emit endRemoveRows(); emit endRemoveRows();
} }

View file

@ -1,7 +1,7 @@
#ifndef SALEMODEL_H #ifndef SALEMODEL_H
#define SALEMODEL_H #define SALEMODEL_H
#include <core/marketplace.h> #include <marketplace.h>
#include <QAbstractItemModel> #include <QAbstractItemModel>
@ -24,8 +24,8 @@ class SaleModel : public QAbstractItemModel
void onBasketDataChanged(); void onBasketDataChanged();
private: private:
Marketplace* m_marketplace; Marketplace* marketplace_;
std::unique_ptr<Sale> m_rootItem{new Sale()}; std::unique_ptr<Sale> rootItem{new Sale()};
}; };
#endif #endif

View file

@ -7,25 +7,25 @@
SellerDialog::SellerDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) SellerDialog::SellerDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f)
{ {
m_ui.setupUi(this); ui_.setupUi(this);
m_ui.editButton->setVisible(false); ui_.editButton->setVisible(false);
m_market = dynamic_cast<MainWindow*>(parent)->getMarketplace(); market_ = dynamic_cast<MainWindow*>(parent)->getMarketplace();
m_model = std::make_unique<SellerModel>(m_market, m_ui.tableView); model_ = std::make_unique<SellerModel>(market_, ui_.tableView);
m_ui.tableView->setModel(m_model.get()); ui_.tableView->setModel(model_.get());
m_ui.tableView->setColumnHidden(0, true); // hide the uuid ui_.tableView->setColumnHidden(0, true); // hide the uuid
m_ui.tableView->setRowHidden(0, true); // hide the special "Sonderkonto" user ui_.tableView->setRowHidden(0, true); // hide the special "Sonderkonto" user
connect(m_ui.newButton, &QPushButton::clicked, this, &SellerDialog::on_newButton_clicked); connect(ui_.newButton, &QPushButton::clicked, this, &SellerDialog::on_newButton_clicked);
connect(m_ui.deleteButton, &QPushButton::clicked, this, &SellerDialog::on_deleteButton_clicked); connect(ui_.deleteButton, &QPushButton::clicked, this, &SellerDialog::on_deleteButton_clicked);
connect(m_model.get(), &SellerModel::duplicateSellerNo, this, connect(model_.get(), &SellerModel::duplicateSellerNo, this,
&SellerDialog::on_model_duplicateSellerNo); &SellerDialog::on_model_duplicateSellerNo);
connect(m_ui.tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, connect(ui_.tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
&SellerDialog::onSellerViewSelectionChanged); &SellerDialog::onSellerViewSelectionChanged);
} }
void SellerDialog::on_newButton_clicked() void SellerDialog::on_newButton_clicked()
{ {
// Don't allow new seller if market has already started // Don't allow new seller if market has already started
if (m_market->getSales().size() > 0) { if (market_->getSales().size() > 0) {
QMessageBox(QMessageBox::Icon::Warning, "Hinweis", QMessageBox(QMessageBox::Icon::Warning, "Hinweis",
"Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) " "Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) "
"können Sie keine Verkäufer mehr hinzufügen.", "können Sie keine Verkäufer mehr hinzufügen.",
@ -34,22 +34,22 @@ void SellerDialog::on_newButton_clicked()
return; return;
} }
m_ui.tableView->reset(); ui_.tableView->reset();
m_ui.tableView->model()->insertRows(m_ui.tableView->model()->rowCount(), 1); ui_.tableView->model()->insertRows(ui_.tableView->model()->rowCount(), 1);
m_ui.tableView->scrollToBottom(); ui_.tableView->scrollToBottom();
m_ui.tableView->selectRow(m_ui.tableView->model()->rowCount() - 1); ui_.tableView->selectRow(ui_.tableView->model()->rowCount() - 1);
QModelIndex idx = m_ui.tableView->model()->index(m_ui.tableView->model()->rowCount() - 1, 2); QModelIndex idx = ui_.tableView->model()->index(ui_.tableView->model()->rowCount() - 1, 2);
m_ui.tableView->setCurrentIndex(idx); ui_.tableView->setCurrentIndex(idx);
m_ui.tableView->edit(idx); ui_.tableView->edit(idx);
} }
void SellerDialog::on_deleteButton_clicked() void SellerDialog::on_deleteButton_clicked()
{ {
auto selModel = m_ui.tableView->selectionModel(); auto selModel = ui_.tableView->selectionModel();
if (selModel->hasSelection() == false) if (selModel->hasSelection() == false)
return; return;
if (m_market->getSales().size() > 0) { if (market_->getSales().size() > 0) {
QMessageBox(QMessageBox::Icon::Warning, "Hinweis", QMessageBox(QMessageBox::Icon::Warning, "Hinweis",
"Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) " "Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) "
"können Sie keine Verkäufer mehr löschen.", "können Sie keine Verkäufer mehr löschen.",
@ -72,7 +72,7 @@ void SellerDialog::on_deleteButton_clicked()
// Deleting the rows, beginning with the last one! // Deleting the rows, beginning with the last one!
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) { for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
m_ui.tableView->model()->removeRow(iter->row()); ui_.tableView->model()->removeRow(iter->row());
} }
} }
@ -102,8 +102,8 @@ void SellerDialog::onSellerViewSelectionChanged(const QItemSelection& selected,
[[maybe_unused]] const QItemSelection& deselected) [[maybe_unused]] const QItemSelection& deselected)
{ {
if (selected.size() > 0) { if (selected.size() > 0) {
m_ui.deleteButton->setEnabled(true); ui_.deleteButton->setEnabled(true);
} else { } else {
m_ui.deleteButton->setEnabled(false); ui_.deleteButton->setEnabled(false);
} }
} }

View file

@ -26,9 +26,9 @@ class SellerDialog : public QDialog
void on_deleteButton_clicked(); void on_deleteButton_clicked();
void on_model_duplicateSellerNo(const QString& message); void on_model_duplicateSellerNo(const QString& message);
virtual void accept() override; virtual void accept() override;
Ui::SellerDialog m_ui; Ui::SellerDialog ui_;
Marketplace* m_market; Marketplace* market_;
std::unique_ptr<SellerModel> m_model; std::unique_ptr<SellerModel> model_;
}; };
#endif #endif

View file

@ -5,13 +5,13 @@
#include <QMessageBox> #include <QMessageBox>
SellerModel::SellerModel(Marketplace* market, QObject* parent) SellerModel::SellerModel(Marketplace* market, QObject* parent)
: QAbstractTableModel(parent), m_marketplace(market) : QAbstractTableModel(parent), marketplace_(market)
{ {
} }
int SellerModel::rowCount([[maybe_unused]] const QModelIndex& parent) const int SellerModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
{ {
return m_marketplace->getSellers().size(); return marketplace_->getSellers().size();
} }
int SellerModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 5; } int SellerModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 5; }
@ -21,10 +21,10 @@ QVariant SellerModel::data(const QModelIndex& index, int role) const
if (role != Qt::DisplayRole) if (role != Qt::DisplayRole)
return QVariant(); return QVariant();
if (m_marketplace->getSellers().size() == 0) if (marketplace_->getSellers().size() == 0)
return QVariant(); return QVariant();
Seller* seller = m_marketplace->getSellers().at(index.row()).get(); Seller* seller = marketplace_->getSellers().at(index.row()).get();
switch (index.column()) { switch (index.column()) {
case 0: case 0:
@ -78,7 +78,7 @@ bool SellerModel::setData(const QModelIndex& index, const QVariant& value, int r
if (role != Qt::EditRole) if (role != Qt::EditRole)
return false; return false;
Seller* seller = m_marketplace->getSellers().at(index.row()).get(); Seller* seller = marketplace_->getSellers().at(index.row()).get();
switch (index.column()) { switch (index.column()) {
case 0: case 0:
@ -88,11 +88,11 @@ bool SellerModel::setData(const QModelIndex& index, const QVariant& value, int r
if (value.toInt() < 0) if (value.toInt() < 0)
return false; return false;
auto iter = auto iter =
std::find_if(m_marketplace->getSellers().begin(), m_marketplace->getSellers().end(), std::find_if(marketplace_->getSellers().begin(), marketplace_->getSellers().end(),
[&value](const std::unique_ptr<Seller>& s) { [&value](const std::unique_ptr<Seller>& s) {
return value.toInt() == s->getSellerNo(); return value.toInt() == s->getSellerNo();
}); });
if (iter != m_marketplace->getSellers().end()) { if (iter != marketplace_->getSellers().end()) {
emit duplicateSellerNo( emit duplicateSellerNo(
"Die Verkäufernummer muss eindeutig sein.\n(Möglicherweise wird die Nummer von " "Die Verkäufernummer muss eindeutig sein.\n(Möglicherweise wird die Nummer von "
"einem (ausgeblendeten) Eintrag, der zum Löschen vorgemerkt ist, verwendet.)"); "einem (ausgeblendeten) Eintrag, der zum Löschen vorgemerkt ist, verwendet.)");
@ -123,8 +123,8 @@ bool SellerModel::insertRows(int row, int count, const QModelIndex& parent)
{ {
emit beginInsertRows(parent, row, row + count - 1); emit beginInsertRows(parent, row, row + count - 1);
auto seller = std::make_unique<Seller>(); auto seller = std::make_unique<Seller>();
seller->setSellerNo(m_marketplace->getNextSellerNo()); seller->setSellerNo(marketplace_->getNextSellerNo());
m_marketplace->getSellers().push_back(std::move(seller)); marketplace_->getSellers().push_back(std::move(seller));
emit endInsertRows(); emit endInsertRows();
return true; return true;
@ -132,21 +132,21 @@ bool SellerModel::insertRows(int row, int count, const QModelIndex& parent)
bool SellerModel::removeRows(int row, int count, const QModelIndex& parent) bool SellerModel::removeRows(int row, int count, const QModelIndex& parent)
{ {
auto seller = m_marketplace->getSellers().at(row).get(); auto seller = marketplace_->getSellers().at(row).get();
if (seller->getState() == Seller::State::NEW) { if (seller->getState() == Seller::State::NEW) {
emit beginRemoveRows(parent, row, row + count - 1); emit beginRemoveRows(parent, row, row + count - 1);
m_marketplace->getSellers().erase( marketplace_->getSellers().erase(
std::remove_if(m_marketplace->getSellers().begin(), m_marketplace->getSellers().end(), std::remove_if(marketplace_->getSellers().begin(), marketplace_->getSellers().end(),
[&seller](const std::unique_ptr<Seller>& a) { [&seller](const std::unique_ptr<Seller>& a) {
return a->getId() == seller->getId(); return a->getId() == seller->getId();
}), }),
m_marketplace->getSellers().end()); marketplace_->getSellers().end());
emit endRemoveRows(); emit endRemoveRows();
return true; return true;
} else { } else {
emit beginRemoveRows(parent, row, row + count - 1); emit beginRemoveRows(parent, row, row + count - 1);
seller->setState(Seller::State::DELETE); seller->setState(Seller::State::DELETE);
m_marketplace->storeToDb(true); marketplace_->storeToDb(true);
emit endRemoveRows(); emit endRemoveRows();
return true; return true;
} }

View file

@ -1,7 +1,7 @@
#ifndef SELLER_MODEL_H #ifndef SELLER_MODEL_H
#define SELLER_MODEL_H #define SELLER_MODEL_H
#include <core/marketplace.h> #include <marketplace.h>
#include <QAbstractTableModel> #include <QAbstractTableModel>
@ -25,7 +25,7 @@ signals:
void duplicateSellerNo(const QString& message); void duplicateSellerNo(const QString& message);
private: private:
Marketplace *m_marketplace; Marketplace* marketplace_;
}; };
#endif #endif

View file

@ -2,10 +2,9 @@
#include "mainwindow.h" #include "mainwindow.h"
#include <core/database.h> #include <database.h>
#include <core/utils.h> #include <posprinter.h>
#include <printer/posprinter.h> #include <utils.h>
#include <printer/utils.h>
#include <exception> #include <exception>
#include <stdexcept> #include <stdexcept>
@ -15,7 +14,7 @@
SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f)
{ {
m_ui.setupUi(this); ui_.setupUi(this);
QSettings settings{}; QSettings settings{};
int cashPointNo = settings.value("global/cashPointNo").toInt(); int cashPointNo = settings.value("global/cashPointNo").toInt();
@ -26,25 +25,25 @@ SettingsDialog::SettingsDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(par
int maxFeeInEuro = settings.value("global/maxFeeInEuro").toInt(); int maxFeeInEuro = settings.value("global/maxFeeInEuro").toInt();
if (parent) if (parent)
m_market = dynamic_cast<MainWindow *>(parent)->getMarketplace(); market_ = dynamic_cast<MainWindow*>(parent)->getMarketplace();
m_ui.cashPointNoSpinBox->setValue(cashPointNo); ui_.cashPointNoSpinBox->setValue(cashPointNo);
m_ui.communeEdit->setText(commune); ui_.communeEdit->setText(commune);
m_ui.posPrinterDeviceEdit->setText(posPrinterDevice); ui_.posPrinterDeviceEdit->setText(posPrinterDevice);
m_ui.posPrinterEndpointEdit->setText(posPrinterEndpoint); ui_.posPrinterEndpointEdit->setText(posPrinterEndpoint);
m_ui.feePercentSpinBox->setValue(feeInPercent); ui_.feePercentSpinBox->setValue(feeInPercent);
m_ui.maxFeeSpinBox->setValue(maxFeeInEuro); ui_.maxFeeSpinBox->setValue(maxFeeInEuro);
connect(m_ui.testPosPrinterButton, &QPushButton::clicked, this, [this]() { connect(ui_.testPosPrinterButton, &QPushButton::clicked, this, [=]() {
using namespace std::string_literals; using namespace std::string_literals;
try { try {
if (m_ui.posPrinterDeviceEdit->text().isEmpty()) { if (ui_.posPrinterDeviceEdit->text().isEmpty()) {
PosPrinter printer; PosPrinter printer;
printer.printTest(); printer.printTest();
} else { } else {
std::string posPrinterDeviceString = m_ui.posPrinterDeviceEdit->text().toStdString(); std::string posPrinterDeviceString = ui_.posPrinterDeviceEdit->text().toStdString();
std::string posPrinterEndpointString = std::string posPrinterEndpointString =
m_ui.posPrinterEndpointEdit->text().toStdString(); ui_.posPrinterEndpointEdit->text().toStdString();
try { try {
auto printerDevice = auto printerDevice =
@ -80,17 +79,17 @@ void SettingsDialog::accept()
QSettings settings; QSettings settings;
int oldCashPointNo = settings.value("global/cashPointNo").toInt(); int oldCashPointNo = settings.value("global/cashPointNo").toInt();
int newCashPointNo = m_ui.cashPointNoSpinBox->value(); int newCashPointNo = ui_.cashPointNoSpinBox->value();
settings.setValue("global/commune", m_ui.communeEdit->text().trimmed()); settings.setValue("global/commune", ui_.communeEdit->text().trimmed());
settings.setValue("global/posPrinterDevice", m_ui.posPrinterDeviceEdit->text().trimmed()); settings.setValue("global/posPrinterDevice", ui_.posPrinterDeviceEdit->text().trimmed());
settings.setValue("global/posPrinterEndpoint", m_ui.posPrinterEndpointEdit->text().trimmed()); settings.setValue("global/posPrinterEndpoint", ui_.posPrinterEndpointEdit->text().trimmed());
settings.setValue("global/feeInPercent", m_ui.feePercentSpinBox->value()); settings.setValue("global/feeInPercent", ui_.feePercentSpinBox->value());
settings.setValue("global/maxFeeInEuro", m_ui.maxFeeSpinBox->value()); settings.setValue("global/maxFeeInEuro", ui_.maxFeeSpinBox->value());
if (oldCashPointNo != newCashPointNo) { if (oldCashPointNo != newCashPointNo) {
int result{0}; int result{0};
if (m_market && m_market->getSales().size() > 0) { if (market_ && market_->getSales().size() > 0) {
result = QMessageBox(QMessageBox::Icon::Question, "Sind Sie sicher?", result = QMessageBox(QMessageBox::Icon::Question, "Sind Sie sicher?",
"Möchten Sie die Kassen-Nr wirklich ändern? Diese muss über alle " "Möchten Sie die Kassen-Nr wirklich ändern? Diese muss über alle "
"Installationen hinweg eindeutig sein.", "Installationen hinweg eindeutig sein.",
@ -112,7 +111,7 @@ void SettingsDialog::accept()
QDialog::accept(); QDialog::accept();
return; return;
} }
settings.setValue("global/cashPointNo", m_ui.cashPointNoSpinBox->value()); settings.setValue("global/cashPointNo", ui_.cashPointNoSpinBox->value());
} }
} }

View file

@ -3,14 +3,12 @@
#include "ui_settingsdialog.h" #include "ui_settingsdialog.h"
#include <core/marketplace.h> #include <marketplace.h>
#include <QDialog> #include <QDialog>
class SettingsDialog : public QDialog class SettingsDialog : public QDialog
{ {
Q_OBJECT
public: public:
SettingsDialog(QWidget* parent = nullptr, SettingsDialog(QWidget* parent = nullptr,
Qt::WindowFlags f = Qt::WindowTitleHint | Qt::WindowSystemMenuHint); Qt::WindowFlags f = Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
@ -19,8 +17,8 @@ class SettingsDialog : public QDialog
void accept() override; void accept() override;
private: private:
Ui::SettingsDialog m_ui; Ui::SettingsDialog ui_;
Marketplace* m_market{}; Marketplace* market_{};
}; };
#endif #endif

View file

@ -1,3 +0,0 @@
subdir('core')
subdir('printer')
subdir('gui')

View file

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

View file

@ -1,9 +0,0 @@
libusb = dependency('libusb-1.0')
src = ['posprinter.cpp', 'utils.cpp']
printer_inc = include_directories('..')
printer_lib = static_library('printer', src, dependencies: [libusb, core_dep])
printer_dep = declare_dependency(link_with : printer_lib, include_directories : printer_inc)

View file

@ -1,6 +1,6 @@
#include "posprinter.h" #include "posprinter.h"
#include <core/marketplace.h> #include <marketplace.h>
#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp>

View file

@ -1,8 +1,8 @@
#ifndef POS_PRINTER_H #ifndef POS_PRINTER_H
#define POS_PRINTER_H #define POS_PRINTER_H
#include <core/sale.h> #include <sale.h>
#include <core/seller.h> #include <seller.h>
#include <memory> #include <memory>

View file

@ -1,26 +0,0 @@
#include "utils.h"
std::optional<PrinterDevice> 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;
}

View file

@ -1,12 +0,0 @@
#ifndef PRINTER_UTILS_H
#define PRINTER_UTILS_H
#include "posprinter.h"
#include <optional>
#include <string>
std::optional<PrinterDevice> convertToPosPrinterDevice(const std::string& vendor,
const std::string& endpoint);
#endif

@ -1 +0,0 @@
Subproject commit 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03

View file

@ -1,27 +0,0 @@
project('singleapplication')
qt5 = import('qt5')
dep_qt5 = dependency('qt5', modules: ['Core', 'Widgets', 'Network'])
singleapp_inc = include_directories('singleapplication.git')
singleapp_moc = qt5.preprocess(
moc_headers: ['singleapplication.git/singleapplication.h', 'singleapplication.git/singleapplication_p.h'],
moc_extra_arguments: ['-DQAPPLICATION_CLASS=QApplication'],
dependencies: dep_qt5
)
singleapp_lib = static_library('SingleApplication',
['singleapplication.git/singleapplication.cpp', 'singleapplication.git/singleapplication_p.cpp', singleapp_moc],
include_directories: singleapp_inc,
cpp_args : '-DQAPPLICATION_CLASS=QApplication',
dependencies: dep_qt5
)
singleapp_dep = declare_dependency(
include_directories: singleapp_inc,
link_with: singleapp_lib
)
# On windows, SingleApplication needs to be linked against advapi32. This is
# done by adding 'advapi32' to cpp_winlibs, where it should be by default.

@ -1 +0,0 @@
Subproject commit 8c48163c4d3fbba603cfe8a5b94046c9dad71825