Compare commits
67 Commits
Author | SHA1 | Date |
---|---|---|
Martin Brodbeck | 0c7f071b9d | |
Martin Brodbeck | d0c50c9b9a | |
Martin Brodbeck | a17cb22e05 | |
Martin Brodbeck | 205dac5326 | |
Martin Brodbeck | b0d2d6b284 | |
Martin Brodbeck | 7f11ba4e5d | |
Martin Brodbeck | 32d0ec7749 | |
Martin Brodbeck | 54e5c70447 | |
Martin Brodbeck | 379fd4a73c | |
Martin Brodbeck | 8a94b53379 | |
Martin Brodbeck | d9b13d0e1a | |
Martin Brodbeck | 6f885dd64e | |
Martin Brodbeck | 1a698a6cd2 | |
Martin Brodbeck | ac9ae8b34e | |
Martin Brodbeck | 4385624988 | |
Martin Brodbeck | 4cfd8d5572 | |
Martin Brodbeck | 528ae1ff31 | |
Martin Brodbeck | 649c26db4b | |
Martin Brodbeck | 13a1d26d96 | |
Martin Brodbeck | f898844c7c | |
Martin Brodbeck | e6b71a7e4d | |
Martin Brodbeck | f4b4ccbbea | |
Martin Brodbeck | e79a81797c | |
Martin Brodbeck | 8efdf7b6fe | |
Martin Brodbeck | a46e8d89c9 | |
Martin Brodbeck | 3e293ba447 | |
Martin Brodbeck | 245e41bbf0 | |
Martin Brodbeck | b0444112a8 | |
Martin Brodbeck | c4ccd43b45 | |
Martin Brodbeck | 16745a248c | |
Martin Brodbeck | 19ea7f27de | |
Martin Brodbeck | 42bf036f85 | |
Martin Brodbeck | 9d7492c745 | |
Martin Brodbeck | 9fcfb8e3ba | |
Martin Brodbeck | a23de4dcf0 | |
Martin Brodbeck | 77f45fa55f | |
Martin Brodbeck | 7299ae7c66 | |
Martin Brodbeck | 1720dbba8b | |
Martin Brodbeck | 66e2e69c3e | |
Martin Brodbeck | 78aafab63b | |
Martin Brodbeck | 72e1a69dae | |
Martin Brodbeck | 7e38da7276 | |
Martin Brodbeck | 144f61d6d4 | |
Martin Brodbeck | 85574ff08a | |
Martin Brodbeck | c44d8b352a | |
Martin Brodbeck | be9a7be38d | |
Martin Brodbeck | 104464f781 | |
Martin Brodbeck | 3a132e69ae | |
Martin Brodbeck | 01577d02a0 | |
Martin Brodbeck | ecd1111391 | |
Martin Brodbeck | 944edc277a | |
Martin Brodbeck | 0427bd4077 | |
Martin Brodbeck | 2b6628bdf8 | |
Martin Brodbeck | 6944051c31 | |
Martin Brodbeck | 5f7d91a18e | |
Martin Brodbeck | 2b7c099f5e | |
Martin Brodbeck | acc3095e60 | |
Martin Brodbeck | d677dfd628 | |
Martin Brodbeck | e0ffd47430 | |
Martin Brodbeck | 3e6e587df8 | |
Martin Brodbeck | 21571215bc | |
Martin Brodbeck | 52e0f1636e | |
Martin Brodbeck | 38b8865cea | |
Martin Brodbeck | 20c7a99578 | |
Martin Brodbeck | 3572d22715 | |
Martin Brodbeck | 453fd8cdb5 | |
Martin Brodbeck | 911b05b487 |
101
.clang-format
101
.clang-format
|
@ -1,27 +1,38 @@
|
|||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveMacros: None
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: true
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
|
@ -31,13 +42,21 @@ BraceWrapping:
|
|||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Linux
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
|
@ -50,35 +69,56 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
|||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseLabels: false
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentRequires: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
|
@ -86,24 +126,57 @@ PenaltyBreakBeforeFirstCallParameter: 19
|
|||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Left
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: -1
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Auto
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
- NS_SWIFT_NAME
|
||||
- CF_SWIFT_NAME
|
||||
...
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
build
|
||||
.vscode/ipch/*
|
||||
.kdev4
|
||||
.cache
|
|
@ -4,6 +4,3 @@
|
|||
[submodule "subprojects/singleapplication"]
|
||||
path = subprojects/singleapplication/singleapplication.git
|
||||
url = https://github.com/itay-grudev/SingleApplication.git
|
||||
[submodule "subprojects/csv-parser"]
|
||||
path = subprojects/csv-parser
|
||||
url = https://github.com/vincentlaucsb/csv-parser.git
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
],
|
||||
"visualizerFile": "/home/brodbemn/.config/Code - OSS/User/workspaceStorage/d64ec049841ecb3d43e402bb3c167cb5/tonka3000.qtvsctools/qt.natvis.xml"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -65,9 +65,47 @@
|
|||
"condition_variable": "cpp",
|
||||
"mutex": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"future": "cpp"
|
||||
"future": "cpp",
|
||||
"bit": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"random": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__bits": "cpp",
|
||||
"__config": "cpp",
|
||||
"__debug": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__hash_table": "cpp",
|
||||
"__locale": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"__tree": "cpp",
|
||||
"__tuple": "cpp",
|
||||
"__verbose_abort": "cpp",
|
||||
"format": "cpp",
|
||||
"ios": "cpp",
|
||||
"locale": "cpp"
|
||||
},
|
||||
"C_Cpp.clang_format_path": "/usr/bin/clang-format",
|
||||
"cmake.configureOnOpen": true,
|
||||
"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
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
cmake_minimum_required(VERSION 3.8)
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(kima2 VERSION 1.5.3)
|
||||
project(kima2 VERSION 1.8.0)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_HOME_DIRECTORY}/cmake")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
#include(InstallRequiredSystemLibraries)
|
||||
|
@ -17,6 +17,7 @@ else()
|
|||
endif()
|
||||
|
||||
configure_file(config.h.in ${PROJECT_BINARY_DIR}/config.h)
|
||||
configure_file(de.rustysoft.kima2.metainfo.xml.in ${PROJECT_BINARY_DIR}/de.rustysoft.kima2.metainfo.xml)
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
|
@ -79,6 +80,8 @@ else(WIN32 AND NOT UNIX)
|
|||
DESTINATION share/${PROJECT_NAME})
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/misc/kima2.svg"
|
||||
DESTINATION share/icons/hicolor/scalable/apps)
|
||||
install(FILES de.rustysoft.kima2.metainfo.xml
|
||||
DESTINATION share/metainfo)
|
||||
endif (WIN32 AND NOT UNIX)
|
||||
|
||||
if( MINGW )
|
||||
|
@ -87,19 +90,19 @@ if( MINGW )
|
|||
set( CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
|
||||
${MINGW_PATH}/libstdc++-6.dll
|
||||
${MINGW_PATH}/libgcc_s_seh-1.dll
|
||||
${MINGW_PATH}/Qt5Core.dll
|
||||
${MINGW_PATH}/Qt5Gui.dll
|
||||
${MINGW_PATH}/Qt5Widgets.dll
|
||||
${MINGW_PATH}/Qt5PrintSupport.dll
|
||||
${MINGW_PATH}/Qt5Network.dll
|
||||
${MINGW_PATH}/Qt6Core.dll
|
||||
${MINGW_PATH}/Qt6Gui.dll
|
||||
${MINGW_PATH}/Qt6Widgets.dll
|
||||
${MINGW_PATH}/Qt6PrintSupport.dll
|
||||
${MINGW_PATH}/Qt6Network.dll
|
||||
${MINGW_PATH}/libwinpthread-1.dll
|
||||
${MINGW_PATH}/libsqlite3-0.dll
|
||||
${MINGW_PATH}/libusb-1.0.dll
|
||||
${MINGW_PATH}/libxlnt.dll
|
||||
${MINGW_PATH}/libicuuc65.dll
|
||||
${MINGW_PATH}/libicuin65.dll
|
||||
${MINGW_PATH}/libicudt65.dll
|
||||
${MINGW_PATH}/libicuuc73.dll
|
||||
${MINGW_PATH}/libicuin73.dll
|
||||
${MINGW_PATH}/libicudt73.dll
|
||||
${MINGW_PATH}/libpcre2-16-0.dll
|
||||
${MINGW_PATH}/libpcre2-8-0.dll
|
||||
${MINGW_PATH}/zlib1.dll
|
||||
${MINGW_PATH}/libharfbuzz-0.dll
|
||||
${MINGW_PATH}/libpng16-16.dll
|
||||
|
@ -111,19 +114,24 @@ if( MINGW )
|
|||
${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)
|
||||
install(FILES ${MINGW_PATH}/../share/qt5/plugins/platforms/qwindows.dll
|
||||
${MINGW_PATH}/../share/qt5/plugins/platforms/qminimal.dll
|
||||
install(FILES ${MINGW_PATH}/../share/qt6/plugins/platforms/qwindows.dll
|
||||
${MINGW_PATH}/../share/qt6/plugins/platforms/qminimal.dll
|
||||
DESTINATION bin/platforms)
|
||||
install(FILES ${MINGW_PATH}/../share/qt5/plugins/printsupport/windowsprintersupport.dll
|
||||
DESTINATION bin/printsupport)
|
||||
install(FILES ${MINGW_PATH}/../share/qt5/translations/qtbase_de.qm
|
||||
${MINGW_PATH}/../share/qt5/translations/qt_de.qm
|
||||
${MINGW_PATH}/../share/qt5/translations/qt_help_de.qm
|
||||
${MINGW_PATH}/../share/qt5/translations/qtmultimedia_de.qm
|
||||
${MINGW_PATH}/../share/qt5/translations/qtquickcontrols_de.qm
|
||||
${MINGW_PATH}/../share/qt5/translations/qtscript_de.qm
|
||||
${MINGW_PATH}/../share/qt5/translations/qtxmlpatterns_de.qm
|
||||
#install(FILES ${MINGW_PATH}/../share/qt6/plugins/printsupport/windowsprintersupport.dll
|
||||
# DESTINATION bin/printsupport)
|
||||
install(FILES ${MINGW_PATH}/../share/qt6/translations/qtbase_de.qm
|
||||
${MINGW_PATH}/../share/qt6/translations/qt_de.qm
|
||||
${MINGW_PATH}/../share/qt6/translations/qt_help_de.qm
|
||||
${MINGW_PATH}/../share/qt6/translations/qtmultimedia_de.qm
|
||||
#${MINGW_PATH}/../share/qt6/translations/qtquickcontrols_de.qm
|
||||
#${MINGW_PATH}/../share/qt6/translations/qtscript_de.qm
|
||||
#${MINGW_PATH}/../share/qt6/translations/qtxmlpatterns_de.qm
|
||||
DESTINATION bin/translations)
|
||||
endif( MINGW )
|
||||
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright © 2018-2021 Martin Brodbeck
|
||||
Copyright © 2018-2024 Martin Brodbeck
|
||||
|
||||
Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der
|
||||
zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt,
|
||||
|
|
10
README.md
10
README.md
|
@ -13,19 +13,17 @@ Verkaufsdaten nach dem Verkaufsende auszutauschen.
|
|||
Ebenso können über einen ESC/POS-Drucker Quittungen ausgestellt werden.
|
||||
|
||||
## Installation
|
||||
Auf [rustysoft.de](https://www.rustysoft.de/?01_kima2) werden verschiedene Installationspakete (Arch Linux,
|
||||
Auf [rustysoft.de](https://www.rustysoft.de/software/kima2/) werden verschiedene Installationspakete (Arch Linux,
|
||||
Ubuntu, Windows) angeboten. Bitte die Hinweise dort beachten.
|
||||
|
||||
### Selbst compilieren
|
||||
KIMA2 benötigt folgende Libraries:
|
||||
* Qt5
|
||||
* boost >= 1.62
|
||||
* Qt 6
|
||||
* boost >= 1.80
|
||||
* libusb-1.0
|
||||
* xlnt >= 1.3.0
|
||||
* nlohmann-json (als 3rdparty submodule vorhanden)
|
||||
|
||||
Da Features aus C++17 verwendet werden sowie std::filesystem, sollte als Compiler mindestens
|
||||
GCC 8 verwendet werden.
|
||||
Da Features aus C++20 verwendet werden, sollte als Compiler mindestens GCC 12 verwendet werden.
|
||||
|
||||
Die Installationsschritte unter Linux sind wie folgt:
|
||||
```
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>de.rustysoft.kima2</id>
|
||||
|
||||
<name>KIMA2</name>
|
||||
<summary>A small cash point program for children’s 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.
|
@ -1,4 +1,4 @@
|
|||
project('kima2', 'cpp', default_options : ['cpp_std=c++17'], version : '1.5.3')
|
||||
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() + '"')
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
# Maintainer: Martin Brodbeck <martin at brodbeck-online dot de>
|
||||
pkgname=kima2
|
||||
pkgver=1.5.0
|
||||
pkgver=1.7.1
|
||||
pkgrel=1
|
||||
pkgdesc="A small cash point program for children's things markets (German only)"
|
||||
arch=('i686' 'x86_64')
|
||||
url="http://www.rustysoft.de/?01_kima2"
|
||||
url="http://www.rustysoft.de/software/kima2"
|
||||
license=('custom')
|
||||
depends=('glibc' 'libusb' 'qt5-base' 'sqlite3' 'xlnt')
|
||||
depends=('glibc' 'libusb' 'qt6-base' 'sqlite3')
|
||||
makedepends=('boost>=1.62')
|
||||
source=($pkgname-$pkgver.tar.gz)
|
||||
md5sums=('c0e6a64b5037675edce4ba8bc4639bd3')
|
||||
source=(git+https://git.rustysoft.de/martin/kima2)
|
||||
sha256sums=('SKIP')
|
||||
|
||||
build() {
|
||||
if [ ! -d $pkgname/build ]; then
|
||||
mkdir $pkgname/build
|
||||
cd $pkgname
|
||||
|
||||
git checkout v$pkgver
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
if [ -d build ]; then
|
||||
rm -rf build
|
||||
fi
|
||||
cd $pkgname/build
|
||||
mkdir build && cd build
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DKIMA2_USE_EXTERNAL_JSON=OFF ..
|
||||
make
|
||||
|
|
|
@ -3,8 +3,8 @@ Type=Application
|
|||
Name=KIMA2
|
||||
GenericName=Cash Point Program
|
||||
GenericName[de]=Kassenprogramm
|
||||
Comment=A small cash point program
|
||||
Comment[de]=Ein kleines Kassenprogramm
|
||||
Comment=A small cash point program for children's stuff markets
|
||||
Comment[de]=Ein kleines Kassenprogramm für Kindersachenmärkte
|
||||
Exec=kima2
|
||||
Icon=kima2
|
||||
Categories=Office;
|
||||
|
|
|
@ -13,7 +13,6 @@ BuildRequires: boost-date-time
|
|||
BuildRequires: sqlite-devel
|
||||
BuildRequires: libusb-devel
|
||||
BuildRequires: qt5-qtdeclarative-devel
|
||||
#BuildRequires: pkgconfig(xlnt)
|
||||
#BuildRequires: pkgconfig(pthreads)
|
||||
|
||||
%description
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
set(Boost_USE_STATIC_LIBS ON)
|
||||
|
||||
find_package(Boost 1.62 COMPONENTS date_time REQUIRED)
|
||||
find_package(Boost 1.78 REQUIRED)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
|
||||
# Because csv-parser needs threads:
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
|
||||
if (MINGW)
|
||||
find_package(XLNT REQUIRED STATIC)
|
||||
else (MINGW)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(XLNT REQUIRED xlnt>=1.3)
|
||||
endif (MINGW)
|
||||
find_package(fmt)
|
||||
|
||||
set(CORE_SOURCES
|
||||
database.cpp
|
||||
|
@ -24,7 +16,6 @@ set(CORE_SOURCES
|
|||
article.cpp
|
||||
sale.cpp
|
||||
marketplace.cpp
|
||||
excelreader.cpp
|
||||
csvreader.cpp
|
||||
jsonutil.cpp
|
||||
utils.cpp
|
||||
|
@ -32,12 +23,12 @@ set(CORE_SOURCES
|
|||
|
||||
|
||||
add_library(core STATIC ${CORE_SOURCES})
|
||||
target_include_directories(core PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/csv-parser/single_include)
|
||||
#target_include_directories(core PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/csv-parser/single_include)
|
||||
if (WIN32)
|
||||
target_link_libraries(core PRIVATE Boost::boost Boost::date_time sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARY} Threads::Threads)
|
||||
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json fmt::fmt)
|
||||
target_link_libraries(core PRIVATE bcrypt)
|
||||
else()
|
||||
target_link_libraries(core PRIVATE Boost::boost Boost::date_time sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARIES} Threads::Threads)
|
||||
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json fmt::fmt)
|
||||
endif()
|
||||
|
||||
target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
|
|
|
@ -5,34 +5,34 @@
|
|||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
Article::Article(int price) : price_(price) {}
|
||||
Article::Article(int price) : m_price(price) {}
|
||||
|
||||
void Article::setArticleNo(int articleNo) { articleNo_ = articleNo; }
|
||||
void Article::setArticleNo(int articleNo) { m_articleNo = articleNo; }
|
||||
|
||||
void Article::setPrice(int price) { price_ = price; }
|
||||
void Article::setPrice(int price) { m_price = price; }
|
||||
|
||||
void Article::setDescription(const std::string& description) { description_ = description; }
|
||||
void Article::setDescription(const std::string &description) { m_description = description; }
|
||||
|
||||
void Article::setSale(Sale* salePtr) { salePtr_ = salePtr; }
|
||||
void Article::setSale(Sale *salePtr) { m_salePtr = salePtr; }
|
||||
|
||||
void Article::setSeller(Seller* sellerPtr) { sellerPtr_ = sellerPtr; }
|
||||
void Article::setSeller(Seller *sellerPtr) { m_sellerPtr = sellerPtr; }
|
||||
|
||||
bool Article::isSold() { return salePtr_ ? true : false; }
|
||||
bool Article::isSold() { return m_salePtr ? true : false; }
|
||||
|
||||
std::string Article::getDescription() { return description_; }
|
||||
std::string Article::getDescription() { return m_description; }
|
||||
|
||||
Seller* Article::getSeller() { return sellerPtr_; }
|
||||
Sale* Article::getSale() { return salePtr_; }
|
||||
Seller *Article::getSeller() { return m_sellerPtr; }
|
||||
Sale *Article::getSale() { return m_salePtr; }
|
||||
|
||||
int Article::getPrice() const { return price_; }
|
||||
int Article::getPrice() const { return m_price; }
|
||||
|
||||
std::string Article::getPriceAsString() const { return formatCentAsEuroString(price_); }
|
||||
std::string Article::getPriceAsString() const { return formatCentAsEuroString(m_price); }
|
||||
|
||||
int Article::getArticleNo() const { return articleNo_; }
|
||||
int Article::getArticleNo() const { return m_articleNo; }
|
||||
|
||||
std::string Article::getCompleteArticleNo() const
|
||||
{
|
||||
std::stringstream artNoStream;
|
||||
artNoStream << sourceNo_ << "K" << std::setfill('0') << std::setw(5) << articleNo_;
|
||||
artNoStream << m_sourceNo << "K" << std::setfill('0') << std::setw(5) << m_articleNo;
|
||||
return artNoStream.str();
|
||||
}
|
||||
|
|
|
@ -33,12 +33,11 @@ class Article : public EntityUuid
|
|||
std::string getPriceAsString() const;
|
||||
|
||||
private:
|
||||
Seller* sellerPtr_{};
|
||||
Sale* salePtr_{};
|
||||
int articleNo_{};
|
||||
int price_{};
|
||||
std::string description_{};
|
||||
Seller *m_sellerPtr{};
|
||||
Sale *m_salePtr{};
|
||||
int m_articleNo{};
|
||||
int m_price{};
|
||||
std::string m_description{};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
#include <fstream>
|
||||
|
||||
#include <csv.hpp>
|
||||
// #include <csv.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#ifdef DELETE
|
||||
#undef DELETE
|
||||
|
@ -13,17 +14,16 @@ namespace fs = std::filesystem;
|
|||
|
||||
std::size_t CsvReader::readSellersFromFile(const fs::path &filePath, Marketplace *market)
|
||||
{
|
||||
csv::CSVFormat format;
|
||||
format.delimiter(';');
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
// Windows: Somhow this is necessary in order to open file names with umlauts
|
||||
auto wide = filePath.wstring();
|
||||
std::string fileName(wide.begin(), wide.end());
|
||||
|
||||
csv::CSVReader csvReader(fileName, format);
|
||||
std::ifstream infile(fileName);
|
||||
#else
|
||||
csv::CSVReader csvReader(filePath.string(), format);
|
||||
// csv::CSVReader csvReader(filePath.string(), format);
|
||||
std::ifstream infile(filePath.string());
|
||||
#endif
|
||||
|
||||
for (auto &seller : market->getSellers()) {
|
||||
|
@ -32,33 +32,48 @@ std::size_t CsvReader::readSellersFromFile(const fs::path& filePath, Marketplace
|
|||
|
||||
market->storeToDb(true);
|
||||
|
||||
int rowCount{};
|
||||
for (csv::CSVRow &row : csvReader) {
|
||||
if (!row[0].is_int()) {
|
||||
++rowCount;
|
||||
continue;
|
||||
}
|
||||
std::string line;
|
||||
|
||||
if (row[2].get<std::string>().empty() && row[3].get<std::string>().empty()) {
|
||||
++rowCount;
|
||||
continue;
|
||||
}
|
||||
while (getline(infile, line)) {
|
||||
std::vector<std::string> strs;
|
||||
boost::split(strs, line, boost::is_any_of(";"));
|
||||
|
||||
auto seller = std::make_unique<Seller>();
|
||||
seller->setSellerNo(row[0].get<int>());
|
||||
if (row[1].is_int()) {
|
||||
seller->setNumArticlesOffered(row[1].get<int>());
|
||||
} else {
|
||||
|
||||
try {
|
||||
int sellerNo = std::stoi(strs[0]);
|
||||
seller->setSellerNo(sellerNo);
|
||||
} catch (std::invalid_argument const &ex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isNumber(strs[1]))
|
||||
seller->setNumArticlesOffered(std::stoi(strs[1]));
|
||||
else
|
||||
seller->setNumArticlesOffered(0);
|
||||
}
|
||||
std::string firstName = row[2].get<std::string>();
|
||||
|
||||
// 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 = row[3].get<std::string>();
|
||||
std::string lastName = strs[3];
|
||||
seller->setLastName(trim(lastName));
|
||||
market->getSellers().push_back(std::move(seller));
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
market->getSellers().push_back(std::move(seller));
|
||||
}
|
||||
|
||||
// Add one additional seller "RESERVE RESERVE"
|
||||
auto seller = std::make_unique<Seller>();
|
||||
seller->setSellerNo(market->getNextSellerNo());
|
||||
seller->setFirstName("RESERVE");
|
||||
seller->setLastName("RESERVE");
|
||||
market->getSellers().push_back(std::move(seller));
|
||||
|
||||
// If there was no special seller "Sonderkonto" in import data, then create one
|
||||
auto specialSeller = market->findSellerWithSellerNo(0);
|
||||
if (!specialSeller) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "database.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <fmt/chrono.h>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include "boost/date_time/posix_time/posix_time.hpp"
|
||||
|
||||
Database::Database(const std::string &dbname)
|
||||
{
|
||||
dbname_ = dbname;
|
||||
|
@ -45,8 +45,11 @@ void Database::newDb()
|
|||
|
||||
fs::path sourcePath = dbname_;
|
||||
fs::path destPath = sourcePath.parent_path() / sourcePath.stem();
|
||||
destPath += std::string("_") +=
|
||||
boost::posix_time::to_iso_string(boost::posix_time::second_clock::local_time()) += ".db";
|
||||
|
||||
auto chronoTime = std::chrono::system_clock::now();
|
||||
std::string timeString = fmt::format("{0:%FT%H-%M-%S}", chronoTime);
|
||||
|
||||
destPath += std::string("_") += timeString += ".db";
|
||||
|
||||
fs::copy_file(sourcePath, destPath, fs::copy_options::overwrite_existing);
|
||||
|
||||
|
@ -594,7 +597,8 @@ unsigned int Database::loadSellers(std::vector<std::unique_ptr<Seller>>& sellers
|
|||
while (retCode != SQLITE_DONE) {
|
||||
++count;
|
||||
auto article = std::make_unique<Article>();
|
||||
article->setUuidFromString(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
|
||||
article->setUuidFromString(
|
||||
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)));
|
||||
article->setSeller(seller.get());
|
||||
article->setSourceNo(sqlite3_column_int(stmt, 1));
|
||||
article->setArticleNo(sqlite3_column_int(stmt, 2));
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
#include "entity.h"
|
||||
|
||||
Entity::State Entity::getState() const
|
||||
{
|
||||
return state_;
|
||||
}
|
||||
Entity::State Entity::getState() const { return m_state; }
|
||||
|
|
|
@ -6,11 +6,11 @@ class Entity
|
|||
public:
|
||||
enum class State { NEW, UPDATE, DELETE, OK };
|
||||
virtual ~Entity() = default;
|
||||
void setState(State state) { state_ = state; }
|
||||
void setState(State state) { m_state = state; }
|
||||
virtual State getState() const;
|
||||
|
||||
private:
|
||||
State state_{State::NEW};
|
||||
State m_state{State::NEW};
|
||||
};
|
||||
|
||||
#endif // ENTITY_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "entityint.h"
|
||||
|
||||
EntityInt::EntityInt(int id) { id_ = id; }
|
||||
EntityInt::EntityInt(int id) { m_id = id; }
|
||||
|
||||
void EntityInt::setId(int id) { id_ = id; }
|
||||
void EntityInt::setId(int id) { m_id = id; }
|
||||
|
|
|
@ -10,10 +10,10 @@ class EntityInt : public Entity
|
|||
virtual ~EntityInt() = default;
|
||||
EntityInt(int id);
|
||||
void setId(int id);
|
||||
int getId() const { return id_; };
|
||||
int getId() const { return m_id; };
|
||||
|
||||
protected:
|
||||
int id_{};
|
||||
int m_id{};
|
||||
};
|
||||
|
||||
#endif // ENTITY_INT_H
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
void EntityUuid::createUuid()
|
||||
{
|
||||
static boost::uuids::random_generator generator{};
|
||||
uuid_ = generator();
|
||||
m_uuid = generator();
|
||||
}
|
||||
|
||||
void EntityUuid::setUuidFromString(const std::string &uuidString)
|
||||
{
|
||||
boost::uuids::string_generator generator{};
|
||||
uuid_ = generator(uuidString);
|
||||
m_uuid = generator(uuidString);
|
||||
}
|
||||
|
||||
void EntityUuid::setSourceNo(int sourceNo) { sourceNo_ = sourceNo; }
|
||||
void EntityUuid::setSourceNo(int sourceNo) { m_sourceNo = sourceNo; }
|
||||
|
||||
int EntityUuid::getSourceNo() const { return sourceNo_; }
|
||||
int EntityUuid::getSourceNo() const { return m_sourceNo; }
|
||||
|
|
|
@ -18,15 +18,15 @@ class EntityUuid : public Entity
|
|||
void setUuidFromString(const std::string &uuidString);
|
||||
void setSourceNo(int sourceNo);
|
||||
|
||||
const boost::uuids::uuid& getUuid() const { return uuid_; };
|
||||
std::string getUuidAsString() const { return boost::uuids::to_string(uuid_); }
|
||||
const boost::uuids::uuid &getUuid() const { return m_uuid; };
|
||||
std::string getUuidAsString() const { return boost::uuids::to_string(m_uuid); }
|
||||
virtual int getSourceNo() const;
|
||||
|
||||
protected:
|
||||
int sourceNo_{};
|
||||
int m_sourceNo{};
|
||||
|
||||
private:
|
||||
boost::uuids::uuid uuid_{};
|
||||
boost::uuids::uuid m_uuid{};
|
||||
};
|
||||
|
||||
#endif // ENTITY_UUID_H
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
#include "excelreader.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <xlnt/xlnt.hpp>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::size_t ExcelReader::readSellersFromFile(const fs::path& filePath, Marketplace* market)
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
std::ifstream mystream(filePath, std::ios::binary);
|
||||
if (!mystream.is_open()) {
|
||||
throw std::runtime_error("Could not open Excel file");
|
||||
}
|
||||
wb.load(mystream);
|
||||
|
||||
for (auto& seller : market->getSellers()) {
|
||||
seller->setState(Seller::State::DELETE);
|
||||
}
|
||||
|
||||
market->storeToDb(true);
|
||||
auto ws = wb.sheet_by_index(0);
|
||||
|
||||
for (auto row : ws.rows(true)) {
|
||||
// Skip the row if the first value is not a number (= seller no)
|
||||
if (row[0].data_type() != xlnt::cell::type::number) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Skip the row if the seller has neither a first name nor a surname
|
||||
if (row[2].value<std::string>().empty() && row[3].value<std::string>().empty()) {
|
||||
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));
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef EXCEL_READER_H
|
||||
#define EXCEL_READER_H
|
||||
|
||||
#include "marketplace.h"
|
||||
#include "seller.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class ExcelReader
|
||||
{
|
||||
public:
|
||||
static std::size_t readSellersFromFile(const std::filesystem::path& filePath,
|
||||
Marketplace* market);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include <fstream>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
using json = nlohmann::json;
|
||||
|
||||
void JsonUtil::exportSellers(const std::filesystem::path &filePath, Marketplace *market)
|
||||
|
@ -103,8 +102,10 @@ void JsonUtil::importSales(const std::filesystem::path& filePath, Marketplace* m
|
|||
|
||||
int source_no = jsonValues["source_no"];
|
||||
if (source_no == cashPointNo) {
|
||||
throw std::runtime_error("Die Kassen-Nr. der zu imporierenden Daten wird von dieser Kasse "
|
||||
"hier bereits verwendet.");
|
||||
std::string ret = "Die Kassen-Nr. ";
|
||||
ret += std::to_string(source_no);
|
||||
ret += " der zu imporierenden Daten wird von dieser Kasse hier bereits verwendet.";
|
||||
throw std::runtime_error(ret);
|
||||
}
|
||||
|
||||
market->setSalesToDelete(jsonValues["source_no"]);
|
||||
|
|
|
@ -6,38 +6,38 @@
|
|||
void Sale::addArticle(Article *articlePtr)
|
||||
{
|
||||
articlePtr->setSale(this);
|
||||
articles_.push_back(articlePtr);
|
||||
m_articles.push_back(articlePtr);
|
||||
}
|
||||
|
||||
ArticlesVec& Sale::getArticles() { return articles_; }
|
||||
ArticlesVec &Sale::getArticles() { return m_articles; }
|
||||
|
||||
void Sale::removeArticle(const Article *articlePtr)
|
||||
{
|
||||
auto it = std::find(articles_.begin(), articles_.end(), articlePtr);
|
||||
auto it = std::find(m_articles.begin(), m_articles.end(), articlePtr);
|
||||
|
||||
if (it != articles_.end()) {
|
||||
if (it != m_articles.end()) {
|
||||
(*it)->setSale(nullptr);
|
||||
(*it)->setState(
|
||||
Article::State::DELETE); // since we only have ad-hoc articles, that have all been sold
|
||||
articles_.erase(it);
|
||||
m_articles.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
int Sale::sumInCents()
|
||||
{
|
||||
int sum = std::accumulate(articles_.begin(), articles_.end(), 0,
|
||||
int sum = std::accumulate(m_articles.begin(), m_articles.end(), 0,
|
||||
[](int a, const Article *b) { return a + b->getPrice(); });
|
||||
return sum;
|
||||
}
|
||||
|
||||
std::string Sale::sumAsString() { return formatCentAsEuroString(sumInCents()); }
|
||||
|
||||
std::string Sale::getTimestamp() const { return timestamp_; }
|
||||
std::string Sale::getTimestamp() const { return m_timestamp; }
|
||||
|
||||
void Sale::setTimestamp(const std::string& timestamp) { timestamp_ = timestamp; }
|
||||
void Sale::setTimestamp(const std::string ×tamp) { m_timestamp = timestamp; }
|
||||
|
||||
std::string Sale::getTimestampFormatted() const
|
||||
{
|
||||
boost::posix_time::ptime time = boost::posix_time::from_iso_extended_string(timestamp_);
|
||||
boost::posix_time::ptime time = boost::posix_time::from_iso_extended_string(m_timestamp);
|
||||
return boost::posix_time::to_simple_string(time);
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ class Sale : public EntityUuid
|
|||
void removeArticle(const Article *articlePtr);
|
||||
|
||||
private:
|
||||
std::string timestamp_{
|
||||
std::string m_timestamp{
|
||||
boost::posix_time::to_iso_extended_string(boost::posix_time::second_clock::local_time())};
|
||||
mutable ArticlesVec articles_{};
|
||||
mutable ArticlesVec m_articles{};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,28 +9,28 @@ Seller::Seller(const std::string& firstName, const std::string& lastName, int se
|
|||
int numArticlesOffered)
|
||||
: EntityInt(sellerNo)
|
||||
{
|
||||
firstName_ = firstName;
|
||||
lastName_ = lastName;
|
||||
numArticlesOffered_ = numArticlesOffered;
|
||||
m_firstName = firstName;
|
||||
m_lastName = lastName;
|
||||
m_numArticlesOffered = numArticlesOffered;
|
||||
}
|
||||
|
||||
void Seller::setSellerNo(int seller_no) { setId(seller_no); }
|
||||
|
||||
void Seller::setFirstName(const std::string& firstName) { firstName_ = firstName; }
|
||||
void Seller::setFirstName(const std::string &firstName) { m_firstName = firstName; }
|
||||
|
||||
void Seller::setLastName(const std::string& lastName) { lastName_ = lastName; }
|
||||
void Seller::setLastName(const std::string &lastName) { m_lastName = lastName; }
|
||||
|
||||
void Seller::setNumArticlesOffered(int number) { numArticlesOffered_ = number; }
|
||||
void Seller::setNumArticlesOffered(int number) { m_numArticlesOffered = number; }
|
||||
|
||||
void Seller::addArticle(std::unique_ptr<Article> article)
|
||||
{
|
||||
article->setSeller(this);
|
||||
articles_.push_back(std::move(article));
|
||||
m_articles.push_back(std::move(article));
|
||||
}
|
||||
|
||||
std::string Seller::getFirstName() const { return firstName_; }
|
||||
std::string Seller::getFirstName() const { return m_firstName; }
|
||||
|
||||
std::string Seller::getLastName() const { return lastName_; }
|
||||
std::string Seller::getLastName() const { return m_lastName; }
|
||||
|
||||
int Seller::getSellerNo() const { return getId(); }
|
||||
|
||||
|
@ -38,7 +38,7 @@ std::string Seller::getSellerNoAsString() const
|
|||
{
|
||||
std::stringstream selNoStr;
|
||||
|
||||
selNoStr << std::setfill('0') << std::setw(3) << id_;
|
||||
selNoStr << std::setfill('0') << std::setw(3) << m_id;
|
||||
|
||||
return selNoStr.str();
|
||||
;
|
||||
|
@ -47,7 +47,7 @@ std::string Seller::getSellerNoAsString() const
|
|||
std::vector<Article *> Seller::getArticles(bool onlySold) const
|
||||
{
|
||||
std::vector<Article *> articles;
|
||||
for (const auto& article : articles_) {
|
||||
for (const auto &article : m_articles) {
|
||||
if (onlySold && article->isSold()) {
|
||||
articles.push_back(article.get());
|
||||
} else if (!onlySold) {
|
||||
|
@ -59,52 +59,52 @@ std::vector<Article*> Seller::getArticles(bool onlySold) const
|
|||
|
||||
Article *Seller::getArticleByUuid(const std::string &uuidString)
|
||||
{
|
||||
auto iter = std::find_if(articles_.begin(), articles_.end(), [&uuidString](const auto& art) {
|
||||
auto iter = std::find_if(m_articles.begin(), m_articles.end(), [&uuidString](const auto &art) {
|
||||
return art->getUuidAsString() == uuidString;
|
||||
});
|
||||
if (iter == articles_.end())
|
||||
if (iter == m_articles.end())
|
||||
return nullptr;
|
||||
return (*iter).get();
|
||||
}
|
||||
|
||||
int Seller::numArticlesSold() const { return static_cast<int>(getArticles(true).size()); }
|
||||
|
||||
int Seller::numArticlesOffered() const { return numArticlesOffered_; }
|
||||
int Seller::numArticlesOffered() const { return m_numArticlesOffered; }
|
||||
|
||||
int Seller::getMaxArticleNo() const
|
||||
{
|
||||
auto iter = std::max_element(
|
||||
articles_.begin(), articles_.end(),
|
||||
m_articles.begin(), m_articles.end(),
|
||||
[](const auto &a, const auto &b) -> bool { return a->getArticleNo() < b->getArticleNo(); });
|
||||
if (iter == articles_.end())
|
||||
if (iter == m_articles.end())
|
||||
return 0;
|
||||
return (*iter)->getArticleNo();
|
||||
}
|
||||
|
||||
void Seller::cleanupArticles()
|
||||
{
|
||||
articles_.erase(std::remove_if(articles_.begin(), articles_.end(),
|
||||
m_articles.erase(std::remove_if(m_articles.begin(), m_articles.end(),
|
||||
[](const auto &article) {
|
||||
return article->getState() == Article::State::DELETE;
|
||||
}),
|
||||
articles_.end());
|
||||
m_articles.end());
|
||||
|
||||
for (auto& article : articles_) {
|
||||
for (auto &article : m_articles) {
|
||||
article->setState(Article::State::OK);
|
||||
}
|
||||
}
|
||||
|
||||
int Seller::sumInCents()
|
||||
{
|
||||
int sum = std::accumulate(articles_.begin(), articles_.end(), 0,
|
||||
int sum = std::accumulate(m_articles.begin(), m_articles.end(), 0,
|
||||
[](int a, const auto &b) { return a + b->getPrice(); });
|
||||
return sum;
|
||||
}
|
||||
|
||||
std::string Seller::sumAsString() { return formatCentAsEuroString(sumInCents()); }
|
||||
|
||||
bool operator<(const Seller& li, const Seller& re) { return li.id_ < re.id_; }
|
||||
bool operator<(const Seller &li, const Seller &re) { return li.m_id < re.m_id; }
|
||||
bool operator<(const std::unique_ptr<Seller> &li, const std::unique_ptr<Seller> &re)
|
||||
{
|
||||
return li->id_ < re->id_;
|
||||
return li->m_id < re->m_id;
|
||||
}
|
||||
|
|
|
@ -42,10 +42,10 @@ class Seller : public EntityInt
|
|||
friend bool operator<(const std::unique_ptr<Seller> &li, const std::unique_ptr<Seller> &re);
|
||||
|
||||
private:
|
||||
int numArticlesOffered_{};
|
||||
std::string firstName_{};
|
||||
std::string lastName_{};
|
||||
std::vector<std::unique_ptr<Article>> articles_{};
|
||||
int m_numArticlesOffered{};
|
||||
std::string m_firstName{};
|
||||
std::string m_lastName{};
|
||||
std::vector<std::unique_ptr<Article>> m_articles{};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <clocale>
|
||||
#include <fmt/format.h>
|
||||
#include <iomanip>
|
||||
#include <numeric>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace fmt;
|
||||
|
||||
std::string formatCentAsEuroString(const int cent, int width)
|
||||
{
|
||||
std::stringstream currStream;
|
||||
/*std::stringstream currStream;
|
||||
|
||||
try {
|
||||
std::locale myLocale("de_DE.utf8");
|
||||
currStream.imbue(myLocale);
|
||||
std::cout << ">>> " << fmt::format(myLocale, "{:6.2Lf}", 1.12345) << '\n';
|
||||
currStream << std::right << std::setw(width) << std::showbase
|
||||
<< std::put_money(cent, false);
|
||||
} catch (std::runtime_error &err) {
|
||||
|
@ -18,7 +25,14 @@ std::string formatCentAsEuroString(const int cent, int width)
|
|||
<< std::setprecision(2) << cent / 100.0L << " €";
|
||||
}
|
||||
|
||||
return currStream.str();
|
||||
return currStream.str();*/
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
std::locale myLocale;
|
||||
#else
|
||||
std::locale myLocale{"de_DE.utf8"};
|
||||
#endif
|
||||
return fmt::format(myLocale, "{:{}.2Lf} €", cent / 100.0L, width);
|
||||
}
|
||||
|
||||
std::string <rim(std::string &str, const std::string &chars)
|
||||
|
@ -47,3 +61,10 @@ bool case_insensitive_match(std::string s1, std::string s2)
|
|||
return true; // The strings are same
|
||||
return false; // not matched
|
||||
}
|
||||
|
||||
bool isNumber(const std::string &str)
|
||||
{
|
||||
return !str.empty() && std::find_if(str.begin(), str.end(), [](unsigned char c) {
|
||||
return !std::isdigit(c);
|
||||
}) == str.end();
|
||||
}
|
|
@ -5,10 +5,11 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
std::string formatCentAsEuroString(const int cent, int width = 10);
|
||||
std::string formatCentAsEuroString(const int cent, int width = 6);
|
||||
std::string <rim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
|
||||
std::string &rtrim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
|
||||
std::string &trim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
|
||||
bool case_insensitive_match(std::string s1, std::string s2);
|
||||
bool isNumber(const std::string &str);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,11 +8,12 @@ set(CMAKE_AUTOUIC ON)
|
|||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
# Find the QtWidgets library
|
||||
find_package(Qt5Widgets CONFIG REQUIRED)
|
||||
find_package(Qt5PrintSupport CONFIG REQUIRED)
|
||||
find_package(Qt6 COMPONENTS Widgets Network PrintSupport CONFIG REQUIRED)
|
||||
#find_package(Qt5Widgets CONFIG REQUIRED)
|
||||
#find_package(Qt5PrintSupport CONFIG REQUIRED)
|
||||
|
||||
# For SingleApplication:
|
||||
find_package(Qt5Network CONFIG REQUIRED)
|
||||
#find_package(Qt5Network CONFIG REQUIRED)
|
||||
set(QAPPLICATION_CLASS QApplication)
|
||||
add_compile_definitions(QAPPLICATION_CLASS=${QAPPLICATION_CLASS})
|
||||
|
||||
|
@ -40,7 +41,9 @@ set(GUI_SOURCES
|
|||
add_executable(kima2 ${GUI_SOURCES} kima2.rc)
|
||||
target_include_directories(kima2 PRIVATE ${PROJECT_BINARY_DIR})
|
||||
target_include_directories(kima2 PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git)
|
||||
target_link_libraries(kima2 core printer Qt5::Widgets Qt5::PrintSupport Qt5::Network stdc++fs)
|
||||
# target_link_libraries(kima2 core printer Qt5::Widgets Qt5::PrintSupport Qt5::Network stdc++fs)
|
||||
target_link_libraries(kima2 core printer Qt::Core Qt::PrintSupport Qt::Network)
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(kima2 PROPERTIES LINK_FLAGS "-mwindows")
|
||||
endif(WIN32)
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
#include <QSettings>
|
||||
|
||||
BasketModel::BasketModel(Marketplace* market, QObject* parent)
|
||||
: QAbstractTableModel(parent), marketplace_(market)
|
||||
: QAbstractTableModel(parent), m_marketplace(market)
|
||||
{
|
||||
}
|
||||
|
||||
int BasketModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
|
||||
{
|
||||
return static_cast<int>(marketplace_->basketSize());
|
||||
return static_cast<int>(m_marketplace->basketSize());
|
||||
}
|
||||
|
||||
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)
|
||||
return QVariant();
|
||||
|
||||
if (marketplace_->basketSize() == 0)
|
||||
if (m_marketplace->basketSize() == 0)
|
||||
return QVariant();
|
||||
|
||||
Article* article = marketplace_->getBasket().at(index.row()).get();
|
||||
Article* article = m_marketplace->getBasket().at(index.row()).get();
|
||||
|
||||
switch (index.column()) {
|
||||
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)
|
||||
{
|
||||
emit beginInsertRows(QModelIndex(), marketplace_->getBasket().size(),
|
||||
marketplace_->getBasket().size());
|
||||
emit beginInsertRows(QModelIndex(), m_marketplace->getBasket().size(),
|
||||
m_marketplace->getBasket().size());
|
||||
auto article = std::make_unique<Article>(price);
|
||||
article->createUuid();
|
||||
article->setDescription(desc);
|
||||
article->setArticleNo(marketplace_->getNextArticleNo());
|
||||
article->setArticleNo(m_marketplace->getNextArticleNo());
|
||||
article->setSourceNo(QSettings().value("global/cashPointNo").toInt());
|
||||
article->setSeller(seller);
|
||||
marketplace_->addArticleToBasket(std::move(article));
|
||||
m_marketplace->addArticleToBasket(std::move(article));
|
||||
emit endInsertRows();
|
||||
}
|
||||
|
||||
void BasketModel::finishSale()
|
||||
{
|
||||
emit beginRemoveRows(QModelIndex(), 0, marketplace_->getBasket().size() - 1);
|
||||
emit beginRemoveRows(QModelIndex(), 0, m_marketplace->getBasket().size() - 1);
|
||||
auto sale = std::make_unique<Sale>();
|
||||
sale->createUuid();
|
||||
sale->setSourceNo(QSettings().value("global/cashPointNo").toInt());
|
||||
marketplace_->finishCurrentSale(std::move(sale));
|
||||
m_marketplace->finishCurrentSale(std::move(sale));
|
||||
emit endRemoveRows();
|
||||
emit basketDataChanged();
|
||||
}
|
||||
|
||||
void BasketModel::cancelSale()
|
||||
{
|
||||
emit beginRemoveRows(QModelIndex(), 0, marketplace_->getBasket().size() - 1);
|
||||
marketplace_->getBasket().clear();
|
||||
emit beginRemoveRows(QModelIndex(), 0, m_marketplace->getBasket().size() - 1);
|
||||
m_marketplace->getBasket().clear();
|
||||
emit endRemoveRows();
|
||||
}
|
||||
|
||||
bool BasketModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||
{
|
||||
auto article = marketplace_->getBasket().at(row).get();
|
||||
auto article = m_marketplace->getBasket().at(row).get();
|
||||
|
||||
emit beginRemoveRows(parent, row, row + count - 1);
|
||||
marketplace_->getBasket().erase(
|
||||
std::remove_if(marketplace_->getBasket().begin(), marketplace_->getBasket().end(),
|
||||
m_marketplace->getBasket().erase(
|
||||
std::remove_if(m_marketplace->getBasket().begin(), m_marketplace->getBasket().end(),
|
||||
[&article](const auto& a) { return a->getUuid() == article->getUuid(); }),
|
||||
marketplace_->getBasket().end());
|
||||
m_marketplace->getBasket().end());
|
||||
emit endRemoveRows();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ class BasketModel : public QAbstractTableModel
|
|||
void basketDataChanged();
|
||||
|
||||
private:
|
||||
Marketplace* marketplace_;
|
||||
Marketplace* m_marketplace;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#include <QMessageBox>
|
||||
#include <QSettings>
|
||||
#include <QSharedMemory>
|
||||
#include <QTranslator>
|
||||
#include <QStyleFactory>
|
||||
#include <QTranslator>
|
||||
|
||||
#include <singleapplication.h>
|
||||
#include <stdexcept>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -20,17 +21,12 @@ int main(int argc, char* argv[])
|
|||
QCoreApplication::setOrganizationDomain("rustysoft.de");
|
||||
QCoreApplication::setApplicationName("kima2");
|
||||
|
||||
QTranslator qTranslator;
|
||||
QLocale german(QLocale::German);
|
||||
#ifdef __linux__
|
||||
qTranslator.load("qt_" + german.name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
QApplication::setStyle(QStyleFactory::create("Fusion"));
|
||||
qTranslator.load("qt_" + german.name(),
|
||||
QApplication::applicationDirPath() + QDir::separator() + "translations");
|
||||
#endif
|
||||
kimaApp.installTranslator(&qTranslator);
|
||||
QTranslator qtTranslator;
|
||||
|
||||
if (qtTranslator.load(QLocale::system(), u"qtbase"_qs, u"_"_qs,
|
||||
QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
|
||||
kimaApp.installTranslator(&qtTranslator);
|
||||
}
|
||||
|
||||
QSettings settings{};
|
||||
while (!settings.contains("global/cashPointNo")) {
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
#include "mainwindow.h"
|
||||
|
||||
#include "basketmodel.h"
|
||||
#include <config.h>
|
||||
#include "pricedialog.h"
|
||||
#include "reportdialog.h"
|
||||
#include "salemodel.h"
|
||||
#include "sellerdialog.h"
|
||||
#include "settingsdialog.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <core/csvreader.h>
|
||||
#include <core/excelreader.h>
|
||||
#include <core/jsonutil.h>
|
||||
#include <core/utils.h>
|
||||
#include <printer/posprinter.h>
|
||||
|
@ -32,10 +31,10 @@ constexpr int STATUSBAR_TIMEOUT = 5000;
|
|||
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
ui_.setupUi(this);
|
||||
m_ui.setupUi(this);
|
||||
|
||||
marketplace_ = std::make_unique<Marketplace>();
|
||||
Database::InitResult res = marketplace_->loadFromDb();
|
||||
m_marketplace = std::make_unique<Marketplace>();
|
||||
Database::InitResult res = m_marketplace->loadFromDb();
|
||||
if (res == Database::InitResult::OUTDATED_REPLACED) {
|
||||
QMessageBox(QMessageBox::Icon::Information, "Datenbankinformation",
|
||||
"Es wurde eine <b>veraltete</b> Datenbankdatei erkannt.<br />Diese wurde "
|
||||
|
@ -44,19 +43,19 @@ MainWindow::MainWindow()
|
|||
}
|
||||
statusBar()->showMessage("Gespeicherte Daten wurden geladen.", STATUSBAR_TIMEOUT);
|
||||
|
||||
BasketModel* model = new BasketModel(getMarketplace(), ui_.basketView);
|
||||
ui_.basketView->setModel(model);
|
||||
ui_.basketView->setColumnHidden(0, true); // hide the uuid
|
||||
BasketModel *model = new BasketModel(getMarketplace(), m_ui.basketView);
|
||||
m_ui.basketView->setModel(model);
|
||||
m_ui.basketView->setColumnHidden(0, true); // hide the uuid
|
||||
|
||||
setWindowTitle("KIMA2 - Kasse Nr. " + QSettings().value("global/cashPointNo").toString());
|
||||
|
||||
ui_.salesView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
m_ui.salesView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
setSaleModel();
|
||||
|
||||
connect(ui_.actionQuit, &QAction::triggered, qApp, QApplication::closeAllWindows,
|
||||
connect(m_ui.actionQuit, &QAction::triggered, qApp, QApplication::closeAllWindows,
|
||||
Qt::QueuedConnection);
|
||||
connect(ui_.newAction, &QAction::triggered, this, [=]() {
|
||||
if (marketplace_->getSellers().size() == 0 && marketplace_->getSales().size() == 0) {
|
||||
connect(m_ui.newAction, &QAction::triggered, this, [this]() {
|
||||
if (m_marketplace->getSellers().size() == 0 && m_marketplace->getSales().size() == 0) {
|
||||
return;
|
||||
}
|
||||
auto dlgResult =
|
||||
|
@ -68,46 +67,45 @@ MainWindow::MainWindow()
|
|||
if (dlgResult == QMessageBox::No)
|
||||
return;
|
||||
|
||||
delete ui_.salesView->model();
|
||||
dynamic_cast<BasketModel*>(ui_.basketView->model())->cancelSale();
|
||||
marketplace_->clear();
|
||||
delete m_ui.salesView->model();
|
||||
dynamic_cast<BasketModel *>(m_ui.basketView->model())->cancelSale();
|
||||
m_marketplace->clear();
|
||||
setSaleModel();
|
||||
updateStatLabel();
|
||||
});
|
||||
|
||||
ui_.sellerNoEdit->installEventFilter(this);
|
||||
ui_.givenSpinBox->installEventFilter(this);
|
||||
m_ui.sellerNoEdit->installEventFilter(this);
|
||||
m_ui.givenSpinBox->installEventFilter(this);
|
||||
|
||||
connect(ui_.actionEditSeller, &QAction::triggered, this,
|
||||
connect(m_ui.actionEditSeller, &QAction::triggered, this,
|
||||
&MainWindow::onActionEditSellerTriggered);
|
||||
connect(ui_.paidButton, &QPushButton::clicked, this, &MainWindow::onPaidButtonTriggered);
|
||||
connect(ui_.givenSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
|
||||
connect(m_ui.paidButton, &QPushButton::clicked, this, &MainWindow::onPaidButtonTriggered);
|
||||
connect(m_ui.givenSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
|
||||
&MainWindow::onGivenSpinBoxValueChanged);
|
||||
connect(ui_.basketView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
connect(m_ui.basketView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&MainWindow::onBasketViewSelectionChanged);
|
||||
connect(ui_.cancelArticleButton, &QPushButton::clicked, this,
|
||||
connect(m_ui.cancelArticleButton, &QPushButton::clicked, this,
|
||||
&MainWindow::onCancelArticleButtonClicked);
|
||||
connect(ui_.cancelSaleButton, &QPushButton::clicked, this,
|
||||
connect(m_ui.cancelSaleButton, &QPushButton::clicked, this,
|
||||
&MainWindow::onCancelSaleButtonClicked);
|
||||
connect(ui_.printSaleReceiptButton, &QPushButton::clicked, this,
|
||||
connect(m_ui.printSaleReceiptButton, &QPushButton::clicked, this,
|
||||
&MainWindow::onPrintSaleReceiptButtonClicked);
|
||||
connect(ui_.cancelAllArticlesButton, &QPushButton::clicked, this,
|
||||
connect(m_ui.cancelAllArticlesButton, &QPushButton::clicked, this,
|
||||
&MainWindow::onCancelAllArticlesButtonClicked);
|
||||
connect(ui_.aboutQtAction, &QAction::triggered, this, &MainWindow::onAboutQt);
|
||||
connect(ui_.aboutAction, &QAction::triggered, this, &MainWindow::onAbout);
|
||||
connect(ui_.openManualAction, &QAction::triggered, this, []() {
|
||||
auto locations = QStandardPaths::standardLocations(QStandardPaths::DataLocation);
|
||||
connect(m_ui.aboutQtAction, &QAction::triggered, this, &MainWindow::onAboutQt);
|
||||
connect(m_ui.aboutAction, &QAction::triggered, this, &MainWindow::onAbout);
|
||||
connect(m_ui.openManualAction, &QAction::triggered, this, []() {
|
||||
auto locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
|
||||
for (auto location : locations) {
|
||||
if (QFile::exists(location + QString("/Benutzerhandbuch.pdf"))) {
|
||||
QDesktopServices::openUrl(
|
||||
QUrl(QString("file:///") + location + QString("/Benutzerhandbuch.pdf"),
|
||||
QUrl::TolerantMode));
|
||||
QUrl::fromLocalFile(location + QString("/Benutzerhandbuch.pdf")));
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(ui_.licenseAction, &QAction::triggered, this, [=]() {
|
||||
connect(m_ui.licenseAction, &QAction::triggered, this, [this]() {
|
||||
QString licenseText(
|
||||
"Copyright © 2018-2021 Martin Brodbeck\n\n"
|
||||
"Copyright © 2018-2024 Martin Brodbeck\n\n"
|
||||
"Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der "
|
||||
"zugehörigen Dokumentationen (die \"Software\") erhält, die Erlaubnis erteilt, "
|
||||
"sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, "
|
||||
|
@ -126,36 +124,30 @@ MainWindow::MainWindow()
|
|||
"SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN.");
|
||||
QMessageBox::information(this, "Lizenzinformation", licenseText);
|
||||
});
|
||||
connect(ui_.reportAction, &QAction::triggered, this, [=]() {
|
||||
ReportDialog(this).exec();
|
||||
});
|
||||
connect(ui_.configAction, &QAction::triggered, this, [=]() {
|
||||
connect(m_ui.reportAction, &QAction::triggered, this, [this]() { ReportDialog(this).exec(); });
|
||||
connect(m_ui.configAction, &QAction::triggered, this, [this]() {
|
||||
int result = SettingsDialog(this).exec();
|
||||
if (result == QDialog::Accepted) {
|
||||
delete ui_.salesView->model();
|
||||
marketplace_->loadFromDb();
|
||||
delete m_ui.salesView->model();
|
||||
m_marketplace->loadFromDb();
|
||||
setSaleModel();
|
||||
}
|
||||
this->setWindowTitle("KIMA2 - Kasse Nr. " +
|
||||
QSettings().value("global/cashPointNo").toString());
|
||||
});
|
||||
connect(ui_.importSellerExcelAction, &QAction::triggered, this,
|
||||
&MainWindow::onImportSellerExcelActionTriggered);
|
||||
connect(ui_.importSellerJsonAction, &QAction::triggered, this,
|
||||
&MainWindow::onImportSellerJsonActionTriggered);
|
||||
connect(ui_.exportSellerJsonAction, &QAction::triggered, this,
|
||||
&MainWindow::onExportSellerJsonActionTriggered);
|
||||
connect(ui_.exportSalesJsonAction, &QAction::triggered, this,
|
||||
connect(m_ui.importSellerAction, &QAction::triggered, this,
|
||||
&MainWindow::onImportSellerActionTriggered);
|
||||
connect(m_ui.exportSalesJsonAction, &QAction::triggered, this,
|
||||
&MainWindow::onExportSalesJsonActionTriggered);
|
||||
connect(ui_.importSalesJsonAction, &QAction::triggered, this,
|
||||
connect(m_ui.importSalesJsonAction, &QAction::triggered, this,
|
||||
&MainWindow::onImportSalesJsonActionTriggered);
|
||||
|
||||
readGeometry();
|
||||
setWindowIcon(QIcon(":/misc/kima2.ico"));
|
||||
|
||||
updateStatLabel();
|
||||
ui_.lastPriceLabel1->setText(formatCentAsEuroString(0).c_str());
|
||||
ui_.lastPriceLabel2->setText(formatCentAsEuroString(0).c_str());
|
||||
m_ui.lastPriceLabel1->setText(formatCentAsEuroString(0).c_str());
|
||||
m_ui.lastPriceLabel2->setText(formatCentAsEuroString(0).c_str());
|
||||
}
|
||||
|
||||
void MainWindow::onActionEditSellerTriggered()
|
||||
|
@ -163,11 +155,11 @@ void MainWindow::onActionEditSellerTriggered()
|
|||
auto dialog = std::make_unique<SellerDialog>(this);
|
||||
int retCode = dialog->exec();
|
||||
|
||||
delete ui_.salesView->model();
|
||||
delete m_ui.salesView->model();
|
||||
|
||||
if (retCode == QDialog::Accepted) {
|
||||
marketplace_->sortSellers();
|
||||
marketplace_->storeToDb();
|
||||
m_marketplace->sortSellers();
|
||||
m_marketplace->storeToDb();
|
||||
statusBar()->showMessage("Änderungen an den Verkäufer-Stammdaten gespeichert.",
|
||||
STATUSBAR_TIMEOUT);
|
||||
} else {
|
||||
|
@ -181,32 +173,32 @@ void MainWindow::onActionEditSellerTriggered()
|
|||
|
||||
void MainWindow::setSaleModel()
|
||||
{
|
||||
ui_.salesView->setModel(new SaleModel(getMarketplace(), ui_.salesView));
|
||||
ui_.salesView->setColumnHidden(2, true);
|
||||
ui_.salesView->resizeColumnToContents(0);
|
||||
ui_.salesView->resizeColumnToContents(1);
|
||||
m_ui.salesView->setModel(new SaleModel(getMarketplace(), m_ui.salesView));
|
||||
m_ui.salesView->setColumnHidden(2, true);
|
||||
m_ui.salesView->resizeColumnToContents(0);
|
||||
m_ui.salesView->resizeColumnToContents(1);
|
||||
|
||||
ui_.printSaleReceiptButton->setEnabled(false);
|
||||
ui_.cancelSaleButton->setEnabled(false);
|
||||
m_ui.printSaleReceiptButton->setEnabled(false);
|
||||
m_ui.cancelSaleButton->setEnabled(false);
|
||||
|
||||
connect(static_cast<BasketModel*>(ui_.basketView->model()), &BasketModel::basketDataChanged,
|
||||
static_cast<SaleModel*>(ui_.salesView->model()), &SaleModel::onBasketDataChanged);
|
||||
connect(ui_.salesView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
connect(static_cast<BasketModel *>(m_ui.basketView->model()), &BasketModel::basketDataChanged,
|
||||
static_cast<SaleModel *>(m_ui.salesView->model()), &SaleModel::onBasketDataChanged);
|
||||
connect(m_ui.salesView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&MainWindow::onSalesViewSelectionChanged);
|
||||
}
|
||||
|
||||
void MainWindow::onPaidButtonTriggered()
|
||||
{
|
||||
if (marketplace_->basketSize() > 0) {
|
||||
QString lastPrice{marketplace_->getBasketSumAsString().c_str()};
|
||||
dynamic_cast<BasketModel*>(ui_.basketView->model())->finishSale();
|
||||
ui_.salesView->resizeColumnToContents(0);
|
||||
ui_.lastPriceLabel1->setText(lastPrice);
|
||||
ui_.lastPriceLabel2->setText(lastPrice);
|
||||
ui_.basketSumLabel->setText(formatCentAsEuroString(0).c_str());
|
||||
ui_.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
||||
ui_.drawbackContainerWidget->setEnabled(false);
|
||||
ui_.sellerNoEdit->setFocus();
|
||||
if (m_marketplace->basketSize() > 0) {
|
||||
QString lastPrice{m_marketplace->getBasketSumAsString().c_str()};
|
||||
dynamic_cast<BasketModel *>(m_ui.basketView->model())->finishSale();
|
||||
m_ui.salesView->resizeColumnToContents(0);
|
||||
m_ui.lastPriceLabel1->setText(lastPrice);
|
||||
m_ui.lastPriceLabel2->setText(lastPrice);
|
||||
m_ui.basketSumLabel->setText(formatCentAsEuroString(0).c_str());
|
||||
m_ui.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
||||
m_ui.drawbackContainerWidget->setEnabled(false);
|
||||
m_ui.sellerNoEdit->setFocus();
|
||||
statusBar()->showMessage("Verkaufsvorgang erfolgreich durchgeführt.", STATUSBAR_TIMEOUT);
|
||||
updateStatLabel();
|
||||
}
|
||||
|
@ -214,7 +206,7 @@ void MainWindow::onPaidButtonTriggered()
|
|||
|
||||
bool MainWindow::eventFilter(QObject *target, QEvent *event)
|
||||
{
|
||||
if (target == ui_.sellerNoEdit) {
|
||||
if (target == m_ui.sellerNoEdit) {
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
|
||||
|
@ -227,7 +219,7 @@ bool MainWindow::eventFilter(QObject* target, QEvent* event)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
} else if (target == ui_.givenSpinBox) {
|
||||
} else if (target == m_ui.givenSpinBox) {
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
|
||||
|
@ -236,9 +228,9 @@ bool MainWindow::eventFilter(QObject* target, QEvent* event)
|
|||
return true;
|
||||
}
|
||||
} else if (keyEvent->key() == Qt::Key::Key_Escape) {
|
||||
ui_.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
||||
ui_.drawbackContainerWidget->setEnabled(false);
|
||||
ui_.sellerNoEdit->setFocus();
|
||||
m_ui.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
||||
m_ui.drawbackContainerWidget->setEnabled(false);
|
||||
m_ui.sellerNoEdit->setFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -249,15 +241,15 @@ void MainWindow::checkSellerNo(bool ctrlPressed)
|
|||
{
|
||||
using std::regex, std::regex_match, std::smatch;
|
||||
|
||||
auto inputText = ui_.sellerNoEdit->text().toStdString();
|
||||
auto inputText = m_ui.sellerNoEdit->text().toStdString();
|
||||
|
||||
if (inputText.empty()) {
|
||||
if (ctrlPressed == false) {
|
||||
onPaidButtonTriggered();
|
||||
} else if (marketplace_->getBasket().size() > 0) {
|
||||
ui_.drawbackContainerWidget->setEnabled(true);
|
||||
ui_.givenSpinBox->setFocus();
|
||||
ui_.givenSpinBox->selectAll();
|
||||
} else if (m_marketplace->getBasket().size() > 0) {
|
||||
m_ui.drawbackContainerWidget->setEnabled(true);
|
||||
m_ui.givenSpinBox->setFocus();
|
||||
m_ui.givenSpinBox->selectAll();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -266,13 +258,13 @@ void MainWindow::checkSellerNo(bool ctrlPressed)
|
|||
smatch result;
|
||||
|
||||
if (!regex_match(inputText, result, pattern)) {
|
||||
ui_.sellerNoEdit->clear();
|
||||
m_ui.sellerNoEdit->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
int sellerNo = std::stoi(result[0]);
|
||||
|
||||
auto seller = marketplace_->findSellerWithSellerNo(sellerNo);
|
||||
auto seller = m_marketplace->findSellerWithSellerNo(sellerNo);
|
||||
if (seller) {
|
||||
PriceDialog priceDialog(this);
|
||||
if (sellerNo == 0) {
|
||||
|
@ -282,30 +274,30 @@ void MainWindow::checkSellerNo(bool ctrlPressed)
|
|||
if (dialogResult == QDialog::Accepted) {
|
||||
int price = priceDialog.getPrice();
|
||||
std::string desc = priceDialog.getDescription();
|
||||
dynamic_cast<BasketModel*>(ui_.basketView->model())->addArticle(seller, price, desc);
|
||||
ui_.basketView->resizeColumnToContents(1);
|
||||
ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str());
|
||||
dynamic_cast<BasketModel *>(m_ui.basketView->model())->addArticle(seller, price, desc);
|
||||
m_ui.basketView->resizeColumnToContents(1);
|
||||
m_ui.basketSumLabel->setText(m_marketplace->getBasketSumAsString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
ui_.sellerNoEdit->clear();
|
||||
m_ui.sellerNoEdit->clear();
|
||||
}
|
||||
|
||||
void MainWindow::onGivenSpinBoxValueChanged(double value)
|
||||
{
|
||||
int givenInCent = std::round(value * 100);
|
||||
int basketSumInCent = marketplace_->getBasketSumInCent();
|
||||
int basketSumInCent = m_marketplace->getBasketSumInCent();
|
||||
int drawback = givenInCent - basketSumInCent;
|
||||
ui_.drawbackLabel->setText(formatCentAsEuroString(drawback).c_str());
|
||||
m_ui.drawbackLabel->setText(formatCentAsEuroString(drawback).c_str());
|
||||
}
|
||||
|
||||
void MainWindow::onBasketViewSelectionChanged(const QItemSelection &selected,
|
||||
[[maybe_unused]] const QItemSelection &deselected)
|
||||
{
|
||||
if (selected.size() > 0) {
|
||||
ui_.cancelArticleButton->setEnabled(true);
|
||||
m_ui.cancelArticleButton->setEnabled(true);
|
||||
} else {
|
||||
ui_.cancelArticleButton->setEnabled(false);
|
||||
m_ui.cancelArticleButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,21 +305,21 @@ void MainWindow::onSalesViewSelectionChanged(const QItemSelection& selected,
|
|||
[[maybe_unused]] const QItemSelection &deselected)
|
||||
{
|
||||
if (selected.size() > 0) {
|
||||
ui_.cancelSaleButton->setEnabled(true);
|
||||
m_ui.cancelSaleButton->setEnabled(true);
|
||||
if (!selected.indexes()[0].parent().isValid())
|
||||
ui_.printSaleReceiptButton->setEnabled(true);
|
||||
m_ui.printSaleReceiptButton->setEnabled(true);
|
||||
else
|
||||
ui_.printSaleReceiptButton->setEnabled(false);
|
||||
m_ui.printSaleReceiptButton->setEnabled(false);
|
||||
|
||||
} else {
|
||||
ui_.cancelSaleButton->setEnabled(false);
|
||||
ui_.printSaleReceiptButton->setEnabled(false);
|
||||
m_ui.cancelSaleButton->setEnabled(false);
|
||||
m_ui.printSaleReceiptButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
|
||||
{
|
||||
auto selModel = ui_.basketView->selectionModel();
|
||||
auto selModel = m_ui.basketView->selectionModel();
|
||||
if (selModel->hasSelection() == false)
|
||||
return;
|
||||
|
||||
|
@ -344,16 +336,17 @@ void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
|
|||
|
||||
// Deleting the rows, beginning with the last one!
|
||||
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
||||
ui_.basketView->model()->removeRow(iter->row());
|
||||
m_ui.basketView->model()->removeRow(iter->row());
|
||||
}
|
||||
|
||||
ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str()); // Update basket sum
|
||||
ui_.sellerNoEdit->setFocus();
|
||||
m_ui.basketSumLabel->setText(
|
||||
m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
|
||||
m_ui.sellerNoEdit->setFocus();
|
||||
}
|
||||
|
||||
void MainWindow::onCancelSaleButtonClicked([[maybe_unused]] bool checked)
|
||||
{
|
||||
auto selModel = ui_.salesView->selectionModel();
|
||||
auto selModel = m_ui.salesView->selectionModel();
|
||||
if (selModel->hasSelection() == false)
|
||||
return;
|
||||
|
||||
|
@ -370,25 +363,25 @@ void MainWindow::onCancelSaleButtonClicked([[maybe_unused]] bool checked)
|
|||
|
||||
// Deleting the rows, beginning with the last one!
|
||||
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
||||
ui_.salesView->model()->removeRow(iter->row(), iter->parent());
|
||||
m_ui.salesView->model()->removeRow(iter->row(), iter->parent());
|
||||
}
|
||||
|
||||
ui_.salesView->collapseAll();
|
||||
m_ui.salesView->collapseAll();
|
||||
|
||||
QString lastPriceValue(formatCentAsEuroString(0).c_str());
|
||||
if (ui_.salesView->model()->rowCount() > 0) {
|
||||
if (m_ui.salesView->model()->rowCount() > 0) {
|
||||
lastPriceValue =
|
||||
ui_.salesView->model()->data(ui_.salesView->model()->index(0, 1)).toString();
|
||||
m_ui.salesView->model()->data(m_ui.salesView->model()->index(0, 1)).toString();
|
||||
}
|
||||
ui_.lastPriceLabel1->setText(lastPriceValue);
|
||||
ui_.lastPriceLabel2->setText(lastPriceValue);
|
||||
m_ui.lastPriceLabel1->setText(lastPriceValue);
|
||||
m_ui.lastPriceLabel2->setText(lastPriceValue);
|
||||
|
||||
updateStatLabel();
|
||||
}
|
||||
|
||||
void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
|
||||
{
|
||||
auto selModel = ui_.salesView->selectionModel();
|
||||
auto selModel = m_ui.salesView->selectionModel();
|
||||
if (selModel->hasSelection() == false)
|
||||
return;
|
||||
|
||||
|
@ -397,7 +390,7 @@ void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
|
|||
QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString();
|
||||
|
||||
auto indexes = selModel->selectedRows();
|
||||
auto& sale = marketplace_->getSales().at(indexes[0].row());
|
||||
auto &sale = m_marketplace->getSales().at(indexes[0].row());
|
||||
|
||||
auto printerDevice =
|
||||
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
|
||||
|
@ -417,7 +410,7 @@ void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
|
|||
|
||||
void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked)
|
||||
{
|
||||
if (ui_.basketView->model()->rowCount() == 0)
|
||||
if (m_ui.basketView->model()->rowCount() == 0)
|
||||
return;
|
||||
|
||||
auto dlgResult =
|
||||
|
@ -428,15 +421,14 @@ void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked)
|
|||
if (dlgResult == QMessageBox::No)
|
||||
return;
|
||||
|
||||
dynamic_cast<BasketModel*>(ui_.basketView->model())->cancelSale();
|
||||
dynamic_cast<BasketModel *>(m_ui.basketView->model())->cancelSale();
|
||||
|
||||
ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str()); // Update basket sum
|
||||
ui_.sellerNoEdit->setFocus();
|
||||
m_ui.basketSumLabel->setText(
|
||||
m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
|
||||
m_ui.sellerNoEdit->setFocus();
|
||||
}
|
||||
|
||||
void MainWindow::onAboutQt() {
|
||||
QMessageBox::aboutQt(this);
|
||||
}
|
||||
void MainWindow::onAboutQt() { QMessageBox::aboutQt(this); }
|
||||
|
||||
void MainWindow::onAbout()
|
||||
{
|
||||
|
@ -449,9 +441,9 @@ void MainWindow::onAbout()
|
|||
">info@rustysoft.de</a>></p>");
|
||||
}
|
||||
|
||||
void MainWindow::onImportSellerExcelActionTriggered()
|
||||
void MainWindow::onImportSellerActionTriggered()
|
||||
{
|
||||
if (!marketplace_->getSales().empty()) {
|
||||
if (!m_marketplace->getSales().empty()) {
|
||||
QMessageBox(QMessageBox::Icon::Information, "Import nicht möglich",
|
||||
"Der Import ist nicht möglich, da schon Verkäufe getätigt wurden.",
|
||||
QMessageBox::StandardButton::Ok, this)
|
||||
|
@ -459,9 +451,9 @@ void MainWindow::onImportSellerExcelActionTriggered()
|
|||
return;
|
||||
}
|
||||
|
||||
auto filename = QFileDialog::getOpenFileName(
|
||||
this, "Verkäufer importieren", QString(),
|
||||
"Alle unterstützte Dateien (*.xlsx *.csv);;Excel Dateien (*.xlsx);;CSV Dateien (*.csv)");
|
||||
auto filename =
|
||||
QFileDialog::getOpenFileName(this, "Verkäufer importieren", QString(),
|
||||
"Alle unterstützte Dateien (*.csv);;CSV Dateien (*.csv)");
|
||||
|
||||
if (filename.isEmpty())
|
||||
return;
|
||||
|
@ -473,85 +465,19 @@ void MainWindow::onImportSellerExcelActionTriggered()
|
|||
#endif
|
||||
|
||||
std::size_t numImported{};
|
||||
if (case_insensitive_match(filePath.extension().string(), std::string(".xlsx"))) {
|
||||
try {
|
||||
numImported = ExcelReader::readSellersFromFile(filePath, marketplace_.get());
|
||||
} catch (const std::exception& e) {
|
||||
QMessageBox(QMessageBox::Icon::Critical, "Fehler beim Importieren",
|
||||
"Beim Import aus der Excel-Datei ist ein Fehler aufgetreten. "
|
||||
"Sie könnten ggf. versuchen, die Daten aus einer .csv Datei zu imporieren.",
|
||||
QMessageBox::StandardButton::Ok, this).exec();
|
||||
std::cerr << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
numImported = CsvReader::readSellersFromFile(filePath, marketplace_.get());
|
||||
}
|
||||
numImported = CsvReader::readSellersFromFile(filePath, m_marketplace.get());
|
||||
|
||||
updateStatLabel();
|
||||
|
||||
using namespace std::string_literals;
|
||||
std::ostringstream msg;
|
||||
msg << "Aus der Excel/CSV-Datei wurden <b>"s << std::to_string(numImported)
|
||||
msg << "Aus der CSV-Datei wurden <b>"s << std::to_string(numImported)
|
||||
<< "</b> Verkäufer importiert.";
|
||||
QMessageBox(QMessageBox::Icon::Information, "Verkäufer erfolgreich importiert",
|
||||
msg.str().c_str(), QMessageBox::StandardButton::Ok, this)
|
||||
.exec();
|
||||
}
|
||||
|
||||
void MainWindow::onImportSellerJsonActionTriggered()
|
||||
{
|
||||
if (!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()
|
||||
{
|
||||
QSettings settings;
|
||||
|
@ -570,7 +496,7 @@ void MainWindow::onExportSalesJsonActionTriggered()
|
|||
fs::path filePath(filename.toStdString());
|
||||
#endif
|
||||
|
||||
JsonUtil::exportSales(filePath, marketplace_.get(),
|
||||
JsonUtil::exportSales(filePath, m_marketplace.get(),
|
||||
settings.value("global/cashPointNo").toInt());
|
||||
}
|
||||
|
||||
|
@ -578,27 +504,30 @@ void MainWindow::onImportSalesJsonActionTriggered()
|
|||
{
|
||||
QSettings settings;
|
||||
|
||||
auto filename = QFileDialog::getOpenFileName(this, "Umsätze/Transaktionen importieren",
|
||||
auto filenames = QFileDialog::getOpenFileNames(this, "Umsätze/Transaktionen importieren",
|
||||
QString(), "JSON Dateien (*.json)");
|
||||
|
||||
if (filename.isEmpty())
|
||||
if (filenames.isEmpty())
|
||||
return;
|
||||
|
||||
for(auto filename: filenames) {
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
fs::path filePath(filename.toStdWString());
|
||||
#else
|
||||
fs::path filePath(filename.toStdString());
|
||||
#endif
|
||||
|
||||
delete ui_.salesView->model();
|
||||
delete m_ui.salesView->model();
|
||||
try {
|
||||
JsonUtil::importSales(filePath, marketplace_.get(),
|
||||
JsonUtil::importSales(filePath, m_marketplace.get(),
|
||||
settings.value("global/cashPointNo").toInt());
|
||||
} catch (std::runtime_error &err) {
|
||||
QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok,
|
||||
this)
|
||||
.exec();
|
||||
}
|
||||
}
|
||||
|
||||
setSaleModel();
|
||||
updateStatLabel();
|
||||
}
|
||||
|
@ -633,9 +562,9 @@ void MainWindow::updateStatLabel()
|
|||
{
|
||||
std::string statistics("<b>KIMA2 - Version ");
|
||||
statistics += PROJECT_VERSION;
|
||||
statistics += "</b><br />Verkäufer: " + std::to_string(marketplace_->getSellers().size() - 1);
|
||||
statistics += "<br />Kunden: " + std::to_string(marketplace_->getSales().size());
|
||||
statistics += "<br />Umsatz: " + marketplace_->getOverallSumAsString();
|
||||
statistics += "</b><br />Verkäufer: " + std::to_string(m_marketplace->getSellers().size() - 1);
|
||||
statistics += "<br />Kunden: " + std::to_string(m_marketplace->getSales().size());
|
||||
statistics += "<br />Umsatz: " + m_marketplace->getOverallSumAsString();
|
||||
|
||||
ui_.statLabel->setText(statistics.c_str());
|
||||
m_ui.statLabel->setText(statistics.c_str());
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class MainWindow : public QMainWindow
|
|||
|
||||
public:
|
||||
MainWindow();
|
||||
Marketplace* getMarketplace() { return marketplace_.get(); }
|
||||
Marketplace* getMarketplace() { return m_marketplace.get(); }
|
||||
|
||||
private slots:
|
||||
void onBasketViewSelectionChanged(const QItemSelection& selected,
|
||||
|
@ -39,9 +39,7 @@ class MainWindow : public QMainWindow
|
|||
void checkSellerNo(bool ctrlPressed = false);
|
||||
void onPaidButtonTriggered();
|
||||
void onGivenSpinBoxValueChanged(double value);
|
||||
void onImportSellerExcelActionTriggered();
|
||||
void onImportSellerJsonActionTriggered();
|
||||
void onExportSellerJsonActionTriggered();
|
||||
void onImportSellerActionTriggered();
|
||||
void onExportSalesJsonActionTriggered();
|
||||
void onImportSalesJsonActionTriggered();
|
||||
void setSaleModel();
|
||||
|
@ -49,8 +47,8 @@ class MainWindow : public QMainWindow
|
|||
void readGeometry();
|
||||
void updateStatLabel();
|
||||
|
||||
Ui::MainWindow ui_;
|
||||
std::unique_ptr<Marketplace> marketplace_;
|
||||
Ui::MainWindow m_ui;
|
||||
std::unique_ptr<Marketplace> m_marketplace;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -423,7 +423,7 @@ drucken</string>
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>817</width>
|
||||
<height>30</height>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_Datei">
|
||||
|
@ -440,16 +440,8 @@ drucken</string>
|
|||
<property name="title">
|
||||
<string>&Verkäufer</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="importSellerMenu">
|
||||
<property name="title">
|
||||
<string>Importieren</string>
|
||||
</property>
|
||||
<addaction name="importSellerExcelAction"/>
|
||||
<addaction name="importSellerJsonAction"/>
|
||||
</widget>
|
||||
<addaction name="actionEditSeller"/>
|
||||
<addaction name="importSellerMenu"/>
|
||||
<addaction name="exportSellerJsonAction"/>
|
||||
<addaction name="importSellerAction"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuHilfe">
|
||||
<property name="title">
|
||||
|
@ -513,9 +505,9 @@ drucken</string>
|
|||
<string>Exportieren für andere Kasse (JSON)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="importSellerExcelAction">
|
||||
<action name="importSellerActionX">
|
||||
<property name="text">
|
||||
<string>Aus Excel/CSV-Datei (initial)</string>
|
||||
<string>Aus CSV-Datei (initial)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="importSellerJsonAction">
|
||||
|
@ -548,6 +540,11 @@ drucken</string>
|
|||
<string>Lizenz</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="importSellerAction">
|
||||
<property name="text">
|
||||
<string>Importieren (aus CSV-Datei)</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
@ -6,31 +6,31 @@
|
|||
|
||||
PriceDialog::PriceDialog(QWidget* parent, bool forceDesc, Qt::WindowFlags f) : QDialog(parent, f)
|
||||
{
|
||||
forceDesc_ = forceDesc;
|
||||
ui_.setupUi(this);
|
||||
ui_.priceSpinBox->setFocus();
|
||||
m_forceDesc = forceDesc;
|
||||
m_ui.setupUi(this);
|
||||
m_ui.priceSpinBox->setFocus();
|
||||
}
|
||||
|
||||
int PriceDialog::getPrice() const { return static_cast<int>(ui_.priceSpinBox->value() * 100); }
|
||||
int PriceDialog::getPrice() const { return static_cast<int>(m_ui.priceSpinBox->value() * 100); }
|
||||
|
||||
std::string PriceDialog::getDescription() const { return ui_.descEdit->text().toStdString(); }
|
||||
std::string PriceDialog::getDescription() const { return m_ui.descEdit->text().toStdString(); }
|
||||
|
||||
void PriceDialog::accept()
|
||||
{
|
||||
if (static_cast<int>(std::round(ui_.priceSpinBox->value() * 100.0L)) % 50 != 0) {
|
||||
if (static_cast<int>(std::round(m_ui.priceSpinBox->value() * 100.0L)) % 50 != 0) {
|
||||
QMessageBox(QMessageBox::Icon::Warning, "Falsche Preiseingabe",
|
||||
"Es sind nur 0,50 Cent-Schritte erlaubt.", QMessageBox::StandardButton::Ok,
|
||||
this)
|
||||
.exec();
|
||||
} else if (forceDesc_ && ui_.descEdit->text().trimmed().isEmpty()) {
|
||||
} else if (m_forceDesc && m_ui.descEdit->text().trimmed().isEmpty()) {
|
||||
QMessageBox(QMessageBox::Icon::Warning, "Artikelbeschreibung fehlt",
|
||||
"Da Sie auf das Sonderkonto buchen ist eine Artikelbeschreibung erforderlich.",
|
||||
QMessageBox::StandardButton::Ok, this)
|
||||
.exec();
|
||||
ui_.descEdit->setFocus();
|
||||
m_ui.descEdit->setFocus();
|
||||
} else {
|
||||
QDialog::accept();
|
||||
}
|
||||
}
|
||||
|
||||
void PriceDialog::setForceDesc(bool force) { forceDesc_ = force; }
|
||||
void PriceDialog::setForceDesc(bool force) { m_forceDesc = force; }
|
|
@ -19,8 +19,8 @@ class PriceDialog : public QDialog
|
|||
private:
|
||||
void on_model_duplicateSellerNo(const QString& message);
|
||||
virtual void accept() override;
|
||||
Ui::PriceDialog ui_;
|
||||
bool forceDesc_;
|
||||
Ui::PriceDialog m_ui;
|
||||
bool m_forceDesc;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -19,20 +19,20 @@ namespace fs = std::filesystem;
|
|||
|
||||
ReportDialog::ReportDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f)
|
||||
{
|
||||
ui_.setupUi(this);
|
||||
market_ = dynamic_cast<MainWindow*>(parent)->getMarketplace();
|
||||
model_ = std::make_unique<ReportModel>(market_, ui_.reportView);
|
||||
ui_.reportView->setModel(model_.get());
|
||||
ui_.reportView->hideColumn(0);
|
||||
ui_.reportView->setRowHidden(0, true); // hide the special "Sonderkonto" user
|
||||
m_ui.setupUi(this);
|
||||
m_market = dynamic_cast<MainWindow *>(parent)->getMarketplace();
|
||||
m_model = std::make_unique<ReportModel>(m_market, m_ui.reportView);
|
||||
m_ui.reportView->setModel(m_model.get());
|
||||
m_ui.reportView->hideColumn(0);
|
||||
m_ui.reportView->setRowHidden(0, true); // hide the special "Sonderkonto" user
|
||||
|
||||
connect(ui_.exportCsvButton, &QPushButton::clicked, this,
|
||||
connect(m_ui.exportCsvButton, &QPushButton::clicked, this,
|
||||
&ReportDialog::onExportCsvButtonClicked);
|
||||
connect(ui_.printReportButton, &QPushButton::clicked, this,
|
||||
connect(m_ui.printReportButton, &QPushButton::clicked, this,
|
||||
&ReportDialog::onPrintReportButtonClicked);
|
||||
connect(ui_.printSellerReceiptButton, &QPushButton::clicked, this,
|
||||
connect(m_ui.printSellerReceiptButton, &QPushButton::clicked, this,
|
||||
&ReportDialog::onPrintSellerReceiptButtonClicked);
|
||||
connect(ui_.reportView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
connect(m_ui.reportView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&ReportDialog::onReportViewSelectionChanged);
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ void ReportDialog::onExportCsvButtonClicked()
|
|||
fs::path filePath(filename.toStdString());
|
||||
#endif
|
||||
|
||||
market_->exportReportToCSV(filePath, feeInPercent, maxFeeInEuro);
|
||||
m_market->exportReportToCSV(filePath, feeInPercent, maxFeeInEuro);
|
||||
}
|
||||
|
||||
void ReportDialog::onPrintReportButtonClicked()
|
||||
|
@ -75,8 +75,8 @@ void ReportDialog::onPrintReportButtonClicked()
|
|||
QPainter painter;
|
||||
int height = printer.height();
|
||||
int width = printer.width();
|
||||
const double ENTRIES_PER_PAGE = 51;
|
||||
const auto& sellers = market_->getSellers();
|
||||
const double ENTRIES_PER_PAGE = 45;
|
||||
const auto &sellers = m_market->getSellers();
|
||||
unsigned int numPages = std::ceil(sellers.size() / ENTRIES_PER_PAGE);
|
||||
|
||||
painter.begin(&printer);
|
||||
|
@ -126,7 +126,7 @@ void ReportDialog::onPrintReportButtonClicked()
|
|||
}
|
||||
|
||||
// pieces booked on the special account "Sonderkonto"
|
||||
const auto specialSeller = market_->findSellerWithSellerNo(0);
|
||||
const auto specialSeller = m_market->findSellerWithSellerNo(0);
|
||||
if (specialSeller && specialSeller->numArticlesSold() > 0) {
|
||||
printer.newPage();
|
||||
painter.setFont(QFont("Arial", 16, QFont::Bold));
|
||||
|
@ -163,8 +163,8 @@ void ReportDialog::onPrintReportButtonClicked()
|
|||
"Auswertung Kindersachenmarkt");
|
||||
painter.setFont(fixedFont);
|
||||
QString content("Gesamtstatistik\n===============\n\n");
|
||||
int numArticlesOffered = market_->getNumArticlesOffered();
|
||||
int numArticlesSold = market_->getNumArticlesSold();
|
||||
int numArticlesOffered = m_market->getNumArticlesOffered();
|
||||
int numArticlesSold = m_market->getNumArticlesSold();
|
||||
double percentArticlesSold =
|
||||
(static_cast<double>(numArticlesSold) / static_cast<double>(numArticlesOffered)) * 100;
|
||||
content += QString("Registrierte Verkäufer: %1\n").arg(sellers.size() - 1, 6);
|
||||
|
@ -172,14 +172,14 @@ void ReportDialog::onPrintReportButtonClicked()
|
|||
content += QString("Verkaufte Artikel: %1 (%L2 %)\n")
|
||||
.arg(numArticlesSold, 6)
|
||||
.arg(percentArticlesSold, 0, 'f', 2);
|
||||
content += QString("Anzahl Kunden: %1\n\n").arg(market_->getSales().size(), 6);
|
||||
content += QString("Gesamtumsatz: %1\n").arg(market_->getOverallSumAsString().c_str(), 10);
|
||||
content += QString("Anzahl Kunden: %1\n\n").arg(m_market->getSales().size(), 6);
|
||||
content += QString("Gesamtumsatz: %1\n").arg(m_market->getOverallSumAsString().c_str(), 10);
|
||||
content +=
|
||||
QString("Ausgezahlt: %1\n")
|
||||
.arg(market_->getOverallPaymentAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10);
|
||||
.arg(m_market->getOverallPaymentAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10);
|
||||
content +=
|
||||
QString("Verbleibend: %1\n\n")
|
||||
.arg(market_->getOverallRevenueAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10);
|
||||
.arg(m_market->getOverallRevenueAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10);
|
||||
content += QString("(Einbehaltener Prozentsatz: %1 %)\n").arg(feeInPercent, 3);
|
||||
content += QString("(Maximal einbehaltener Betrag: %1 €)\n").arg(maxFeeInEuro, 3);
|
||||
|
||||
|
@ -196,12 +196,12 @@ void ReportDialog::onPrintSellerReceiptButtonClicked()
|
|||
QString posPrinterDevice = settings.value("global/posPrinterDevice", "").toString();
|
||||
QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString();
|
||||
|
||||
auto selModel = ui_.reportView->selectionModel();
|
||||
auto selModel = m_ui.reportView->selectionModel();
|
||||
if (selModel->hasSelection() == false)
|
||||
return;
|
||||
|
||||
auto indexes = selModel->selectedRows();
|
||||
auto& seller = market_->getSellers().at(indexes[0].row());
|
||||
auto &seller = m_market->getSellers().at(indexes[0].row());
|
||||
|
||||
auto printerDevice =
|
||||
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
|
||||
|
@ -224,8 +224,8 @@ void ReportDialog::onReportViewSelectionChanged(const QItemSelection& selected,
|
|||
[[maybe_unused]] const QItemSelection &deselected)
|
||||
{
|
||||
if (selected.size() > 0) {
|
||||
ui_.printSellerReceiptButton->setEnabled(true);
|
||||
m_ui.printSellerReceiptButton->setEnabled(true);
|
||||
} else {
|
||||
ui_.printSellerReceiptButton->setEnabled(false);
|
||||
m_ui.printSellerReceiptButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,9 @@ class ReportDialog : public QDialog
|
|||
const QItemSelection& deselected);
|
||||
|
||||
private:
|
||||
Ui::ReportDialog ui_;
|
||||
Marketplace* market_;
|
||||
std::unique_ptr<ReportModel> model_;
|
||||
Ui::ReportDialog m_ui;
|
||||
Marketplace* m_market;
|
||||
std::unique_ptr<ReportModel> m_model;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
#include <QSettings>
|
||||
|
||||
ReportModel::ReportModel(Marketplace* market, QObject* parent)
|
||||
: QAbstractTableModel(parent), market_(market)
|
||||
: QAbstractTableModel(parent), m_market(market)
|
||||
{
|
||||
QSettings settings;
|
||||
feeInPercent_ = settings.value("global/feeInPercent").toInt();
|
||||
maxFeeInCent_ = settings.value("global/maxFeeInEuro").toInt() * 100;
|
||||
m_feeInPercent = settings.value("global/feeInPercent").toInt();
|
||||
m_maxFeeInCent = settings.value("global/maxFeeInEuro").toInt() * 100;
|
||||
}
|
||||
|
||||
int ReportModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
|
||||
{
|
||||
return static_cast<int>(market_->getSellers().size());
|
||||
return static_cast<int>(m_market->getSellers().size());
|
||||
}
|
||||
|
||||
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)
|
||||
return QVariant();
|
||||
|
||||
if (market_->getSellers().size() == 0)
|
||||
if (m_market->getSellers().size() == 0)
|
||||
return QVariant();
|
||||
|
||||
Seller* seller = market_->getSellers().at(index.row()).get();
|
||||
Seller* seller = m_market->getSellers().at(index.row()).get();
|
||||
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
|
@ -71,7 +71,7 @@ QVariant ReportModel::data(const QModelIndex& index, int role) const
|
|||
case 5:
|
||||
return seller->sumAsString().c_str();
|
||||
case 6:
|
||||
return paymentAsString(seller->sumInCents(), feeInPercent_, maxFeeInCent_).c_str();
|
||||
return paymentAsString(seller->sumInCents(), m_feeInPercent, m_maxFeeInCent).c_str();
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ class ReportModel : public QAbstractTableModel
|
|||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
private:
|
||||
Marketplace* market_;
|
||||
int feeInPercent_{};
|
||||
int maxFeeInCent_{};
|
||||
Marketplace* m_market;
|
||||
int m_feeInPercent{};
|
||||
int m_maxFeeInCent{};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
SaleModel::SaleModel(Marketplace* market, QObject* parent) : QAbstractItemModel(parent)
|
||||
{
|
||||
marketplace_ = market;
|
||||
m_marketplace = market;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (!parent.isValid()) {
|
||||
Sale* sale = marketplace_->getSales().at(row).get();
|
||||
Sale* sale = m_marketplace->getSales().at(row).get();
|
||||
return createIndex(row, column, sale);
|
||||
} else if (!parent.parent().isValid()) {
|
||||
Sale* sale = static_cast<Sale*>(parent.internalPointer());
|
||||
|
@ -49,10 +49,10 @@ QModelIndex SaleModel::parent(const QModelIndex& index) const
|
|||
sale = dynamic_cast<Sale*>(ent);
|
||||
|
||||
if (sale) {
|
||||
if (sale == rootItem.get())
|
||||
if (sale == m_rootItem.get())
|
||||
return QModelIndex();
|
||||
else {
|
||||
return createIndex(-1, 0, rootItem.get());
|
||||
return createIndex(-1, 0, m_rootItem.get());
|
||||
}
|
||||
} else {
|
||||
article = dynamic_cast<Article*>(ent);
|
||||
|
@ -132,7 +132,7 @@ int SaleModel::rowCount(const QModelIndex& parent) const
|
|||
return 0;
|
||||
|
||||
if (!parent.isValid()) {
|
||||
return marketplace_->getSales().size();
|
||||
return m_marketplace->getSales().size();
|
||||
} else if (!parent.parent().isValid()) {
|
||||
Sale* sale = static_cast<Sale*>(parent.internalPointer());
|
||||
return sale->getArticles().size();
|
||||
|
@ -167,7 +167,7 @@ QVariant SaleModel::headerData(int section, Qt::Orientation orientation, int rol
|
|||
void SaleModel::onBasketDataChanged()
|
||||
{
|
||||
emit beginResetModel();
|
||||
auto& sales = marketplace_->getSales();
|
||||
auto& sales = m_marketplace->getSales();
|
||||
std::sort(sales.begin(), sales.end(), [](const auto& lhs, const auto& rhs) {
|
||||
return lhs->getTimestamp() > rhs->getTimestamp();
|
||||
});
|
||||
|
@ -179,11 +179,11 @@ bool SaleModel::removeRows(int row, int count, const QModelIndex& parent)
|
|||
if (!parent.isValid()) {
|
||||
// remove complete sale
|
||||
emit beginRemoveRows(parent, row, row + count - 1);
|
||||
auto& sale = marketplace_->getSales().at(row);
|
||||
auto& sale = m_marketplace->getSales().at(row);
|
||||
sale->setState(Sale::State::DELETE);
|
||||
std::for_each(sale->getArticles().begin(), sale->getArticles().end(),
|
||||
[](auto& a) { a->setState(Article::State::DELETE); });
|
||||
marketplace_->storeToDb();
|
||||
m_marketplace->storeToDb();
|
||||
emit endRemoveRows();
|
||||
|
||||
} else if (!parent.parent().isValid()) {
|
||||
|
@ -199,7 +199,7 @@ bool SaleModel::removeRows(int row, int count, const QModelIndex& parent)
|
|||
sale->setState(Sale::State::DELETE);
|
||||
}
|
||||
emit beginRemoveRows(parent.parent(), 0, 0);
|
||||
marketplace_->storeToDb();
|
||||
m_marketplace->storeToDb();
|
||||
emit endRemoveRows();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ class SaleModel : public QAbstractItemModel
|
|||
void onBasketDataChanged();
|
||||
|
||||
private:
|
||||
Marketplace* marketplace_;
|
||||
std::unique_ptr<Sale> rootItem{new Sale()};
|
||||
Marketplace* m_marketplace;
|
||||
std::unique_ptr<Sale> m_rootItem{new Sale()};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,25 +7,25 @@
|
|||
|
||||
SellerDialog::SellerDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f)
|
||||
{
|
||||
ui_.setupUi(this);
|
||||
ui_.editButton->setVisible(false);
|
||||
market_ = dynamic_cast<MainWindow*>(parent)->getMarketplace();
|
||||
model_ = std::make_unique<SellerModel>(market_, ui_.tableView);
|
||||
ui_.tableView->setModel(model_.get());
|
||||
ui_.tableView->setColumnHidden(0, true); // hide the uuid
|
||||
ui_.tableView->setRowHidden(0, true); // hide the special "Sonderkonto" user
|
||||
connect(ui_.newButton, &QPushButton::clicked, this, &SellerDialog::on_newButton_clicked);
|
||||
connect(ui_.deleteButton, &QPushButton::clicked, this, &SellerDialog::on_deleteButton_clicked);
|
||||
connect(model_.get(), &SellerModel::duplicateSellerNo, this,
|
||||
m_ui.setupUi(this);
|
||||
m_ui.editButton->setVisible(false);
|
||||
m_market = dynamic_cast<MainWindow*>(parent)->getMarketplace();
|
||||
m_model = std::make_unique<SellerModel>(m_market, m_ui.tableView);
|
||||
m_ui.tableView->setModel(m_model.get());
|
||||
m_ui.tableView->setColumnHidden(0, true); // hide the uuid
|
||||
m_ui.tableView->setRowHidden(0, true); // hide the special "Sonderkonto" user
|
||||
connect(m_ui.newButton, &QPushButton::clicked, this, &SellerDialog::on_newButton_clicked);
|
||||
connect(m_ui.deleteButton, &QPushButton::clicked, this, &SellerDialog::on_deleteButton_clicked);
|
||||
connect(m_model.get(), &SellerModel::duplicateSellerNo, this,
|
||||
&SellerDialog::on_model_duplicateSellerNo);
|
||||
connect(ui_.tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
connect(m_ui.tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&SellerDialog::onSellerViewSelectionChanged);
|
||||
}
|
||||
|
||||
void SellerDialog::on_newButton_clicked()
|
||||
{
|
||||
// Don't allow new seller if market has already started
|
||||
if (market_->getSales().size() > 0) {
|
||||
if (m_market->getSales().size() > 0) {
|
||||
QMessageBox(QMessageBox::Icon::Warning, "Hinweis",
|
||||
"Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) "
|
||||
"können Sie keine Verkäufer mehr hinzufügen.",
|
||||
|
@ -34,22 +34,22 @@ void SellerDialog::on_newButton_clicked()
|
|||
return;
|
||||
}
|
||||
|
||||
ui_.tableView->reset();
|
||||
ui_.tableView->model()->insertRows(ui_.tableView->model()->rowCount(), 1);
|
||||
ui_.tableView->scrollToBottom();
|
||||
ui_.tableView->selectRow(ui_.tableView->model()->rowCount() - 1);
|
||||
QModelIndex idx = ui_.tableView->model()->index(ui_.tableView->model()->rowCount() - 1, 2);
|
||||
ui_.tableView->setCurrentIndex(idx);
|
||||
ui_.tableView->edit(idx);
|
||||
m_ui.tableView->reset();
|
||||
m_ui.tableView->model()->insertRows(m_ui.tableView->model()->rowCount(), 1);
|
||||
m_ui.tableView->scrollToBottom();
|
||||
m_ui.tableView->selectRow(m_ui.tableView->model()->rowCount() - 1);
|
||||
QModelIndex idx = m_ui.tableView->model()->index(m_ui.tableView->model()->rowCount() - 1, 2);
|
||||
m_ui.tableView->setCurrentIndex(idx);
|
||||
m_ui.tableView->edit(idx);
|
||||
}
|
||||
|
||||
void SellerDialog::on_deleteButton_clicked()
|
||||
{
|
||||
auto selModel = ui_.tableView->selectionModel();
|
||||
auto selModel = m_ui.tableView->selectionModel();
|
||||
if (selModel->hasSelection() == false)
|
||||
return;
|
||||
|
||||
if (market_->getSales().size() > 0) {
|
||||
if (m_market->getSales().size() > 0) {
|
||||
QMessageBox(QMessageBox::Icon::Warning, "Hinweis",
|
||||
"Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) "
|
||||
"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!
|
||||
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
||||
ui_.tableView->model()->removeRow(iter->row());
|
||||
m_ui.tableView->model()->removeRow(iter->row());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,8 +102,8 @@ void SellerDialog::onSellerViewSelectionChanged(const QItemSelection& selected,
|
|||
[[maybe_unused]] const QItemSelection& deselected)
|
||||
{
|
||||
if (selected.size() > 0) {
|
||||
ui_.deleteButton->setEnabled(true);
|
||||
m_ui.deleteButton->setEnabled(true);
|
||||
} else {
|
||||
ui_.deleteButton->setEnabled(false);
|
||||
m_ui.deleteButton->setEnabled(false);
|
||||
}
|
||||
}
|
|
@ -26,9 +26,9 @@ class SellerDialog : public QDialog
|
|||
void on_deleteButton_clicked();
|
||||
void on_model_duplicateSellerNo(const QString& message);
|
||||
virtual void accept() override;
|
||||
Ui::SellerDialog ui_;
|
||||
Marketplace* market_;
|
||||
std::unique_ptr<SellerModel> model_;
|
||||
Ui::SellerDialog m_ui;
|
||||
Marketplace* m_market;
|
||||
std::unique_ptr<SellerModel> m_model;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,13 +5,13 @@
|
|||
#include <QMessageBox>
|
||||
|
||||
SellerModel::SellerModel(Marketplace* market, QObject* parent)
|
||||
: QAbstractTableModel(parent), marketplace_(market)
|
||||
: QAbstractTableModel(parent), m_marketplace(market)
|
||||
{
|
||||
}
|
||||
|
||||
int SellerModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
|
||||
{
|
||||
return marketplace_->getSellers().size();
|
||||
return m_marketplace->getSellers().size();
|
||||
}
|
||||
|
||||
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)
|
||||
return QVariant();
|
||||
|
||||
if (marketplace_->getSellers().size() == 0)
|
||||
if (m_marketplace->getSellers().size() == 0)
|
||||
return QVariant();
|
||||
|
||||
Seller* seller = marketplace_->getSellers().at(index.row()).get();
|
||||
Seller* seller = m_marketplace->getSellers().at(index.row()).get();
|
||||
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
|
@ -78,7 +78,7 @@ bool SellerModel::setData(const QModelIndex& index, const QVariant& value, int r
|
|||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
|
||||
Seller* seller = marketplace_->getSellers().at(index.row()).get();
|
||||
Seller* seller = m_marketplace->getSellers().at(index.row()).get();
|
||||
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
|
@ -88,11 +88,11 @@ bool SellerModel::setData(const QModelIndex& index, const QVariant& value, int r
|
|||
if (value.toInt() < 0)
|
||||
return false;
|
||||
auto iter =
|
||||
std::find_if(marketplace_->getSellers().begin(), marketplace_->getSellers().end(),
|
||||
std::find_if(m_marketplace->getSellers().begin(), m_marketplace->getSellers().end(),
|
||||
[&value](const std::unique_ptr<Seller>& s) {
|
||||
return value.toInt() == s->getSellerNo();
|
||||
});
|
||||
if (iter != marketplace_->getSellers().end()) {
|
||||
if (iter != m_marketplace->getSellers().end()) {
|
||||
emit duplicateSellerNo(
|
||||
"Die Verkäufernummer muss eindeutig sein.\n(Möglicherweise wird die Nummer von "
|
||||
"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);
|
||||
auto seller = std::make_unique<Seller>();
|
||||
seller->setSellerNo(marketplace_->getNextSellerNo());
|
||||
marketplace_->getSellers().push_back(std::move(seller));
|
||||
seller->setSellerNo(m_marketplace->getNextSellerNo());
|
||||
m_marketplace->getSellers().push_back(std::move(seller));
|
||||
emit endInsertRows();
|
||||
|
||||
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)
|
||||
{
|
||||
auto seller = marketplace_->getSellers().at(row).get();
|
||||
auto seller = m_marketplace->getSellers().at(row).get();
|
||||
if (seller->getState() == Seller::State::NEW) {
|
||||
emit beginRemoveRows(parent, row, row + count - 1);
|
||||
marketplace_->getSellers().erase(
|
||||
std::remove_if(marketplace_->getSellers().begin(), marketplace_->getSellers().end(),
|
||||
m_marketplace->getSellers().erase(
|
||||
std::remove_if(m_marketplace->getSellers().begin(), m_marketplace->getSellers().end(),
|
||||
[&seller](const std::unique_ptr<Seller>& a) {
|
||||
return a->getId() == seller->getId();
|
||||
}),
|
||||
marketplace_->getSellers().end());
|
||||
m_marketplace->getSellers().end());
|
||||
emit endRemoveRows();
|
||||
return true;
|
||||
} else {
|
||||
emit beginRemoveRows(parent, row, row + count - 1);
|
||||
seller->setState(Seller::State::DELETE);
|
||||
marketplace_->storeToDb(true);
|
||||
m_marketplace->storeToDb(true);
|
||||
emit endRemoveRows();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class SellerModel : public QAbstractTableModel
|
|||
void duplicateSellerNo(const QString &message);
|
||||
|
||||
private:
|
||||
Marketplace* marketplace_;
|
||||
Marketplace *m_marketplace;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
#include "mainwindow.h"
|
||||
|
||||
#include <core/database.h>
|
||||
#include <core/utils.h>
|
||||
#include <printer/posprinter.h>
|
||||
#include <printer/utils.h>
|
||||
#include <core/utils.h>
|
||||
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
@ -15,7 +15,7 @@
|
|||
|
||||
SettingsDialog::SettingsDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f)
|
||||
{
|
||||
ui_.setupUi(this);
|
||||
m_ui.setupUi(this);
|
||||
|
||||
QSettings settings{};
|
||||
int cashPointNo = settings.value("global/cashPointNo").toInt();
|
||||
|
@ -26,25 +26,25 @@ SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(par
|
|||
int maxFeeInEuro = settings.value("global/maxFeeInEuro").toInt();
|
||||
|
||||
if (parent)
|
||||
market_ = dynamic_cast<MainWindow*>(parent)->getMarketplace();
|
||||
m_market = dynamic_cast<MainWindow *>(parent)->getMarketplace();
|
||||
|
||||
ui_.cashPointNoSpinBox->setValue(cashPointNo);
|
||||
ui_.communeEdit->setText(commune);
|
||||
ui_.posPrinterDeviceEdit->setText(posPrinterDevice);
|
||||
ui_.posPrinterEndpointEdit->setText(posPrinterEndpoint);
|
||||
ui_.feePercentSpinBox->setValue(feeInPercent);
|
||||
ui_.maxFeeSpinBox->setValue(maxFeeInEuro);
|
||||
m_ui.cashPointNoSpinBox->setValue(cashPointNo);
|
||||
m_ui.communeEdit->setText(commune);
|
||||
m_ui.posPrinterDeviceEdit->setText(posPrinterDevice);
|
||||
m_ui.posPrinterEndpointEdit->setText(posPrinterEndpoint);
|
||||
m_ui.feePercentSpinBox->setValue(feeInPercent);
|
||||
m_ui.maxFeeSpinBox->setValue(maxFeeInEuro);
|
||||
|
||||
connect(ui_.testPosPrinterButton, &QPushButton::clicked, this, [=]() {
|
||||
connect(m_ui.testPosPrinterButton, &QPushButton::clicked, this, [this]() {
|
||||
using namespace std::string_literals;
|
||||
try {
|
||||
if (ui_.posPrinterDeviceEdit->text().isEmpty()) {
|
||||
if (m_ui.posPrinterDeviceEdit->text().isEmpty()) {
|
||||
PosPrinter printer;
|
||||
printer.printTest();
|
||||
} else {
|
||||
std::string posPrinterDeviceString = ui_.posPrinterDeviceEdit->text().toStdString();
|
||||
std::string posPrinterDeviceString = m_ui.posPrinterDeviceEdit->text().toStdString();
|
||||
std::string posPrinterEndpointString =
|
||||
ui_.posPrinterEndpointEdit->text().toStdString();
|
||||
m_ui.posPrinterEndpointEdit->text().toStdString();
|
||||
|
||||
try {
|
||||
auto printerDevice =
|
||||
|
@ -80,17 +80,17 @@ void SettingsDialog::accept()
|
|||
QSettings settings;
|
||||
|
||||
int oldCashPointNo = settings.value("global/cashPointNo").toInt();
|
||||
int newCashPointNo = ui_.cashPointNoSpinBox->value();
|
||||
int newCashPointNo = m_ui.cashPointNoSpinBox->value();
|
||||
|
||||
settings.setValue("global/commune", ui_.communeEdit->text().trimmed());
|
||||
settings.setValue("global/posPrinterDevice", ui_.posPrinterDeviceEdit->text().trimmed());
|
||||
settings.setValue("global/posPrinterEndpoint", ui_.posPrinterEndpointEdit->text().trimmed());
|
||||
settings.setValue("global/feeInPercent", ui_.feePercentSpinBox->value());
|
||||
settings.setValue("global/maxFeeInEuro", ui_.maxFeeSpinBox->value());
|
||||
settings.setValue("global/commune", m_ui.communeEdit->text().trimmed());
|
||||
settings.setValue("global/posPrinterDevice", m_ui.posPrinterDeviceEdit->text().trimmed());
|
||||
settings.setValue("global/posPrinterEndpoint", m_ui.posPrinterEndpointEdit->text().trimmed());
|
||||
settings.setValue("global/feeInPercent", m_ui.feePercentSpinBox->value());
|
||||
settings.setValue("global/maxFeeInEuro", m_ui.maxFeeSpinBox->value());
|
||||
|
||||
if (oldCashPointNo != newCashPointNo) {
|
||||
int result{0};
|
||||
if (market_ && market_->getSales().size() > 0) {
|
||||
if (m_market && m_market->getSales().size() > 0) {
|
||||
result = QMessageBox(QMessageBox::Icon::Question, "Sind Sie sicher?",
|
||||
"Möchten Sie die Kassen-Nr wirklich ändern? Diese muss über alle "
|
||||
"Installationen hinweg eindeutig sein.",
|
||||
|
@ -112,7 +112,7 @@ void SettingsDialog::accept()
|
|||
QDialog::accept();
|
||||
return;
|
||||
}
|
||||
settings.setValue("global/cashPointNo", ui_.cashPointNoSpinBox->value());
|
||||
settings.setValue("global/cashPointNo", m_ui.cashPointNoSpinBox->value());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ class SettingsDialog : public QDialog
|
|||
void accept() override;
|
||||
|
||||
private:
|
||||
Ui::SettingsDialog ui_;
|
||||
Marketplace* market_{};
|
||||
Ui::SettingsDialog m_ui;
|
||||
Marketplace* m_market{};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
set(Boost_USE_STATIC_LIBS ON)
|
||||
|
||||
find_package(Boost 1.62 REQUIRED)
|
||||
find_package(Boost 1.78 REQUIRED)
|
||||
|
||||
if(WIN32)
|
||||
find_package(LIBUSB REQUIRED)
|
||||
|
@ -20,4 +20,4 @@ if(WIN32)
|
|||
else()
|
||||
target_link_libraries(printer core ${LibUSB_LIBRARIES})
|
||||
endif()
|
||||
target_include_directories(printer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
target_include_directories(printer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/.. ${Boost_INCLUDE_DIRS})
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit ea547fdb16c7baf99bd9ced5febba52cc5da3ca3
|
|
@ -1 +1 @@
|
|||
Subproject commit db78ac1d7716f56fc9f1b030b715f872f93964e4
|
||||
Subproject commit 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03
|
|
@ -1 +1 @@
|
|||
Subproject commit 3d152b03d872b99d7f36e8463ac253e41194a17a
|
||||
Subproject commit 8c48163c4d3fbba603cfe8a5b94046c9dad71825
|
Loading…
Reference in New Issue