Compare commits
191 commits
Author | SHA1 | Date | |
---|---|---|---|
8a5038e462 | |||
068a50e289 | |||
da89a0d2c7 | |||
429d66dd4d | |||
37c8446ea4 | |||
a896e0d40e | |||
3668e2484f | |||
52dc7f1974 | |||
ab7b14f12e | |||
0c7f071b9d | |||
d0c50c9b9a | |||
a17cb22e05 | |||
205dac5326 | |||
b0d2d6b284 | |||
7f11ba4e5d | |||
32d0ec7749 | |||
54e5c70447 | |||
379fd4a73c | |||
8a94b53379 | |||
d9b13d0e1a | |||
6f885dd64e | |||
1a698a6cd2 | |||
ac9ae8b34e | |||
4385624988 | |||
4cfd8d5572 | |||
528ae1ff31 | |||
649c26db4b | |||
13a1d26d96 | |||
f898844c7c | |||
e6b71a7e4d | |||
f4b4ccbbea | |||
e79a81797c | |||
8efdf7b6fe | |||
a46e8d89c9 | |||
3e293ba447 | |||
245e41bbf0 | |||
b0444112a8 | |||
c4ccd43b45 | |||
16745a248c | |||
19ea7f27de | |||
42bf036f85 | |||
9d7492c745 | |||
9fcfb8e3ba | |||
a23de4dcf0 | |||
77f45fa55f | |||
7299ae7c66 | |||
1720dbba8b | |||
66e2e69c3e | |||
78aafab63b | |||
72e1a69dae | |||
7e38da7276 | |||
144f61d6d4 | |||
85574ff08a | |||
c44d8b352a | |||
be9a7be38d | |||
104464f781 | |||
3a132e69ae | |||
01577d02a0 | |||
ecd1111391 | |||
944edc277a | |||
0427bd4077 | |||
2b6628bdf8 | |||
6944051c31 | |||
5f7d91a18e | |||
2b7c099f5e | |||
acc3095e60 | |||
d677dfd628 | |||
e0ffd47430 | |||
3e6e587df8 | |||
21571215bc | |||
52e0f1636e | |||
38b8865cea | |||
20c7a99578 | |||
3572d22715 | |||
453fd8cdb5 | |||
911b05b487 | |||
9e511c684d | |||
b9bb9f1a8c | |||
329c3a1540 | |||
8feb122c11 | |||
d573aed916 | |||
83b6cd1d26 | |||
059ae5ca66 | |||
edf9cb1a2c | |||
b8b5d8b140 | |||
072af76de1 | |||
92ecc92bf7 | |||
e48fbe82e0 | |||
8ef821dcc0 | |||
c65e7be415 | |||
b9f09fcd4c | |||
a156c5331a | |||
9e6e2eb936 | |||
8b299bacc3 | |||
eb5434f374 | |||
a547b6f3c3 | |||
26804ba03e | |||
305d41f2e1 | |||
8374175087 | |||
01bf3c29a2 | |||
ff9dc9b05e | |||
e41ce5a117 | |||
2d06de9907 | |||
77791e142c | |||
a8181729f9 | |||
5aa4e3a5f0 | |||
77226f294b | |||
03f1c7cca5 | |||
b9d4375f5a | |||
f37cd75502 | |||
b016452a06 | |||
7ca04f79ce | |||
e987692c7a | |||
d13f9d2824 | |||
2faa2fa019 | |||
fc308c644c | |||
e89728846c | |||
ad895abd35 | |||
ec0b7cbf0d | |||
9fd29d588f | |||
710b4cf9fb | |||
98fdffe5fb | |||
847e8aa8ba | |||
9e2d377195 | |||
acc8408b0a | |||
99104a932f | |||
f0ec980e8d | |||
4f9151d85b | |||
df972f68fc | |||
57bfe3af62 | |||
a33b9896b3 | |||
63f9822f34 | |||
69982fc931 | |||
46d6468e5c | |||
dd23da5f72 | |||
c171a6350d | |||
bc5c63fe0d | |||
106846a127 | |||
04c553e657 | |||
2a5cf16998 | |||
857f706443 | |||
1a82a4147b | |||
ddb06c73a8 | |||
0b369e1c8e | |||
52cff89735 | |||
fe9c69b88a | |||
3d52357480 | |||
75fb3753e1 | |||
8ff8cbd6d2 | |||
44a736fd79 | |||
ffdece92b4 | |||
8265212c11 | |||
780e37f565 | |||
79f1065868 | |||
b9d502dcde | |||
6702459b0d | |||
083767bfd4 | |||
6b25c7c9cf | |||
fb98c3786e | |||
dc2b31a5f9 | |||
1ea26f1e6c | |||
43b5ec1fc0 | |||
07b734521b | |||
9b7f5568d7 | |||
e8ce908a7f | |||
4621274c4e | |||
080ac45f5b | |||
2c243a6563 | |||
d2680c52af | |||
7a2e8c6fc3 | |||
8e3ad5dc53 | |||
193cb0d8ce | |||
ecc45811d8 | |||
5a3b6fff82 | |||
b9ec6f983e | |||
d3e56e629d | |||
1797a860d1 | |||
96c89da080 | |||
abe570e28c | |||
b2dc79207d | |||
e97cbf1287 | |||
cfdb319c14 | |||
e5c66463c3 | |||
32da117468 | |||
2fb42d5365 | |||
45fe7ea8bd | |||
65f5da45ec | |||
f32f0afd6a | |||
838525942e | |||
7a8c7a9d0b | |||
6c51f8cec5 |
78 changed files with 1471 additions and 998 deletions
101
.clang-format
101
.clang-format
|
@ -1,27 +1,38 @@
|
||||||
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
# BasedOnStyle: LLVM
|
# BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -2
|
AccessModifierOffset: -4
|
||||||
AlignAfterOpenBracket: Align
|
AlignAfterOpenBracket: Align
|
||||||
AlignConsecutiveAssignments: false
|
AlignArrayOfStructures: None
|
||||||
AlignConsecutiveDeclarations: false
|
AlignConsecutiveMacros: None
|
||||||
|
AlignConsecutiveAssignments: None
|
||||||
|
AlignConsecutiveBitFields: None
|
||||||
|
AlignConsecutiveDeclarations: None
|
||||||
AlignEscapedNewlines: Right
|
AlignEscapedNewlines: Right
|
||||||
AlignOperands: true
|
AlignOperands: Align
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
AllowShortBlocksOnASingleLine: false
|
AllowShortEnumsOnASingleLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
AllowShortFunctionsOnASingleLine: All
|
AllowShortFunctionsOnASingleLine: All
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakAfterReturnType: None
|
AlwaysBreakAfterReturnType: None
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
AlwaysBreakTemplateDeclarations: false
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
BinPackArguments: true
|
BinPackArguments: true
|
||||||
BinPackParameters: true
|
BinPackParameters: true
|
||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
AfterClass: true
|
AfterCaseLabel: false
|
||||||
AfterControlStatement: false
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
AfterEnum: false
|
AfterEnum: false
|
||||||
AfterFunction: false
|
AfterFunction: false
|
||||||
AfterNamespace: false
|
AfterNamespace: false
|
||||||
|
@ -31,13 +42,21 @@ BraceWrapping:
|
||||||
AfterExternBlock: false
|
AfterExternBlock: false
|
||||||
BeforeCatch: false
|
BeforeCatch: false
|
||||||
BeforeElse: false
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
IndentBraces: false
|
IndentBraces: false
|
||||||
SplitEmptyFunction: true
|
SplitEmptyFunction: true
|
||||||
SplitEmptyRecord: true
|
SplitEmptyRecord: true
|
||||||
SplitEmptyNamespace: true
|
SplitEmptyNamespace: true
|
||||||
BreakBeforeBinaryOperators: None
|
BreakBeforeBinaryOperators: None
|
||||||
BreakBeforeBraces: Linux
|
BreakBeforeConceptDeclarations: true
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
BreakBeforeInheritanceComma: false
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: true
|
||||||
BreakConstructorInitializersBeforeComma: false
|
BreakConstructorInitializersBeforeComma: false
|
||||||
BreakConstructorInitializers: BeforeColon
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
@ -50,35 +69,56 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
Cpp11BracedListStyle: true
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
DisableFormat: false
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
ExperimentalAutoDetectBinPacking: false
|
ExperimentalAutoDetectBinPacking: false
|
||||||
FixNamespaceComments: true
|
FixNamespaceComments: true
|
||||||
ForEachMacros:
|
ForEachMacros:
|
||||||
- foreach
|
- foreach
|
||||||
- Q_FOREACH
|
- Q_FOREACH
|
||||||
- BOOST_FOREACH
|
- BOOST_FOREACH
|
||||||
|
IfMacros:
|
||||||
|
- KJ_IF_MAYBE
|
||||||
IncludeBlocks: Preserve
|
IncludeBlocks: Preserve
|
||||||
IncludeCategories:
|
IncludeCategories:
|
||||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
Priority: 2
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
Priority: 3
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
- Regex: '.*'
|
- Regex: '.*'
|
||||||
Priority: 1
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
IncludeIsMainRegex: '(Test)?$'
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentAccessModifiers: false
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentGotoLabels: true
|
||||||
IndentPPDirectives: None
|
IndentPPDirectives: None
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentRequires: false
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertTrailingCommas: None
|
||||||
JavaScriptQuotes: Leave
|
JavaScriptQuotes: Leave
|
||||||
JavaScriptWrapImports: true
|
JavaScriptWrapImports: true
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
MacroBlockBegin: ''
|
MacroBlockBegin: ''
|
||||||
MacroBlockEnd: ''
|
MacroBlockEnd: ''
|
||||||
MaxEmptyLinesToKeep: 1
|
MaxEmptyLinesToKeep: 1
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
ObjCBlockIndentWidth: 2
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
ObjCSpaceAfterProperty: false
|
ObjCSpaceAfterProperty: false
|
||||||
ObjCSpaceBeforeProtocolList: true
|
ObjCSpaceBeforeProtocolList: true
|
||||||
PenaltyBreakAssignment: 2
|
PenaltyBreakAssignment: 2
|
||||||
|
@ -86,24 +126,57 @@ PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
PenaltyBreakComment: 300
|
PenaltyBreakComment: 300
|
||||||
PenaltyBreakFirstLessLess: 120
|
PenaltyBreakFirstLessLess: 120
|
||||||
PenaltyBreakString: 1000
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
PenaltyExcessCharacter: 1000000
|
PenaltyExcessCharacter: 1000000
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
PointerAlignment: Left
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PointerAlignment: Right
|
||||||
|
PPIndentWidth: -1
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
SortIncludes: true
|
ShortNamespaceLines: 1
|
||||||
|
SortIncludes: CaseSensitive
|
||||||
|
SortJavaStaticImport: Before
|
||||||
SortUsingDeclarations: true
|
SortUsingDeclarations: true
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
SpaceAfterTemplateKeyword: true
|
SpaceAfterTemplateKeyword: true
|
||||||
SpaceBeforeAssignmentOperators: true
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
SpaceInEmptyParentheses: false
|
SpaceInEmptyParentheses: false
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
SpacesInAngles: false
|
SpacesInAngles: Never
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
SpacesInContainerLiterals: true
|
SpacesInContainerLiterals: true
|
||||||
SpacesInCStyleCastParentheses: false
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
Standard: Auto
|
SpaceBeforeSquareBrackets: false
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
Standard: Latest
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
|
UseCRLF: false
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- STRINGIZE
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
...
|
||||||
|
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1 +1,4 @@
|
||||||
build
|
build
|
||||||
|
.vscode/ipch/*
|
||||||
|
.kdev4
|
||||||
|
.cache
|
7
.gitmodules
vendored
7
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
||||||
[submodule "3rdparty/nlohmann_json"]
|
[submodule "subprojects/nlohmann_json"]
|
||||||
path = 3rdparty/nlohmann_json
|
path = subprojects/nlohmann_json
|
||||||
url = https://github.com/nlohmann/json.git
|
url = https://github.com/nlohmann/json.git
|
||||||
|
[submodule "subprojects/singleapplication"]
|
||||||
|
path = subprojects/singleapplication/singleapplication.git
|
||||||
|
url = https://github.com/itay-grudev/SingleApplication.git
|
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
|
@ -21,7 +21,8 @@
|
||||||
"text": "-enable-pretty-printing",
|
"text": "-enable-pretty-printing",
|
||||||
"ignoreFailures": true
|
"ignoreFailures": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"visualizerFile": "/home/brodbemn/.config/Code - OSS/User/workspaceStorage/d64ec049841ecb3d43e402bb3c167cb5/tonka3000.qtvsctools/qt.natvis.xml"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
42
.vscode/settings.json
vendored
42
.vscode/settings.json
vendored
|
@ -65,9 +65,47 @@
|
||||||
"condition_variable": "cpp",
|
"condition_variable": "cpp",
|
||||||
"mutex": "cpp",
|
"mutex": "cpp",
|
||||||
"hash_map": "cpp",
|
"hash_map": "cpp",
|
||||||
"future": "cpp"
|
"future": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"forward_list": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"semaphore": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"__bit_reference": "cpp",
|
||||||
|
"__bits": "cpp",
|
||||||
|
"__config": "cpp",
|
||||||
|
"__debug": "cpp",
|
||||||
|
"__errc": "cpp",
|
||||||
|
"__hash_table": "cpp",
|
||||||
|
"__locale": "cpp",
|
||||||
|
"__mutex_base": "cpp",
|
||||||
|
"__node_handle": "cpp",
|
||||||
|
"__split_buffer": "cpp",
|
||||||
|
"__threading_support": "cpp",
|
||||||
|
"__tree": "cpp",
|
||||||
|
"__tuple": "cpp",
|
||||||
|
"__verbose_abort": "cpp",
|
||||||
|
"format": "cpp",
|
||||||
|
"ios": "cpp",
|
||||||
|
"locale": "cpp"
|
||||||
},
|
},
|
||||||
"C_Cpp.clang_format_path": "/usr/bin/clang-format",
|
"C_Cpp.clang_format_path": "/usr/bin/clang-format",
|
||||||
"cmake.configureOnOpen": true,
|
"cmake.configureOnOpen": true,
|
||||||
"C_Cpp.configurationWarnings": "Disabled"
|
"C_Cpp.configurationWarnings": "Disabled",
|
||||||
|
"files.watcherExclude": {
|
||||||
|
"**/.git/objects/**": true,
|
||||||
|
"**/.git/subtree-cache/**": true,
|
||||||
|
"**/node_modules/*/**": true,
|
||||||
|
"**/.hg/store/**": true,
|
||||||
|
".flatpak/**": true,
|
||||||
|
"_build/**": true
|
||||||
|
}
|
||||||
}
|
}
|
1
3rdparty/nlohmann_json
vendored
1
3rdparty/nlohmann_json
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit f1768a540a7b7c5cc30cdcd6be9e9ef91083719b
|
|
|
@ -1,10 +1,10 @@
|
||||||
cmake_minimum_required(VERSION 3.8)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
project(kima2 VERSION 0.13.1)
|
project(kima2 VERSION 1.8.3)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_HOME_DIRECTORY}/cmake" ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH "${CMAKE_HOME_DIRECTORY}/cmake")
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
#include(InstallRequiredSystemLibraries)
|
#include(InstallRequiredSystemLibraries)
|
||||||
|
@ -12,10 +12,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
add_compile_options(/W4 /WX)
|
add_compile_options(/W4 /WX)
|
||||||
else()
|
else()
|
||||||
add_compile_options(-Wall -Wextra -pedantic -Woverloaded-virtual -Wredundant-decls -Wshadow)
|
#add_compile_options(-Wall -Wextra -pedantic -Woverloaded-virtual -Wredundant-decls -Wshadow)
|
||||||
|
add_compile_options(-Wall -Wextra)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
configure_file(config.h.in ${PROJECT_BINARY_DIR}/config.h)
|
configure_file(config.h.in ${PROJECT_BINARY_DIR}/config.h)
|
||||||
|
configure_file(de.rustysoft.kima2.metainfo.xml.in ${PROJECT_BINARY_DIR}/de.rustysoft.kima2.metainfo.xml)
|
||||||
|
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
@ -27,14 +29,14 @@ if(KIMA2_USE_EXTERNAL_JSON)
|
||||||
find_package(nlohmann_json REQUIRED)
|
find_package(nlohmann_json REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(3rdparty)
|
add_subdirectory(subprojects)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE MATCHES Debug)
|
#if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
include(CTest)
|
# include(CTest)
|
||||||
enable_testing()
|
# enable_testing()
|
||||||
add_subdirectory(test)
|
# add_subdirectory(test)
|
||||||
endif()
|
#endif()
|
||||||
|
|
||||||
|
|
||||||
# CPack
|
# CPack
|
||||||
|
@ -78,6 +80,8 @@ else(WIN32 AND NOT UNIX)
|
||||||
DESTINATION share/${PROJECT_NAME})
|
DESTINATION share/${PROJECT_NAME})
|
||||||
install(FILES "${CMAKE_SOURCE_DIR}/misc/kima2.svg"
|
install(FILES "${CMAKE_SOURCE_DIR}/misc/kima2.svg"
|
||||||
DESTINATION share/icons/hicolor/scalable/apps)
|
DESTINATION share/icons/hicolor/scalable/apps)
|
||||||
|
install(FILES de.rustysoft.kima2.metainfo.xml
|
||||||
|
DESTINATION share/metainfo)
|
||||||
endif (WIN32 AND NOT UNIX)
|
endif (WIN32 AND NOT UNIX)
|
||||||
|
|
||||||
if( MINGW )
|
if( MINGW )
|
||||||
|
@ -86,18 +90,19 @@ if( MINGW )
|
||||||
set( CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
|
set( CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
|
||||||
${MINGW_PATH}/libstdc++-6.dll
|
${MINGW_PATH}/libstdc++-6.dll
|
||||||
${MINGW_PATH}/libgcc_s_seh-1.dll
|
${MINGW_PATH}/libgcc_s_seh-1.dll
|
||||||
${MINGW_PATH}/Qt5Core.dll
|
${MINGW_PATH}/Qt6Core.dll
|
||||||
${MINGW_PATH}/Qt5Gui.dll
|
${MINGW_PATH}/Qt6Gui.dll
|
||||||
${MINGW_PATH}/Qt5Widgets.dll
|
${MINGW_PATH}/Qt6Widgets.dll
|
||||||
${MINGW_PATH}/Qt5PrintSupport.dll
|
${MINGW_PATH}/Qt6PrintSupport.dll
|
||||||
|
${MINGW_PATH}/Qt6Network.dll
|
||||||
${MINGW_PATH}/libwinpthread-1.dll
|
${MINGW_PATH}/libwinpthread-1.dll
|
||||||
${MINGW_PATH}/libsqlite3-0.dll
|
${MINGW_PATH}/libsqlite3-0.dll
|
||||||
${MINGW_PATH}/libusb-1.0.dll
|
${MINGW_PATH}/libusb-1.0.dll
|
||||||
${MINGW_PATH}/libxlnt.dll
|
${MINGW_PATH}/libicuuc75.dll
|
||||||
${MINGW_PATH}/libicuuc62.dll
|
${MINGW_PATH}/libicuin75.dll
|
||||||
${MINGW_PATH}/libicuin62.dll
|
${MINGW_PATH}/libicudt75.dll
|
||||||
${MINGW_PATH}/libicudt62.dll
|
|
||||||
${MINGW_PATH}/libpcre2-16-0.dll
|
${MINGW_PATH}/libpcre2-16-0.dll
|
||||||
|
${MINGW_PATH}/libpcre2-8-0.dll
|
||||||
${MINGW_PATH}/zlib1.dll
|
${MINGW_PATH}/zlib1.dll
|
||||||
${MINGW_PATH}/libharfbuzz-0.dll
|
${MINGW_PATH}/libharfbuzz-0.dll
|
||||||
${MINGW_PATH}/libpng16-16.dll
|
${MINGW_PATH}/libpng16-16.dll
|
||||||
|
@ -107,20 +112,26 @@ if( MINGW )
|
||||||
${MINGW_PATH}/libbz2-1.dll
|
${MINGW_PATH}/libbz2-1.dll
|
||||||
${MINGW_PATH}/libintl-8.dll
|
${MINGW_PATH}/libintl-8.dll
|
||||||
${MINGW_PATH}/libpcre-1.dll
|
${MINGW_PATH}/libpcre-1.dll
|
||||||
|
${MINGW_PATH}/libdouble-conversion.dll
|
||||||
|
${MINGW_PATH}/libzstd.dll
|
||||||
|
${MINGW_PATH}/libmd4c.dll
|
||||||
|
${MINGW_PATH}/libbrotlicommon.dll
|
||||||
|
${MINGW_PATH}/libbrotlidec.dll
|
||||||
|
#${MINGW_PATH}/libfmt.dll
|
||||||
|
${MINGW_PATH}/libb2-1.dll
|
||||||
${MINGW_PATH}/libiconv-2.dll)
|
${MINGW_PATH}/libiconv-2.dll)
|
||||||
install(FILES ${MINGW_PATH}/../share/qt5/plugins/platforms/qwindows.dll
|
install(FILES ${MINGW_PATH}/../share/qt6/plugins/platforms/qwindows.dll
|
||||||
${MINGW_PATH}/../share/qt5/plugins/platforms/qminimal.dll
|
${MINGW_PATH}/../share/qt6/plugins/platforms/qminimal.dll
|
||||||
DESTINATION bin/platforms)
|
DESTINATION bin/platforms)
|
||||||
install(FILES ${MINGW_PATH}/../share/qt5/plugins/printsupport/windowsprintersupport.dll
|
#install(FILES ${MINGW_PATH}/../share/qt6/plugins/printsupport/windowsprintersupport.dll
|
||||||
DESTINATION bin/printsupport)
|
# DESTINATION bin/printsupport)
|
||||||
install(FILES ${MINGW_PATH}/../share/qt5/translations/qtbase_de.qm
|
install(FILES ${MINGW_PATH}/../share/qt6/translations/qtbase_de.qm
|
||||||
${MINGW_PATH}/../share/qt5/translations/qt_de.qm
|
${MINGW_PATH}/../share/qt6/translations/qt_de.qm
|
||||||
${MINGW_PATH}/../share/qt5/translations/qt_help_de.qm
|
${MINGW_PATH}/../share/qt6/translations/qt_help_de.qm
|
||||||
${MINGW_PATH}/../share/qt5/translations/qtmultimedia_de.qm
|
${MINGW_PATH}/../share/qt6/translations/qtmultimedia_de.qm
|
||||||
${MINGW_PATH}/../share/qt5/translations/qtquick1_de.qm
|
DESTINATION bin/share/qt6/translations)
|
||||||
${MINGW_PATH}/../share/qt5/translations/qtscript_de.qm
|
install(FILES ${MINGW_PATH}/../share/qt6/plugins/styles/qmodernwindowsstyle.dll
|
||||||
${MINGW_PATH}/../share/qt5/translations/qtxmlpatterns_de.qm
|
DESTINATION bin/styles)
|
||||||
DESTINATION bin/translations)
|
|
||||||
endif( MINGW )
|
endif( MINGW )
|
||||||
|
|
||||||
include(InstallRequiredSystemLibraries)
|
include(InstallRequiredSystemLibraries)
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright © 2018 Martin Brodbeck
|
Copyright © 2018-2024 Martin Brodbeck
|
||||||
|
|
||||||
Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der
|
Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der
|
||||||
zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt,
|
zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt,
|
||||||
|
|
13
README.md
13
README.md
|
@ -13,19 +13,16 @@ Verkaufsdaten nach dem Verkaufsende auszutauschen.
|
||||||
Ebenso können über einen ESC/POS-Drucker Quittungen ausgestellt werden.
|
Ebenso können über einen ESC/POS-Drucker Quittungen ausgestellt werden.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Auf [rustysoft.de](https://www.rustysoft.de/?01_kima2) werden verschiedene Installationspakete (Arch Linux,
|
Auf [rustysoft.de](https://www.rustysoft.de/software/kima2/) werden die Installationsmöglichkeiten (Flatpak, Windows-Installer) erläutert. Bitte die Hinweise dort beachten.
|
||||||
Ubuntu, Windows) angeboten. Bitte die Hinweise dort beachten.
|
|
||||||
|
|
||||||
### Selbst compilieren
|
## Selbst compilieren
|
||||||
KIMA2 benötigt folgende Libraries:
|
KIMA2 benötigt folgende Libraries:
|
||||||
* Qt5
|
* Qt 6
|
||||||
* boost >= 1.62
|
* boost >= 1.80
|
||||||
* libusb-1.0
|
* libusb-1.0
|
||||||
* xlnt >= 1.3.0
|
|
||||||
* nlohmann-json (als 3rdparty submodule vorhanden)
|
* nlohmann-json (als 3rdparty submodule vorhanden)
|
||||||
|
|
||||||
Da Features aus C++17 verwendet werden sowie std::filesystem, sollte als Compiler mindestens
|
Da Features aus C++20 sowie von neueren Compilern verwendet werden, sollte als Compiler mindestens GCC 14 verwendet werden.
|
||||||
GCC 8 verwendet werden.
|
|
||||||
|
|
||||||
Die Installationsschritte unter Linux sind wie folgt:
|
Die Installationsschritte unter Linux sind wie folgt:
|
||||||
```
|
```
|
||||||
|
|
27
de.rustysoft.kima2.metainfo.xml.in
Normal file
27
de.rustysoft.kima2.metainfo.xml.in
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<component type="desktop-application">
|
||||||
|
<id>de.rustysoft.kima2</id>
|
||||||
|
|
||||||
|
<name>KIMA2</name>
|
||||||
|
<summary>A small cash point program for 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>
|
4
kima2.kdev4
Normal file
4
kima2.kdev4
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[Project]
|
||||||
|
CreatedFrom=CMakeLists.txt
|
||||||
|
Manager=KDevCMakeManager
|
||||||
|
Name=kima2
|
Binary file not shown.
Binary file not shown.
33
meson.build
Normal file
33
meson.build
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
project('kima2', 'cpp', default_options : ['cpp_std=c++20'], version : '1.8.0')
|
||||||
|
|
||||||
|
conf_data = configuration_data()
|
||||||
|
conf_data.set('PROJECT_VERSION', '"' + meson.project_version() + '"')
|
||||||
|
configure_file(output : 'config.h',
|
||||||
|
configuration : conf_data)
|
||||||
|
configuration_inc = include_directories('.')
|
||||||
|
|
||||||
|
#csv = cmake.subproject('csv-parser')
|
||||||
|
#csv_lib = csv.dependency('csv')
|
||||||
|
|
||||||
|
nlohmann_lib = dependency('nlohmann_json', version : '>=3.5.0', required : false)
|
||||||
|
|
||||||
|
if not nlohmann_lib.found()
|
||||||
|
nlohmann_inc = include_directories('subprojects/nlohmann_json/single_include')
|
||||||
|
nlohmann_lib = declare_dependency(include_directories : nlohmann_inc)
|
||||||
|
endif
|
||||||
|
|
||||||
|
csv_inc = include_directories('subprojects/csv-parser/single_include')
|
||||||
|
csv_dep = declare_dependency(include_directories : csv_inc)
|
||||||
|
|
||||||
|
singleapp_proj = subproject('singleapplication')
|
||||||
|
singleapp_lib = singleapp_proj.get_variable('singleapp_lib')
|
||||||
|
singleapp_dep = singleapp_proj.get_variable('singleapp_dep')
|
||||||
|
|
||||||
|
subdir('src')
|
||||||
|
|
||||||
|
if build_machine.system() == 'linux'
|
||||||
|
install_data('misc/kima2.svg', install_dir : get_option('datadir') / 'icons/hicolor/scalable/apps')
|
||||||
|
install_data('misc/kima2.desktop', install_dir : get_option('datadir') / 'applications')
|
||||||
|
install_data('manual/Benutzerhandbuch.pdf', install_dir : get_option('datadir') / 'kima2')
|
||||||
|
endif
|
||||||
|
|
|
@ -1,29 +1,35 @@
|
||||||
# Maintainer: Martin Brodbeck <martin at brodbeck-online dot de>
|
# Maintainer: Martin Brodbeck <martin at brodbeck-online dot de>
|
||||||
pkgname=kima2
|
pkgname=kima2
|
||||||
pkgver=0.13.0
|
pkgver=1.7.1
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="A small cash point program for children's things markets (German only)"
|
pkgdesc="A small cash point program for children's things markets (German only)"
|
||||||
arch=('i686' 'x86_64')
|
arch=('i686' 'x86_64')
|
||||||
url="http://www.rustysoft.de/?01_kima2"
|
url="http://www.rustysoft.de/software/kima2"
|
||||||
license=('custom')
|
license=('custom')
|
||||||
depends=('glibc' 'libusb' 'qt5-base' 'sqlite3' 'xlnt')
|
depends=('glibc' 'libusb' 'qt6-base' 'sqlite3')
|
||||||
makedepends=('boost>=1.62')
|
makedepends=('boost>=1.62')
|
||||||
source=($pkgname-$pkgver.tar.gz)
|
source=(git+https://git.rustysoft.de/martin/kima2)
|
||||||
md5sums=('')
|
sha256sums=('SKIP')
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
if [ ! -d $pkgname/build ]; then
|
cd $pkgname
|
||||||
mkdir $pkgname/build
|
|
||||||
fi
|
|
||||||
cd $pkgname/build
|
|
||||||
|
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$pkgdir/usr -DKIMA2_USE_EXTERNAL_JSON=ON ..
|
git checkout v$pkgver
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
|
||||||
|
if [ -d build ]; then
|
||||||
|
rm -rf build
|
||||||
|
fi
|
||||||
|
mkdir build && cd build
|
||||||
|
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DKIMA2_USE_EXTERNAL_JSON=OFF ..
|
||||||
make
|
make
|
||||||
}
|
}
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
cd $pkgname/build
|
cd $pkgname/build
|
||||||
make install
|
make DESTDIR="$pkgdir" install
|
||||||
cd ..
|
cd ..
|
||||||
install -D -m644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
install -D -m644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ Type=Application
|
||||||
Name=KIMA2
|
Name=KIMA2
|
||||||
GenericName=Cash Point Program
|
GenericName=Cash Point Program
|
||||||
GenericName[de]=Kassenprogramm
|
GenericName[de]=Kassenprogramm
|
||||||
Comment=A small cash point program
|
Comment=A small cash point program for children's stuff markets
|
||||||
Comment[de]=Ein kleines Kassenprogramm
|
Comment[de]=Ein kleines Kassenprogramm für Kindersachenmärkte
|
||||||
Exec=kima2
|
Exec=kima2
|
||||||
Icon=kima2
|
Icon=kima2
|
||||||
Categories=Office;
|
Categories=Office;
|
||||||
|
|
43
misc/kima2.spec
Normal file
43
misc/kima2.spec
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
Name: kima2
|
||||||
|
Version: 1.6.0
|
||||||
|
Release: 1%{?dist}
|
||||||
|
Summary: A small cash point program for children's things markets
|
||||||
|
License: custom
|
||||||
|
|
||||||
|
Source0: %{name}-%{version}.tar.gz
|
||||||
|
|
||||||
|
BuildRequires: meson
|
||||||
|
BuildRequires: gcc-c++
|
||||||
|
#BuildRequires: pkgconfig(nlohmann_json)
|
||||||
|
BuildRequires: boost-date-time
|
||||||
|
BuildRequires: sqlite-devel
|
||||||
|
BuildRequires: libusb-devel
|
||||||
|
BuildRequires: qt5-qtdeclarative-devel
|
||||||
|
#BuildRequires: pkgconfig(pthreads)
|
||||||
|
|
||||||
|
%description
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%autosetup
|
||||||
|
|
||||||
|
%build
|
||||||
|
%meson
|
||||||
|
%meson_build
|
||||||
|
|
||||||
|
%install
|
||||||
|
%meson_install
|
||||||
|
|
||||||
|
%check
|
||||||
|
%meson_test
|
||||||
|
|
||||||
|
%files
|
||||||
|
%{_bindir}/kima2
|
||||||
|
%{_datadir}/applications/kima2.desktop
|
||||||
|
%{_datadir}/icons/hicolor/scalable/apps/kima2.svg
|
||||||
|
%{_datadir}/kima2/Benutzerhandbuch.pdf
|
||||||
|
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Fri Oct 11 2019 Martin Brodbeck <infor@rustysoft.de> - dev builds
|
||||||
|
-
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
set(Boost_USE_STATIC_LIBS ON)
|
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)
|
find_package(SQLite3 REQUIRED)
|
||||||
|
|
||||||
if (MINGW)
|
# Because csv-parser needs threads:
|
||||||
find_package(XLNT REQUIRED STATIC)
|
|
||||||
else (MINGW)
|
find_package(fmt)
|
||||||
find_package(PkgConfig REQUIRED)
|
|
||||||
pkg_check_modules(XLNT REQUIRED xlnt>=1.3)
|
|
||||||
endif (MINGW)
|
|
||||||
|
|
||||||
set(CORE_SOURCES
|
set(CORE_SOURCES
|
||||||
database.cpp
|
database.cpp
|
||||||
entity.cpp
|
entity.cpp
|
||||||
|
entityint.cpp
|
||||||
|
entityuuid.cpp
|
||||||
seller.cpp
|
seller.cpp
|
||||||
article.cpp
|
article.cpp
|
||||||
sale.cpp
|
sale.cpp
|
||||||
marketplace.cpp
|
marketplace.cpp
|
||||||
excelreader.cpp
|
csvreader.cpp
|
||||||
jsonutil.cpp
|
jsonutil.cpp
|
||||||
utils.cpp
|
utils.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(core STATIC ${CORE_SOURCES})
|
|
||||||
|
|
||||||
|
add_library(core STATIC ${CORE_SOURCES})
|
||||||
|
#target_include_directories(core PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/csv-parser/single_include)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_link_libraries(core PRIVATE printer Boost::boost Boost::date_time sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARY})
|
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json)
|
||||||
target_link_libraries(core PRIVATE bcrypt)
|
target_link_libraries(core PRIVATE bcrypt)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(core PRIVATE printer Boost::boost Boost::date_time sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARIES})
|
target_link_libraries(core PRIVATE sqlite3 nlohmann_json::nlohmann_json)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||||
|
|
|
@ -1,44 +1,38 @@
|
||||||
#include "article.h"
|
#include "article.h"
|
||||||
|
#include "seller.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
// Article::Article() : Entity() {}
|
Article::Article(int price) : m_price(price) {}
|
||||||
|
|
||||||
Article::Article(int price) : price_(price) {}
|
void Article::setArticleNo(int articleNo) { m_articleNo = articleNo; }
|
||||||
|
|
||||||
// Article::Article(std::shared_ptr<Seller> sellerPtr) : Entity() { sellerPtr_ = sellerPtr; }
|
void Article::setPrice(int price) { m_price = price; }
|
||||||
|
|
||||||
void Article::setArticleNo(int articleNo) { articleNo_ = articleNo; }
|
void Article::setDescription(const std::string &description) { m_description = description; }
|
||||||
|
|
||||||
void Article::setPrice(int price) { price_ = price; }
|
void Article::setSale(Sale *salePtr) { m_salePtr = salePtr; }
|
||||||
|
|
||||||
void Article::setDescription(const std::string& description) { description_ = description; }
|
void Article::setSeller(Seller *sellerPtr) { m_sellerPtr = sellerPtr; }
|
||||||
|
|
||||||
void Article::setSale(Sale* salePtr) { salePtr_ = salePtr; }
|
bool Article::isSold() { return m_salePtr ? true : false; }
|
||||||
|
|
||||||
void Article::setSeller(Seller* sellerPtr) { sellerPtr_ = sellerPtr; }
|
std::string Article::getDescription() { return m_description; }
|
||||||
|
|
||||||
bool Article::isSold() { return salePtr_ ? true : false; }
|
Seller *Article::getSeller() { return m_sellerPtr; }
|
||||||
|
Sale *Article::getSale() { return m_salePtr; }
|
||||||
|
|
||||||
std::string Article::getDescription() { return description_; }
|
int Article::getPrice() const { return m_price; }
|
||||||
|
|
||||||
Seller* Article::getSeller() { return sellerPtr_; }
|
std::string Article::getPriceAsString() const { return formatCentAsEuroString(m_price); }
|
||||||
Sale* Article::getSale() { return salePtr_; }
|
|
||||||
|
|
||||||
int Article::getPrice() const { return price_; }
|
int Article::getArticleNo() const { return m_articleNo; }
|
||||||
|
|
||||||
std::string Article::getPriceAsString() const
|
|
||||||
{
|
|
||||||
return formatCentAsEuroString(price_);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Article::getArticleNo() const { return articleNo_; }
|
|
||||||
|
|
||||||
std::string Article::getCompleteArticleNo() const
|
std::string Article::getCompleteArticleNo() const
|
||||||
{
|
{
|
||||||
std::stringstream artNoStream;
|
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();
|
return artNoStream.str();
|
||||||
}
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
#ifndef ARTICLE_H
|
#ifndef ARTICLE_H
|
||||||
#define ARTICLE_H
|
#define ARTICLE_H
|
||||||
|
|
||||||
#include "entity.h"
|
#include "entityuuid.h"
|
||||||
//#include "sale.h"
|
|
||||||
//#include "seller.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -11,34 +9,35 @@
|
||||||
class Seller;
|
class Seller;
|
||||||
class Sale;
|
class Sale;
|
||||||
|
|
||||||
class Article : public Entity
|
class Article : public EntityUuid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Article() = default;
|
Article() = default;
|
||||||
Article(int price);
|
Article(int price);
|
||||||
//virtual ~Article() = default;
|
Article(const Article &) = delete;
|
||||||
|
virtual ~Article() = default;
|
||||||
|
|
||||||
void setArticleNo(int articleNo);
|
void setArticleNo(int articleNo);
|
||||||
void setPrice(int price);
|
void setPrice(int price);
|
||||||
void setDescription(const std::string& description);
|
void setDescription(const std::string &description);
|
||||||
bool isSold();
|
bool isSold();
|
||||||
void setSale(Sale* salePtr);
|
void setSale(Sale *salePtr);
|
||||||
void setSeller(Seller* sellerPtr);
|
void setSeller(Seller *sellerPtr);
|
||||||
|
|
||||||
int getArticleNo() const;
|
int getArticleNo() const;
|
||||||
std::string getCompleteArticleNo() const;
|
std::string getCompleteArticleNo() const;
|
||||||
std::string getDescription();
|
std::string getDescription();
|
||||||
Seller* getSeller();
|
Seller *getSeller();
|
||||||
Sale* getSale();
|
Sale *getSale();
|
||||||
int getPrice() const;
|
int getPrice() const;
|
||||||
std::string getPriceAsString() const;
|
std::string getPriceAsString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Seller* sellerPtr_{};
|
Seller *m_sellerPtr{};
|
||||||
Sale* salePtr_{};
|
Sale *m_salePtr{};
|
||||||
int articleNo_{};
|
int m_articleNo{};
|
||||||
int price_{};
|
int m_price{};
|
||||||
std::string description_{};
|
std::string m_description{};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
92
src/core/csvreader.cpp
Normal file
92
src/core/csvreader.cpp
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
#include "csvreader.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
// #include <csv.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#ifdef DELETE
|
||||||
|
#undef DELETE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
std::size_t CsvReader::readSellersFromFile(const fs::path &filePath, Marketplace *market)
|
||||||
|
{
|
||||||
|
|
||||||
|
#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());
|
||||||
|
|
||||||
|
std::ifstream infile(fileName);
|
||||||
|
#else
|
||||||
|
// csv::CSVReader csvReader(filePath.string(), format);
|
||||||
|
std::ifstream infile(filePath.string());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (auto &seller : market->getSellers()) {
|
||||||
|
seller->setState(Seller::State::DELETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
market->storeToDb(true);
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
while (getline(infile, line)) {
|
||||||
|
std::vector<std::string> strs;
|
||||||
|
boost::split(strs, line, boost::is_any_of(";"));
|
||||||
|
|
||||||
|
auto seller = std::make_unique<Seller>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
int sellerNo = std::stoi(strs[0]);
|
||||||
|
seller->setSellerNo(sellerNo);
|
||||||
|
} catch (std::invalid_argument const &ex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNumber(strs[1]))
|
||||||
|
seller->setNumArticlesOffered(std::stoi(strs[1]));
|
||||||
|
else
|
||||||
|
seller->setNumArticlesOffered(0);
|
||||||
|
|
||||||
|
// If both, first name and last name, are empty, use N. N.
|
||||||
|
// Else, use the real values.
|
||||||
|
if (strs[2].empty() && strs[2].empty()) {
|
||||||
|
seller->setFirstName("N.");
|
||||||
|
seller->setLastName("N.");
|
||||||
|
} else {
|
||||||
|
std::string firstName = strs[2];
|
||||||
|
seller->setFirstName(trim(firstName));
|
||||||
|
std::string lastName = strs[3];
|
||||||
|
seller->setLastName(trim(lastName));
|
||||||
|
}
|
||||||
|
|
||||||
|
market->getSellers().push_back(std::move(seller));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add one additional seller "RESERVE RESERVE"
|
||||||
|
auto seller = std::make_unique<Seller>();
|
||||||
|
seller->setSellerNo(market->getNextSellerNo());
|
||||||
|
seller->setFirstName("RESERVE");
|
||||||
|
seller->setLastName("RESERVE");
|
||||||
|
market->getSellers().push_back(std::move(seller));
|
||||||
|
|
||||||
|
// If there was no special seller "Sonderkonto" in import data, then create one
|
||||||
|
auto specialSeller = market->findSellerWithSellerNo(0);
|
||||||
|
if (!specialSeller) {
|
||||||
|
auto seller = std::make_unique<Seller>();
|
||||||
|
seller->setSellerNo(0);
|
||||||
|
seller->setLastName("Sonderkonto");
|
||||||
|
seller->setFirstName("Sonderkonto");
|
||||||
|
seller->setNumArticlesOffered(0);
|
||||||
|
market->getSellers().push_back(std::move(seller));
|
||||||
|
}
|
||||||
|
|
||||||
|
market->sortSellers();
|
||||||
|
market->storeToDb();
|
||||||
|
|
||||||
|
return market->getSellers().size() - 1; // minus 1 because we don't count the "special" seller
|
||||||
|
}
|
19
src/core/csvreader.h
Normal file
19
src/core/csvreader.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef CSV_READER_H
|
||||||
|
#define CSV_READER_H
|
||||||
|
|
||||||
|
#include "marketplace.h"
|
||||||
|
#include "seller.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class CsvReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::size_t readSellersFromFile(const std::filesystem::path &filePath,
|
||||||
|
Marketplace *market);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,13 +1,13 @@
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <format>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "boost/date_time/posix_time/posix_time.hpp"
|
Database::Database(const std::string &dbname)
|
||||||
|
|
||||||
Database::Database(const std::string& dbname)
|
|
||||||
{
|
{
|
||||||
dbname_ = dbname;
|
dbname_ = dbname;
|
||||||
init();
|
init();
|
||||||
|
@ -28,7 +28,7 @@ Database::Database()
|
||||||
if (!fs::exists(dbpath)) {
|
if (!fs::exists(dbpath)) {
|
||||||
try {
|
try {
|
||||||
fs::create_directories(dbpath);
|
fs::create_directories(dbpath);
|
||||||
} catch (fs::filesystem_error& err) {
|
} catch (fs::filesystem_error &err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,11 @@ void Database::newDb()
|
||||||
|
|
||||||
fs::path sourcePath = dbname_;
|
fs::path sourcePath = dbname_;
|
||||||
fs::path destPath = sourcePath.parent_path() / sourcePath.stem();
|
fs::path destPath = sourcePath.parent_path() / sourcePath.stem();
|
||||||
destPath += std::string("_") +=
|
|
||||||
boost::posix_time::to_iso_string(boost::posix_time::second_clock::local_time()) += ".db";
|
auto chronoTime = std::chrono::system_clock::now();
|
||||||
|
std::string timeString = std::format("{0:%FT%H-%M-%S}", chronoTime);
|
||||||
|
|
||||||
|
destPath += std::string("_") += timeString += ".db";
|
||||||
|
|
||||||
fs::copy_file(sourcePath, destPath, fs::copy_options::overwrite_existing);
|
fs::copy_file(sourcePath, destPath, fs::copy_options::overwrite_existing);
|
||||||
|
|
||||||
|
@ -57,13 +60,13 @@ void Database::newDb()
|
||||||
|
|
||||||
Database::~Database() { sqlite3_close(db_); }
|
Database::~Database() { sqlite3_close(db_); }
|
||||||
|
|
||||||
void Database::exec(const std::string& sql)
|
void Database::exec(const std::string &sql)
|
||||||
{
|
{
|
||||||
char* errMsg;
|
char *errMsg;
|
||||||
const int errCode = sqlite3_exec(db_, sql.c_str(), nullptr, nullptr, &errMsg);
|
const int errCode = sqlite3_exec(db_, sql.c_str(), nullptr, nullptr, &errMsg);
|
||||||
if (errCode) {
|
if (errCode) {
|
||||||
std::string errMsgString(errMsg); // Make a C++ string of the errMsg, so that we can call
|
std::string errMsgString(errMsg); // Make a C++ string of the errMsg, so that we can call
|
||||||
// sqlite3_free() before throwing the exception
|
// sqlite3_free() before throwing the exception
|
||||||
sqlite3_free(errMsg);
|
sqlite3_free(errMsg);
|
||||||
throw std::runtime_error("Error in SQL execution: " + errMsgString);
|
throw std::runtime_error("Error in SQL execution: " + errMsgString);
|
||||||
}
|
}
|
||||||
|
@ -75,11 +78,10 @@ void Database::createNew()
|
||||||
|
|
||||||
std::string sqlCreateKima2{"CREATE TABLE IF NOT EXISTS kima2 ("
|
std::string sqlCreateKima2{"CREATE TABLE IF NOT EXISTS kima2 ("
|
||||||
"version INTEGER NOT NULL);"
|
"version INTEGER NOT NULL);"
|
||||||
"INSERT INTO kima2 (version) VALUES (2);"};
|
"INSERT INTO kima2 (version) VALUES (3);"};
|
||||||
sqlStrings.push_back(sqlCreateKima2);
|
sqlStrings.push_back(sqlCreateKima2);
|
||||||
std::string sqlCreateSellers{"CREATE TABLE IF NOT EXISTS sellers ("
|
std::string sqlCreateSellers{"CREATE TABLE IF NOT EXISTS sellers ("
|
||||||
"id TEXT PRIMARY KEY NOT NULL, "
|
"seller_no INTEGER PRIMARY KEY NOT NULL, "
|
||||||
"seller_no INTEGER, "
|
|
||||||
"first_name TEXT, "
|
"first_name TEXT, "
|
||||||
"last_name TEXT, "
|
"last_name TEXT, "
|
||||||
"num_offered_articles INTEGER, "
|
"num_offered_articles INTEGER, "
|
||||||
|
@ -89,13 +91,13 @@ void Database::createNew()
|
||||||
std::string sqlCreateArticles{
|
std::string sqlCreateArticles{
|
||||||
"CREATE TABLE IF NOT EXISTS articles ("
|
"CREATE TABLE IF NOT EXISTS articles ("
|
||||||
"id TEXT PRIMARY KEY NOT NULL, "
|
"id TEXT PRIMARY KEY NOT NULL, "
|
||||||
"seller_id TEXT NOT NULL, "
|
"seller_no TEXT NOT NULL, "
|
||||||
"source_no INTEGER NOT NULL, "
|
"source_no INTEGER NOT NULL, "
|
||||||
"article_no INTEGER NOT NULL, "
|
"article_no INTEGER NOT NULL, "
|
||||||
"description TEXT, "
|
"description TEXT, "
|
||||||
"price INTEGER NOT NULL, "
|
"price INTEGER NOT NULL, "
|
||||||
"UNIQUE (source_no, article_no), "
|
"UNIQUE (source_no, article_no), "
|
||||||
"FOREIGN KEY (seller_id) REFERENCES sellers(id) ON DELETE CASCADE, "
|
"FOREIGN KEY (seller_no) REFERENCES sellers(seller_no) ON DELETE CASCADE, "
|
||||||
"CHECK (article_no BETWEEN 0 AND 99999)"
|
"CHECK (article_no BETWEEN 0 AND 99999)"
|
||||||
");"};
|
");"};
|
||||||
sqlStrings.push_back(sqlCreateArticles);
|
sqlStrings.push_back(sqlCreateArticles);
|
||||||
|
@ -115,13 +117,13 @@ void Database::createNew()
|
||||||
sqlStrings.push_back(sqlCreateSalesItems);
|
sqlStrings.push_back(sqlCreateSalesItems);
|
||||||
|
|
||||||
std::string sqlInitialEntries{
|
std::string sqlInitialEntries{
|
||||||
"INSERT OR IGNORE INTO sellers (id, seller_no, first_name, last_name, "
|
"INSERT OR IGNORE INTO sellers (seller_no, first_name, last_name, "
|
||||||
"num_offered_articles) VALUES "
|
"num_offered_articles) VALUES "
|
||||||
"('11111111-1111-1111-1111-111111111111', 0, 'Sonderkonto', 'Sonderkonto', 0)"};
|
"(0, 'Sonderkonto', 'Sonderkonto', 0)"};
|
||||||
sqlStrings.push_back(sqlInitialEntries);
|
sqlStrings.push_back(sqlInitialEntries);
|
||||||
|
|
||||||
beginTransaction();
|
beginTransaction();
|
||||||
for (const auto& sql : sqlStrings) {
|
for (const auto &sql : sqlStrings) {
|
||||||
exec(sql);
|
exec(sql);
|
||||||
}
|
}
|
||||||
endTransaction();
|
endTransaction();
|
||||||
|
@ -130,13 +132,15 @@ void Database::createNew()
|
||||||
void Database::updateDbToVer2()
|
void Database::updateDbToVer2()
|
||||||
{
|
{
|
||||||
beginTransaction();
|
beginTransaction();
|
||||||
exec("INSERT OR IGNORE INTO sellers (id, seller_no, first_name, last_name, "
|
exec("INSERT OR IGNORE INTO sellers (seller_no, first_name, last_name, "
|
||||||
"num_offered_articles) VALUES "
|
"num_offered_articles) VALUES "
|
||||||
"('11111111-1111-1111-1111-111111111111', 0, 'Sonderkonto', 'Sonderkonto', 0)");
|
"(0, 'Sonderkonto', 'Sonderkonto', 0)");
|
||||||
exec("UPDATE kima2 SET version = 2");
|
exec("UPDATE kima2 SET version = 3");
|
||||||
endTransaction();
|
endTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::updateDbToVer3() { newDb(); }
|
||||||
|
|
||||||
void Database::init()
|
void Database::init()
|
||||||
{
|
{
|
||||||
const int errCode = sqlite3_open(dbname_.c_str(), &db_);
|
const int errCode = sqlite3_open(dbname_.c_str(), &db_);
|
||||||
|
@ -152,12 +156,19 @@ void Database::init()
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case 0:
|
case 0:
|
||||||
createNew();
|
createNew();
|
||||||
|
initResult_ = InitResult::OK;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
updateDbToVer2();
|
updateDbToVer3();
|
||||||
|
initResult_ = InitResult::OUTDATED_REPLACED;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
updateDbToVer3();
|
||||||
|
initResult_ = InitResult::OUTDATED_REPLACED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Do nothing because we are up-to-date.
|
// Do nothing because we are up-to-date.
|
||||||
|
initResult_ = InitResult::OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,7 +176,7 @@ void Database::init()
|
||||||
int Database::getVersion()
|
int Database::getVersion()
|
||||||
{
|
{
|
||||||
int retCode{};
|
int retCode{};
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
// Check if there's already a kima2 table available.
|
// Check if there's already a kima2 table available.
|
||||||
// If not, return version == 0.
|
// If not, return version == 0.
|
||||||
|
@ -212,29 +223,26 @@ void Database::beginTransaction() { exec("BEGIN TRANSACTION"); }
|
||||||
|
|
||||||
void Database::endTransaction() { exec("END TRANSACTION"); }
|
void Database::endTransaction() { exec("END TRANSACTION"); }
|
||||||
|
|
||||||
unsigned int Database::storeSellers(std::vector<std::unique_ptr<Seller>>& sellers, bool onlyDelete)
|
unsigned int Database::storeSellers(std::vector<std::unique_ptr<Seller>> &sellers, bool onlyDelete)
|
||||||
{
|
{
|
||||||
int retCode{};
|
int retCode{};
|
||||||
int count{};
|
int count{};
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
beginTransaction();
|
beginTransaction();
|
||||||
|
|
||||||
for (auto& seller : sellers) {
|
for (auto &seller : sellers) {
|
||||||
if (seller->getState() == Seller::State::NEW && !onlyDelete) {
|
if (seller->getState() == Seller::State::NEW && !onlyDelete) {
|
||||||
retCode = sqlite3_prepare_v2(
|
retCode = sqlite3_prepare_v2(
|
||||||
db_,
|
db_,
|
||||||
"INSERT INTO sellers"
|
"INSERT INTO sellers"
|
||||||
" (id, seller_no, first_name, last_name, num_offered_articles)"
|
" (seller_no, first_name, last_name, num_offered_articles)"
|
||||||
" VALUES (:uuid, :seller_no, :first_name, :last_name, :num_offered_articles)",
|
" VALUES (:seller_no, :first_name, :last_name, :num_offered_articles)",
|
||||||
-1, &stmt, nullptr);
|
-1, &stmt, nullptr);
|
||||||
|
|
||||||
if (retCode != SQLITE_OK)
|
if (retCode != SQLITE_OK)
|
||||||
throw std::runtime_error(sqlite3_errmsg(db_));
|
throw std::runtime_error(sqlite3_errmsg(db_));
|
||||||
|
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":uuid"),
|
|
||||||
boost::uuids::to_string(seller->getUuid()).c_str(), -1,
|
|
||||||
SQLITE_TRANSIENT);
|
|
||||||
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":seller_no"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":seller_no"),
|
||||||
seller->getSellerNo());
|
seller->getSellerNo());
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":first_name"),
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":first_name"),
|
||||||
|
@ -260,15 +268,13 @@ unsigned int Database::storeSellers(std::vector<std::unique_ptr<Seller>>& seller
|
||||||
"UPDATE sellers SET"
|
"UPDATE sellers SET"
|
||||||
" seller_no = :seller_no, first_name = :first_name,"
|
" seller_no = :seller_no, first_name = :first_name,"
|
||||||
" last_name = :last_name, num_offered_articles = :num_offered_articles"
|
" last_name = :last_name, num_offered_articles = :num_offered_articles"
|
||||||
" WHERE id = :uuid",
|
" WHERE seller_no = :id",
|
||||||
-1, &stmt, nullptr);
|
-1, &stmt, nullptr);
|
||||||
|
|
||||||
if (retCode != SQLITE_OK)
|
if (retCode != SQLITE_OK)
|
||||||
throw std::runtime_error(sqlite3_errmsg(db_));
|
throw std::runtime_error(sqlite3_errmsg(db_));
|
||||||
|
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":uuid"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":id"), seller->getId());
|
||||||
boost::uuids::to_string(seller->getUuid()).c_str(), -1,
|
|
||||||
SQLITE_TRANSIENT);
|
|
||||||
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":seller_no"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":seller_no"),
|
||||||
seller->getSellerNo());
|
seller->getSellerNo());
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":first_name"),
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":first_name"),
|
||||||
|
@ -291,15 +297,13 @@ unsigned int Database::storeSellers(std::vector<std::unique_ptr<Seller>>& seller
|
||||||
} else if (seller->getState() == Seller::State::DELETE) {
|
} else if (seller->getState() == Seller::State::DELETE) {
|
||||||
count += static_cast<int>(seller->getArticles(false).size());
|
count += static_cast<int>(seller->getArticles(false).size());
|
||||||
|
|
||||||
retCode =
|
retCode = sqlite3_prepare_v2(db_, "DELETE FROM sellers WHERE seller_no = :id", -1,
|
||||||
sqlite3_prepare_v2(db_, "DELETE FROM sellers WHERE id = :uuid", -1, &stmt, nullptr);
|
&stmt, nullptr);
|
||||||
|
|
||||||
if (retCode != SQLITE_OK)
|
if (retCode != SQLITE_OK)
|
||||||
throw std::runtime_error(sqlite3_errmsg(db_));
|
throw std::runtime_error(sqlite3_errmsg(db_));
|
||||||
|
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":uuid"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":id"), seller->getId());
|
||||||
boost::uuids::to_string(seller->getUuid()).c_str(), -1,
|
|
||||||
SQLITE_TRANSIENT);
|
|
||||||
|
|
||||||
retCode = sqlite3_step(stmt);
|
retCode = sqlite3_step(stmt);
|
||||||
|
|
||||||
|
@ -322,12 +326,12 @@ unsigned int Database::storeSellers(std::vector<std::unique_ptr<Seller>>& seller
|
||||||
|
|
||||||
// Everything went fine, so we can now update our objects
|
// Everything went fine, so we can now update our objects
|
||||||
sellers.erase(std::remove_if(sellers.begin(), sellers.end(),
|
sellers.erase(std::remove_if(sellers.begin(), sellers.end(),
|
||||||
[](const std::unique_ptr<Seller>& seller) {
|
[](const std::unique_ptr<Seller> &seller) {
|
||||||
return (seller->getState() == Seller::State::DELETE);
|
return (seller->getState() == Seller::State::DELETE);
|
||||||
}),
|
}),
|
||||||
sellers.end());
|
sellers.end());
|
||||||
|
|
||||||
for (auto& seller : sellers) {
|
for (auto &seller : sellers) {
|
||||||
seller->cleanupArticles();
|
seller->cleanupArticles();
|
||||||
seller->setState(Seller::State::OK);
|
seller->setState(Seller::State::OK);
|
||||||
}
|
}
|
||||||
|
@ -335,18 +339,18 @@ unsigned int Database::storeSellers(std::vector<std::unique_ptr<Seller>>& seller
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Database::storeArticles(std::vector<Article*> articles)
|
unsigned int Database::storeArticles(std::vector<Article *> articles)
|
||||||
{
|
{
|
||||||
int retCode{};
|
int retCode{};
|
||||||
int count{};
|
int count{};
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
for (auto& article : articles) {
|
for (auto &article : articles) {
|
||||||
if (article->getState() == Article::State::NEW) {
|
if (article->getState() == Article::State::NEW) {
|
||||||
retCode = sqlite3_prepare_v2(
|
retCode = sqlite3_prepare_v2(
|
||||||
db_,
|
db_,
|
||||||
"INSERT INTO articles"
|
"INSERT INTO articles"
|
||||||
" (id, seller_id, source_no, article_no, description, price)"
|
" (id, seller_no, source_no, article_no, description, price)"
|
||||||
" VALUES (:uuid, :seller_id, :source_no, :article_no, :desc, :price)",
|
" VALUES (:uuid, :seller_id, :source_no, :article_no, :desc, :price)",
|
||||||
-1, &stmt, nullptr);
|
-1, &stmt, nullptr);
|
||||||
|
|
||||||
|
@ -356,9 +360,8 @@ unsigned int Database::storeArticles(std::vector<Article*> articles)
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":uuid"),
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":uuid"),
|
||||||
boost::uuids::to_string(article->getUuid()).c_str(), -1,
|
boost::uuids::to_string(article->getUuid()).c_str(), -1,
|
||||||
SQLITE_TRANSIENT);
|
SQLITE_TRANSIENT);
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":seller_id"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":seller_id"),
|
||||||
boost::uuids::to_string(article->getSeller()->getUuid()).c_str(), -1,
|
article->getSeller()->getId());
|
||||||
SQLITE_TRANSIENT);
|
|
||||||
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":source_no"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":source_no"),
|
||||||
article->getSourceNo());
|
article->getSourceNo());
|
||||||
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":article_no"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":article_no"),
|
||||||
|
@ -382,7 +385,7 @@ unsigned int Database::storeArticles(std::vector<Article*> articles)
|
||||||
retCode = sqlite3_prepare_v2(
|
retCode = sqlite3_prepare_v2(
|
||||||
db_,
|
db_,
|
||||||
"UPDATE articles SET"
|
"UPDATE articles SET"
|
||||||
" seller_id = seller_id, source_no = :source_no, article_no = :article_no,"
|
" seller_no = :seller_id, source_no = :source_no, article_no = :article_no,"
|
||||||
" description = :desc, price = :price"
|
" description = :desc, price = :price"
|
||||||
" WHERE id = :uuid",
|
" WHERE id = :uuid",
|
||||||
-1, &stmt, nullptr);
|
-1, &stmt, nullptr);
|
||||||
|
@ -393,9 +396,8 @@ unsigned int Database::storeArticles(std::vector<Article*> articles)
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":uuid"),
|
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":uuid"),
|
||||||
boost::uuids::to_string(article->getUuid()).c_str(), -1,
|
boost::uuids::to_string(article->getUuid()).c_str(), -1,
|
||||||
SQLITE_TRANSIENT);
|
SQLITE_TRANSIENT);
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":seller_id"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":seller_id"),
|
||||||
boost::uuids::to_string(article->getSeller()->getUuid()).c_str(), -1,
|
article->getSeller()->getId());
|
||||||
SQLITE_TRANSIENT);
|
|
||||||
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":source_no"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":source_no"),
|
||||||
article->getSourceNo());
|
article->getSourceNo());
|
||||||
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":article_no"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":article_no"),
|
||||||
|
@ -442,18 +444,18 @@ unsigned int Database::storeArticles(std::vector<Article*> articles)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Database::storeSales(std::vector<std::unique_ptr<Sale>>& sales)
|
unsigned int Database::storeSales(std::vector<std::unique_ptr<Sale>> &sales)
|
||||||
{
|
{
|
||||||
int retCode{};
|
int retCode{};
|
||||||
int count{};
|
int count{};
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
if (sales.size() == 0)
|
if (sales.size() == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
beginTransaction();
|
beginTransaction();
|
||||||
|
|
||||||
for (auto& sale : sales) {
|
for (auto &sale : sales) {
|
||||||
if (sale->getState() == Sale::State::NEW) {
|
if (sale->getState() == Sale::State::NEW) {
|
||||||
retCode = sqlite3_prepare_v2(db_,
|
retCode = sqlite3_prepare_v2(db_,
|
||||||
"INSERT INTO sales"
|
"INSERT INTO sales"
|
||||||
|
@ -483,7 +485,7 @@ unsigned int Database::storeSales(std::vector<std::unique_ptr<Sale>>& sales)
|
||||||
++count;
|
++count;
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
for (const auto& article : sale->getArticles()) {
|
for (const auto &article : sale->getArticles()) {
|
||||||
retCode = sqlite3_prepare_v2(db_,
|
retCode = sqlite3_prepare_v2(db_,
|
||||||
"INSERT INTO sales_items"
|
"INSERT INTO sales_items"
|
||||||
" (sale_id, article_id)"
|
" (sale_id, article_id)"
|
||||||
|
@ -536,24 +538,24 @@ unsigned int Database::storeSales(std::vector<std::unique_ptr<Sale>>& sales)
|
||||||
// Everything went fine, so we can now update our objects
|
// Everything went fine, so we can now update our objects
|
||||||
sales.erase(
|
sales.erase(
|
||||||
std::remove_if(sales.begin(), sales.end(),
|
std::remove_if(sales.begin(), sales.end(),
|
||||||
[](const auto& sale) { return (sale->getState() == Sale::State::DELETE); }),
|
[](const auto &sale) { return (sale->getState() == Sale::State::DELETE); }),
|
||||||
sales.end());
|
sales.end());
|
||||||
|
|
||||||
for (auto& sale : sales) {
|
for (auto &sale : sales) {
|
||||||
sale->setState(Sale::State::OK);
|
sale->setState(Sale::State::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Database::loadSellers(std::vector<std::unique_ptr<Seller>>& sellers)
|
unsigned int Database::loadSellers(std::vector<std::unique_ptr<Seller>> &sellers)
|
||||||
{
|
{
|
||||||
int retCode{};
|
int retCode{};
|
||||||
int count{};
|
int count{};
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
retCode = sqlite3_prepare_v2(db_,
|
retCode = sqlite3_prepare_v2(db_,
|
||||||
"SELECT id, seller_no, first_name, last_name, "
|
"SELECT seller_no, first_name, last_name, "
|
||||||
"num_offered_articles FROM sellers ORDER BY seller_no",
|
"num_offered_articles FROM sellers ORDER BY seller_no",
|
||||||
-1, &stmt, nullptr);
|
-1, &stmt, nullptr);
|
||||||
if (retCode != SQLITE_OK)
|
if (retCode != SQLITE_OK)
|
||||||
|
@ -566,11 +568,10 @@ unsigned int Database::loadSellers(std::vector<std::unique_ptr<Seller>>& sellers
|
||||||
while (retCode != SQLITE_DONE) {
|
while (retCode != SQLITE_DONE) {
|
||||||
++count;
|
++count;
|
||||||
auto seller = std::make_unique<Seller>();
|
auto seller = std::make_unique<Seller>();
|
||||||
seller->setUuidFromString(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
|
seller->setSellerNo(sqlite3_column_int(stmt, 0));
|
||||||
seller->setSellerNo(sqlite3_column_int(stmt, 1));
|
seller->setFirstName(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)));
|
||||||
seller->setFirstName(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2)));
|
seller->setLastName(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2)));
|
||||||
seller->setLastName(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3)));
|
seller->setNumArticlesOffered(sqlite3_column_int(stmt, 3));
|
||||||
seller->setNumArticlesOffered(sqlite3_column_int(stmt, 4));
|
|
||||||
seller->setState(Seller::State::OK);
|
seller->setState(Seller::State::OK);
|
||||||
sellers.push_back(std::move(seller));
|
sellers.push_back(std::move(seller));
|
||||||
|
|
||||||
|
@ -579,29 +580,29 @@ unsigned int Database::loadSellers(std::vector<std::unique_ptr<Seller>>& sellers
|
||||||
|
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
for (auto& seller : sellers) {
|
for (auto &seller : sellers) {
|
||||||
retCode = sqlite3_prepare_v2(db_,
|
retCode = sqlite3_prepare_v2(db_,
|
||||||
"SELECT id, source_no, article_no, description, price"
|
"SELECT id, source_no, article_no, description, price"
|
||||||
" FROM articles"
|
" FROM articles"
|
||||||
" WHERE seller_id = :seller_uuid"
|
" WHERE seller_no = :seller_id"
|
||||||
" ORDER BY article_no",
|
" ORDER BY article_no",
|
||||||
-1, &stmt, nullptr);
|
-1, &stmt, nullptr);
|
||||||
if (retCode != SQLITE_OK)
|
if (retCode != SQLITE_OK)
|
||||||
throw std::runtime_error(sqlite3_errmsg(db_));
|
throw std::runtime_error(sqlite3_errmsg(db_));
|
||||||
|
|
||||||
sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, ":seller_uuid"),
|
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, ":seller_id"), seller->getId());
|
||||||
boost::uuids::to_string(seller->getUuid()).c_str(), -1, SQLITE_TRANSIENT);
|
|
||||||
|
|
||||||
retCode = sqlite3_step(stmt);
|
retCode = sqlite3_step(stmt);
|
||||||
|
|
||||||
while (retCode != SQLITE_DONE) {
|
while (retCode != SQLITE_DONE) {
|
||||||
++count;
|
++count;
|
||||||
auto article = std::make_unique<Article>();
|
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->setSeller(seller.get());
|
||||||
article->setSourceNo(sqlite3_column_int(stmt, 1));
|
article->setSourceNo(sqlite3_column_int(stmt, 1));
|
||||||
article->setArticleNo(sqlite3_column_int(stmt, 2));
|
article->setArticleNo(sqlite3_column_int(stmt, 2));
|
||||||
article->setDescription(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3)));
|
article->setDescription(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 3)));
|
||||||
article->setPrice(sqlite3_column_int(stmt, 4));
|
article->setPrice(sqlite3_column_int(stmt, 4));
|
||||||
article->setState(Article::State::OK);
|
article->setState(Article::State::OK);
|
||||||
|
|
||||||
|
@ -616,12 +617,12 @@ unsigned int Database::loadSellers(std::vector<std::unique_ptr<Seller>>& sellers
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Database::loadSales(std::vector<std::unique_ptr<Sale>>& sales,
|
unsigned int Database::loadSales(std::vector<std::unique_ptr<Sale>> &sales,
|
||||||
std::vector<std::unique_ptr<Seller>>& sellers)
|
std::vector<std::unique_ptr<Seller>> &sellers)
|
||||||
{
|
{
|
||||||
int retCode{};
|
int retCode{};
|
||||||
int count{};
|
int count{};
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
retCode = sqlite3_prepare_v2(db_,
|
retCode = sqlite3_prepare_v2(db_,
|
||||||
"SELECT id, source_no, sold_at"
|
"SELECT id, source_no, sold_at"
|
||||||
|
@ -634,13 +635,13 @@ unsigned int Database::loadSales(std::vector<std::unique_ptr<Sale>>& sales,
|
||||||
|
|
||||||
sales.clear();
|
sales.clear();
|
||||||
|
|
||||||
std::map<std::string, Sale*> saleMap;
|
std::map<std::string, Sale *> saleMap;
|
||||||
while (retCode != SQLITE_DONE) {
|
while (retCode != SQLITE_DONE) {
|
||||||
++count;
|
++count;
|
||||||
auto sale = std::make_unique<Sale>();
|
auto sale = std::make_unique<Sale>();
|
||||||
sale->setUuidFromString(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
|
sale->setUuidFromString(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)));
|
||||||
sale->setSourceNo(sqlite3_column_int(stmt, 1));
|
sale->setSourceNo(sqlite3_column_int(stmt, 1));
|
||||||
sale->setTimestamp(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2)));
|
sale->setTimestamp(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2)));
|
||||||
sale->setState(Sale::State::OK);
|
sale->setState(Sale::State::OK);
|
||||||
saleMap.insert(std::make_pair(sale->getUuidAsString(), sale.get()));
|
saleMap.insert(std::make_pair(sale->getUuidAsString(), sale.get()));
|
||||||
sales.push_back(std::move(sale));
|
sales.push_back(std::move(sale));
|
||||||
|
@ -650,8 +651,8 @@ unsigned int Database::loadSales(std::vector<std::unique_ptr<Sale>>& sales,
|
||||||
|
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
std::map<std::string, Article*> artMap;
|
std::map<std::string, Article *> artMap;
|
||||||
for (const auto& seller : sellers) {
|
for (const auto &seller : sellers) {
|
||||||
for (const auto article : seller->getArticles(false)) {
|
for (const auto article : seller->getArticles(false)) {
|
||||||
artMap.insert(std::make_pair(article->getUuidAsString(), article));
|
artMap.insert(std::make_pair(article->getUuidAsString(), article));
|
||||||
}
|
}
|
||||||
|
@ -667,8 +668,8 @@ unsigned int Database::loadSales(std::vector<std::unique_ptr<Sale>>& sales,
|
||||||
retCode = sqlite3_step(stmt);
|
retCode = sqlite3_step(stmt);
|
||||||
|
|
||||||
while (retCode != SQLITE_DONE) {
|
while (retCode != SQLITE_DONE) {
|
||||||
saleMap[reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0))]->addArticle(
|
saleMap[reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0))]->addArticle(
|
||||||
artMap[reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1))]);
|
artMap[reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1))]);
|
||||||
|
|
||||||
retCode = sqlite3_step(stmt);
|
retCode = sqlite3_step(stmt);
|
||||||
}
|
}
|
||||||
|
@ -681,7 +682,7 @@ unsigned int Database::loadSales(std::vector<std::unique_ptr<Sale>>& sales,
|
||||||
void Database::updateCashPointNo(int oldCashPointNo, int newCashPointNo)
|
void Database::updateCashPointNo(int oldCashPointNo, int newCashPointNo)
|
||||||
{
|
{
|
||||||
int retCode{};
|
int retCode{};
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
// Check if the new no ist already in use
|
// Check if the new no ist already in use
|
||||||
retCode = sqlite3_prepare_v2(db_, "SELECT COUNT() FROM articles WHERE source_no = :source_no",
|
retCode = sqlite3_prepare_v2(db_, "SELECT COUNT() FROM articles WHERE source_no = :source_no",
|
||||||
|
|
|
@ -10,32 +10,36 @@
|
||||||
|
|
||||||
class Database
|
class Database
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Database(const std::string& dbname);
|
enum class InitResult { OK, OUTDATED_REPLACED };
|
||||||
|
explicit Database(const std::string &dbname);
|
||||||
Database();
|
Database();
|
||||||
~Database();
|
~Database();
|
||||||
Database(const Database&) = delete;
|
Database(const Database &) = delete;
|
||||||
Database& operator=(const Database&) = delete;
|
Database &operator=(const Database &) = delete;
|
||||||
void exec(const std::string& sql);
|
void exec(const std::string &sql);
|
||||||
unsigned int storeSellers(std::vector<std::unique_ptr<Seller>>& sellers,
|
unsigned int storeSellers(std::vector<std::unique_ptr<Seller>> &sellers,
|
||||||
bool onlyDelete = false);
|
bool onlyDelete = false);
|
||||||
unsigned int loadSellers(std::vector<std::unique_ptr<Seller>>& sellers);
|
unsigned int loadSellers(std::vector<std::unique_ptr<Seller>> &sellers);
|
||||||
unsigned int storeSales(std::vector<std::unique_ptr<Sale>>& sales);
|
unsigned int storeSales(std::vector<std::unique_ptr<Sale>> &sales);
|
||||||
unsigned int loadSales(std::vector<std::unique_ptr<Sale>>& sales,
|
unsigned int loadSales(std::vector<std::unique_ptr<Sale>> &sales,
|
||||||
std::vector<std::unique_ptr<Seller>>& sellers);
|
std::vector<std::unique_ptr<Seller>> &sellers);
|
||||||
void updateCashPointNo(int oldCashPointNo, int newCashPointNo);
|
void updateCashPointNo(int oldCashPointNo, int newCashPointNo);
|
||||||
void newDb();
|
void newDb();
|
||||||
|
InitResult getInitResult() { return initResult_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sqlite3* db_{nullptr};
|
sqlite3 *db_{nullptr};
|
||||||
std::string dbname_;
|
std::string dbname_;
|
||||||
void init();
|
void init();
|
||||||
void beginTransaction();
|
void beginTransaction();
|
||||||
void endTransaction();
|
void endTransaction();
|
||||||
void createNew();
|
void createNew();
|
||||||
int getVersion();
|
int getVersion();
|
||||||
unsigned int storeArticles(std::vector<Article*> articles);
|
unsigned int storeArticles(std::vector<Article *> articles);
|
||||||
void updateDbToVer2();
|
void updateDbToVer2();
|
||||||
|
void updateDbToVer3();
|
||||||
|
InitResult initResult_{InitResult::OK};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DATABASE_H
|
#endif // DATABASE_H
|
|
@ -1,33 +1,3 @@
|
||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
|
|
||||||
#include <iostream>
|
Entity::State Entity::getState() const { return m_state; }
|
||||||
|
|
||||||
#include <boost/uuid/uuid_generators.hpp>
|
|
||||||
#include <boost/uuid/uuid_io.hpp>
|
|
||||||
|
|
||||||
Entity::~Entity() = default;
|
|
||||||
|
|
||||||
void Entity::createUuid()
|
|
||||||
{
|
|
||||||
static boost::uuids::random_generator generator{};
|
|
||||||
uuid_ = generator();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Entity::setUuidFromString(const std::string& uuidString)
|
|
||||||
{
|
|
||||||
boost::uuids::string_generator generator{};
|
|
||||||
uuid_ = generator(uuidString);
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity::State Entity::getState() const
|
|
||||||
{
|
|
||||||
return state_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Entity::setSourceNo(int sourceNo) {
|
|
||||||
sourceNo_ = sourceNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Entity::getSourceNo() const {
|
|
||||||
return sourceNo_;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,35 +1,16 @@
|
||||||
#ifndef ENTITY_H
|
#ifndef ENTITY_H
|
||||||
#define ENTITY_H
|
#define ENTITY_H
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <boost/uuid/uuid.hpp>
|
|
||||||
#include <boost/uuid/uuid_io.hpp>
|
|
||||||
|
|
||||||
class Entity
|
class Entity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class State { NEW, UPDATE, DELETE, OK };
|
enum class State { NEW, UPDATE, DELETE, OK };
|
||||||
|
virtual ~Entity() = default;
|
||||||
// Entity() = default;
|
void setState(State state) { m_state = state; }
|
||||||
virtual ~Entity() = 0;
|
|
||||||
|
|
||||||
void createUuid();
|
|
||||||
void setUuidFromString(const std::string& uuidString);
|
|
||||||
void setState(State state) { state_ = state; }
|
|
||||||
void setSourceNo(int sourceNo);
|
|
||||||
|
|
||||||
const boost::uuids::uuid& getUuid() const { return uuid_; };
|
|
||||||
std::string getUuidAsString() const { return boost::uuids::to_string(uuid_); }
|
|
||||||
virtual State getState() const;
|
virtual State getState() const;
|
||||||
virtual int getSourceNo() const;
|
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
int sourceNo_{};
|
State m_state{State::NEW};
|
||||||
|
|
||||||
private:
|
|
||||||
boost::uuids::uuid uuid_{};
|
|
||||||
State state_{State::NEW};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ENTITY_H
|
#endif // ENTITY_H
|
5
src/core/entityint.cpp
Normal file
5
src/core/entityint.cpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include "entityint.h"
|
||||||
|
|
||||||
|
EntityInt::EntityInt(int id) { m_id = id; }
|
||||||
|
|
||||||
|
void EntityInt::setId(int id) { m_id = id; }
|
19
src/core/entityint.h
Normal file
19
src/core/entityint.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef ENTITY_INT_H
|
||||||
|
#define ENTITY_INT_H
|
||||||
|
|
||||||
|
#include "entity.h"
|
||||||
|
|
||||||
|
class EntityInt : public Entity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EntityInt() = default;
|
||||||
|
virtual ~EntityInt() = default;
|
||||||
|
EntityInt(int id);
|
||||||
|
void setId(int id);
|
||||||
|
int getId() const { return m_id; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_id{};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ENTITY_INT_H
|
22
src/core/entityuuid.cpp
Normal file
22
src/core/entityuuid.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include "entityuuid.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <boost/uuid/uuid_generators.hpp>
|
||||||
|
#include <boost/uuid/uuid_io.hpp>
|
||||||
|
|
||||||
|
void EntityUuid::createUuid()
|
||||||
|
{
|
||||||
|
static boost::uuids::random_generator generator{};
|
||||||
|
m_uuid = generator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityUuid::setUuidFromString(const std::string &uuidString)
|
||||||
|
{
|
||||||
|
boost::uuids::string_generator generator{};
|
||||||
|
m_uuid = generator(uuidString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityUuid::setSourceNo(int sourceNo) { m_sourceNo = sourceNo; }
|
||||||
|
|
||||||
|
int EntityUuid::getSourceNo() const { return m_sourceNo; }
|
32
src/core/entityuuid.h
Normal file
32
src/core/entityuuid.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef ENTITY_UUID_H
|
||||||
|
#define ENTITY_UUID_H
|
||||||
|
|
||||||
|
#include "entity.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/uuid/uuid.hpp>
|
||||||
|
#include <boost/uuid/uuid_io.hpp>
|
||||||
|
|
||||||
|
class EntityUuid : public Entity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EntityUuid() = default;
|
||||||
|
virtual ~EntityUuid() = default;
|
||||||
|
|
||||||
|
void createUuid();
|
||||||
|
void setUuidFromString(const std::string &uuidString);
|
||||||
|
void setSourceNo(int sourceNo);
|
||||||
|
|
||||||
|
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 m_sourceNo{};
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::uuids::uuid m_uuid{};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ENTITY_UUID_H
|
|
@ -1,63 +0,0 @@
|
||||||
#include "excelreader.h"
|
|
||||||
|
|
||||||
#include <xlnt/xlnt.hpp>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
void 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 ecxel file");
|
|
||||||
}
|
|
||||||
wb.load(mystream);
|
|
||||||
|
|
||||||
for (auto& seller : market->getSellers()) {
|
|
||||||
seller->setState(Seller::State::DELETE);
|
|
||||||
}
|
|
||||||
|
|
||||||
market->storeToDb(true);
|
|
||||||
auto ws = wb.sheet_by_index(0);
|
|
||||||
|
|
||||||
const int START_ROW = 5;
|
|
||||||
const int END_ROW = 350;
|
|
||||||
|
|
||||||
int rowCount{};
|
|
||||||
for (const auto& row : ws.rows(false)) {
|
|
||||||
if (rowCount < START_ROW) {
|
|
||||||
++rowCount;
|
|
||||||
continue;
|
|
||||||
} else if (rowCount > END_ROW) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (row[2].value<std::string>().empty() && row[3].value<std::string>().empty()) {
|
|
||||||
++rowCount;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto seller = std::make_unique<Seller>();
|
|
||||||
seller->createUuid();
|
|
||||||
seller->setSellerNo(row[0].value<int>());
|
|
||||||
seller->setNumArticlesOffered(row[1].value<int>());
|
|
||||||
seller->setFirstName(row[2].value<std::string>());
|
|
||||||
seller->setLastName(row[3].value<std::string>());
|
|
||||||
market->getSellers().push_back(std::move(seller));
|
|
||||||
rowCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there was no special seller "Sonderkonto" in import data, then create one
|
|
||||||
auto specialSeller = market->findSellerWithUuid("11111111-1111-1111-1111-111111111111");
|
|
||||||
if (!specialSeller) {
|
|
||||||
auto seller = std::make_unique<Seller>();
|
|
||||||
seller->setUuidFromString("11111111-1111-1111-1111-111111111111");
|
|
||||||
seller->setSellerNo(0);
|
|
||||||
seller->setLastName("Sonderkonto");
|
|
||||||
seller->setFirstName("Sonderkonto");
|
|
||||||
seller->setNumArticlesOffered(0);
|
|
||||||
market->getSellers().push_back(std::move(seller));
|
|
||||||
}
|
|
||||||
|
|
||||||
market->sortSellers();
|
|
||||||
market->storeToDb();
|
|
||||||
}
|
|
|
@ -1,18 +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 void readSellersFromFile(const std::filesystem::path& filePath, Marketplace* market);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -5,17 +5,15 @@
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
void JsonUtil::exportSellers(const std::filesystem::path& filePath, Marketplace* market)
|
void JsonUtil::exportSellers(const std::filesystem::path &filePath, Marketplace *market)
|
||||||
{
|
{
|
||||||
json root;
|
json root;
|
||||||
std::ofstream file(filePath);
|
std::ofstream file(filePath);
|
||||||
|
|
||||||
for (const auto& seller : market->getSellers()) {
|
for (const auto &seller : market->getSellers()) {
|
||||||
json newEntry;
|
json newEntry;
|
||||||
newEntry["uuid"] = seller->getUuidAsString();
|
|
||||||
newEntry["seller_no"] = seller->getSellerNo();
|
newEntry["seller_no"] = seller->getSellerNo();
|
||||||
newEntry["last_name"] = seller->getLastName();
|
newEntry["last_name"] = seller->getLastName();
|
||||||
newEntry["first_name"] = seller->getFirstName();
|
newEntry["first_name"] = seller->getFirstName();
|
||||||
|
@ -26,9 +24,9 @@ void JsonUtil::exportSellers(const std::filesystem::path& filePath, Marketplace*
|
||||||
file << root.dump(4) << std::endl;
|
file << root.dump(4) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonUtil::importSellers(const std::filesystem::path& filePath, Marketplace* market)
|
std::size_t JsonUtil::importSellers(const std::filesystem::path &filePath, Marketplace *market)
|
||||||
{
|
{
|
||||||
for (auto& seller : market->getSellers()) {
|
for (auto &seller : market->getSellers()) {
|
||||||
seller->setState(Seller::State::DELETE);
|
seller->setState(Seller::State::DELETE);
|
||||||
}
|
}
|
||||||
market->storeToDb(true);
|
market->storeToDb(true);
|
||||||
|
@ -38,7 +36,6 @@ void JsonUtil::importSellers(const std::filesystem::path& filePath, Marketplace*
|
||||||
|
|
||||||
for (auto val : jsonValues["sellers"]) {
|
for (auto val : jsonValues["sellers"]) {
|
||||||
auto seller = std::make_unique<Seller>();
|
auto seller = std::make_unique<Seller>();
|
||||||
seller->setUuidFromString(val["uuid"]);
|
|
||||||
seller->setSellerNo(val["seller_no"]);
|
seller->setSellerNo(val["seller_no"]);
|
||||||
seller->setLastName(val["last_name"]);
|
seller->setLastName(val["last_name"]);
|
||||||
seller->setFirstName(val["first_name"]);
|
seller->setFirstName(val["first_name"]);
|
||||||
|
@ -47,10 +44,9 @@ void JsonUtil::importSellers(const std::filesystem::path& filePath, Marketplace*
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there was no special seller "Sonderkonto" in import data, then create one
|
// If there was no special seller "Sonderkonto" in import data, then create one
|
||||||
auto specialSeller = market->findSellerWithUuid("11111111-1111-1111-1111-111111111111");
|
auto specialSeller = market->findSellerWithSellerNo(0);
|
||||||
if (!specialSeller) {
|
if (!specialSeller) {
|
||||||
auto seller = std::make_unique<Seller>();
|
auto seller = std::make_unique<Seller>();
|
||||||
seller->setUuidFromString("11111111-1111-1111-1111-111111111111");
|
|
||||||
seller->setSellerNo(0);
|
seller->setSellerNo(0);
|
||||||
seller->setLastName("Sonderkonto");
|
seller->setLastName("Sonderkonto");
|
||||||
seller->setFirstName("Sonderkonto");
|
seller->setFirstName("Sonderkonto");
|
||||||
|
@ -59,18 +55,20 @@ void JsonUtil::importSellers(const std::filesystem::path& filePath, Marketplace*
|
||||||
}
|
}
|
||||||
|
|
||||||
market->sortSellers();
|
market->sortSellers();
|
||||||
|
|
||||||
market->storeToDb();
|
market->storeToDb();
|
||||||
|
|
||||||
|
return market->getSellers().size() - 1; // minus 1 because we don't count the "special" seller
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonUtil::exportSales(const std::filesystem::path& filePath, Marketplace* market, int cashPointNo)
|
void JsonUtil::exportSales(const std::filesystem::path &filePath, Marketplace *market,
|
||||||
|
int cashPointNo)
|
||||||
{
|
{
|
||||||
json root;
|
json root;
|
||||||
std::ofstream file(filePath);
|
std::ofstream file(filePath);
|
||||||
|
|
||||||
root["source_no"] = cashPointNo;
|
root["source_no"] = cashPointNo;
|
||||||
|
|
||||||
for (const auto& sale : market->getSales()) {
|
for (const auto &sale : market->getSales()) {
|
||||||
if (sale->getSourceNo() != cashPointNo)
|
if (sale->getSourceNo() != cashPointNo)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -78,10 +76,10 @@ void JsonUtil::exportSales(const std::filesystem::path& filePath, Marketplace* m
|
||||||
newSale["uuid"] = sale->getUuidAsString();
|
newSale["uuid"] = sale->getUuidAsString();
|
||||||
newSale["timestamp"] = sale->getTimestamp();
|
newSale["timestamp"] = sale->getTimestamp();
|
||||||
|
|
||||||
for (const auto& article : sale->getArticles()) {
|
for (const auto &article : sale->getArticles()) {
|
||||||
json newArticle;
|
json newArticle;
|
||||||
newArticle["uuid"] = article->getUuidAsString();
|
newArticle["uuid"] = article->getUuidAsString();
|
||||||
newArticle["seller_uuid"] = article->getSeller()->getUuidAsString();
|
newArticle["seller_no"] = article->getSeller()->getSellerNo();
|
||||||
newArticle["desc"] = article->getDescription();
|
newArticle["desc"] = article->getDescription();
|
||||||
newArticle["price"] = article->getPrice();
|
newArticle["price"] = article->getPrice();
|
||||||
// newArticle["source_no"] = article->getSourceNo();
|
// newArticle["source_no"] = article->getSourceNo();
|
||||||
|
@ -96,33 +94,36 @@ void JsonUtil::exportSales(const std::filesystem::path& filePath, Marketplace* m
|
||||||
file << root.dump(4) << std::endl;
|
file << root.dump(4) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonUtil::importSales(const std::filesystem::path& filePath, Marketplace* market, int cashPointNo)
|
void JsonUtil::importSales(const std::filesystem::path &filePath, Marketplace *market,
|
||||||
|
int cashPointNo)
|
||||||
{
|
{
|
||||||
std::ifstream file(filePath);
|
std::ifstream file(filePath);
|
||||||
json jsonValues = json::parse(file);
|
json jsonValues = json::parse(file);
|
||||||
|
|
||||||
int source_no = jsonValues["source_no"];
|
int source_no = jsonValues["source_no"];
|
||||||
if (source_no == cashPointNo) {
|
if (source_no == cashPointNo) {
|
||||||
throw std::runtime_error("Die Kassen-Nr. der zu imporierenden Daten wird von dieser Kasse "
|
std::string ret = "Die Kassen-Nr. ";
|
||||||
"hier bereits verwendet.");
|
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"]);
|
market->setSalesToDelete(jsonValues["source_no"]);
|
||||||
market->storeToDb();
|
market->storeToDb();
|
||||||
|
|
||||||
for (const auto& valSale : jsonValues["sales"]) {
|
for (const auto &valSale : jsonValues["sales"]) {
|
||||||
auto sale = std::make_unique<Sale>();
|
auto sale = std::make_unique<Sale>();
|
||||||
sale->setUuidFromString(valSale["uuid"]);
|
sale->setUuidFromString(valSale["uuid"]);
|
||||||
sale->setSourceNo(jsonValues["source_no"]);
|
sale->setSourceNo(jsonValues["source_no"]);
|
||||||
sale->setTimestamp(valSale["timestamp"]);
|
sale->setTimestamp(valSale["timestamp"]);
|
||||||
for (const auto& valArticle : valSale["articles"]) {
|
for (const auto &valArticle : valSale["articles"]) {
|
||||||
auto article = std::make_unique<Article>();
|
auto article = std::make_unique<Article>();
|
||||||
article->setUuidFromString(valArticle["uuid"]);
|
article->setUuidFromString(valArticle["uuid"]);
|
||||||
article->setSourceNo(jsonValues["source_no"]);
|
article->setSourceNo(jsonValues["source_no"]);
|
||||||
article->setArticleNo(valArticle["article_no"]);
|
article->setArticleNo(valArticle["article_no"]);
|
||||||
article->setDescription(valArticle["desc"]);
|
article->setDescription(valArticle["desc"]);
|
||||||
article->setPrice(valArticle["price"]);
|
article->setPrice(valArticle["price"]);
|
||||||
auto seller = market->findSellerWithUuid(valArticle["seller_uuid"]);
|
auto seller = market->findSellerWithSellerNo(valArticle["seller_no"]);
|
||||||
if (seller == nullptr) {
|
if (seller == nullptr) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"Die zu importierenden Daten verweisen auf einen nicht vorhandenen Verkäufer. "
|
"Die zu importierenden Daten verweisen auf einen nicht vorhandenen Verkäufer. "
|
||||||
|
|
|
@ -3,16 +3,18 @@
|
||||||
|
|
||||||
#include "marketplace.h"
|
#include "marketplace.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class JsonUtil
|
class JsonUtil
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void exportSellers(const std::filesystem::path& filePath, Marketplace* market);
|
static void exportSellers(const std::filesystem::path &filePath, Marketplace *market);
|
||||||
static void importSellers(const std::filesystem::path& filePath, Marketplace* market);
|
static std::size_t importSellers(const std::filesystem::path &filePath, Marketplace *market);
|
||||||
static void exportSales(const std::filesystem::path& filePath, Marketplace* market, int cashPointNo);
|
static void exportSales(const std::filesystem::path &filePath, Marketplace *market,
|
||||||
static void importSales(const std::filesystem::path& filePath, Marketplace* market, int cashPointNo);
|
int cashPointNo);
|
||||||
|
static void importSales(const std::filesystem::path &filePath, Marketplace *market,
|
||||||
|
int cashPointNo);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3,19 +3,19 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
Marketplace::Marketplace()
|
Marketplace::Marketplace()
|
||||||
{
|
{
|
||||||
auto seller = std::make_unique<Seller>("Max", "Mustermann");
|
/*auto seller = std::make_unique<Seller>("Max", "Mustermann");
|
||||||
seller->createUuid();
|
seller->createUuid();
|
||||||
sellers_.push_back(std::move(seller));
|
sellers_.push_back(std::move(seller)); */
|
||||||
}
|
}
|
||||||
|
|
||||||
void Marketplace::storeToDb(bool onlyDelete)
|
void Marketplace::storeToDb(bool onlyDelete)
|
||||||
|
@ -25,22 +25,23 @@ void Marketplace::storeToDb(bool onlyDelete)
|
||||||
db.storeSales(sales_);
|
db.storeSales(sales_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Marketplace::loadFromDb()
|
Database::InitResult Marketplace::loadFromDb()
|
||||||
{
|
{
|
||||||
Database db;
|
Database db;
|
||||||
db.loadSellers(sellers_);
|
db.loadSellers(sellers_);
|
||||||
db.loadSales(sales_, sellers_);
|
db.loadSales(sales_, sellers_);
|
||||||
|
return db.getInitResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
SellersVec& Marketplace::getSellers() { return sellers_; }
|
SellersVec &Marketplace::getSellers() { return sellers_; }
|
||||||
|
|
||||||
SalesVec& Marketplace::getSales() { return sales_; }
|
SalesVec &Marketplace::getSales() { return sales_; }
|
||||||
|
|
||||||
int Marketplace::getNextSellerNo()
|
int Marketplace::getNextSellerNo()
|
||||||
{
|
{
|
||||||
auto iter = std::max_element(
|
auto iter = std::max_element(
|
||||||
sellers_.begin(), sellers_.end(),
|
sellers_.begin(), sellers_.end(),
|
||||||
[](const auto& a, const auto& b) -> bool { return a->getSellerNo() < b->getSellerNo(); });
|
[](const auto &a, const auto &b) -> bool { return a->getSellerNo() < b->getSellerNo(); });
|
||||||
if (iter == sellers_.end())
|
if (iter == sellers_.end())
|
||||||
return 1;
|
return 1;
|
||||||
return (*iter)->getSellerNo() + 1;
|
return (*iter)->getSellerNo() + 1;
|
||||||
|
@ -52,14 +53,14 @@ int Marketplace::getNextArticleNo()
|
||||||
int maxArtNoInBasket{0};
|
int maxArtNoInBasket{0};
|
||||||
|
|
||||||
auto iter = std::max_element(sellers_.begin(), sellers_.end(),
|
auto iter = std::max_element(sellers_.begin(), sellers_.end(),
|
||||||
[](const auto& a, const auto& b) -> bool {
|
[](const auto &a, const auto &b) -> bool {
|
||||||
return a->getMaxArticleNo() < b->getMaxArticleNo();
|
return a->getMaxArticleNo() < b->getMaxArticleNo();
|
||||||
});
|
});
|
||||||
if (iter != sellers_.end())
|
if (iter != sellers_.end())
|
||||||
maxArtNoInDb = (*iter)->getMaxArticleNo();
|
maxArtNoInDb = (*iter)->getMaxArticleNo();
|
||||||
|
|
||||||
auto iter2 =
|
auto iter2 =
|
||||||
std::max_element(basket_.begin(), basket_.end(), [](const auto& a, const auto& b) -> bool {
|
std::max_element(basket_.begin(), basket_.end(), [](const auto &a, const auto &b) -> bool {
|
||||||
return a->getArticleNo() < b->getArticleNo();
|
return a->getArticleNo() < b->getArticleNo();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -72,13 +73,13 @@ int Marketplace::getNextArticleNo()
|
||||||
int Marketplace::getNumSellersDelete()
|
int Marketplace::getNumSellersDelete()
|
||||||
{
|
{
|
||||||
int count = std::count_if(sellers_.begin(), sellers_.end(),
|
int count = std::count_if(sellers_.begin(), sellers_.end(),
|
||||||
[](const auto& a) { return a->getState() == Seller::State::DELETE; });
|
[](const auto &a) { return a->getState() == Seller::State::DELETE; });
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Marketplace::getNumArticlesSold()
|
int Marketplace::getNumArticlesSold()
|
||||||
{
|
{
|
||||||
int sum = std::accumulate(sellers_.begin(), sellers_.end(), 0, [](int a, const auto& seller) {
|
int sum = std::accumulate(sellers_.begin(), sellers_.end(), 0, [](int a, const auto &seller) {
|
||||||
return a + seller->numArticlesSold();
|
return a + seller->numArticlesSold();
|
||||||
});
|
});
|
||||||
return sum;
|
return sum;
|
||||||
|
@ -86,7 +87,7 @@ int Marketplace::getNumArticlesSold()
|
||||||
|
|
||||||
int Marketplace::getNumArticlesOffered()
|
int Marketplace::getNumArticlesOffered()
|
||||||
{
|
{
|
||||||
int sum = std::accumulate(sellers_.begin(), sellers_.end(), 0, [](int a, const auto& seller) {
|
int sum = std::accumulate(sellers_.begin(), sellers_.end(), 0, [](int a, const auto &seller) {
|
||||||
return a + seller->numArticlesOffered();
|
return a + seller->numArticlesOffered();
|
||||||
});
|
});
|
||||||
return sum;
|
return sum;
|
||||||
|
@ -94,19 +95,10 @@ int Marketplace::getNumArticlesOffered()
|
||||||
|
|
||||||
void Marketplace::sortSellers() { std::sort(sellers_.begin(), sellers_.end()); }
|
void Marketplace::sortSellers() { std::sort(sellers_.begin(), sellers_.end()); }
|
||||||
|
|
||||||
Seller* Marketplace::findSellerWithSellerNo(int sellerNo)
|
Seller *Marketplace::findSellerWithSellerNo(int sellerNo)
|
||||||
{
|
{
|
||||||
auto iter = std::find_if(sellers_.begin(), sellers_.end(),
|
auto iter = std::find_if(sellers_.begin(), sellers_.end(),
|
||||||
[sellerNo](const auto& a) { return a->getSellerNo() == sellerNo; });
|
[sellerNo](const auto &a) { return a->getSellerNo() == sellerNo; });
|
||||||
if (iter == sellers_.end())
|
|
||||||
return nullptr;
|
|
||||||
return (*iter).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
Seller* Marketplace::findSellerWithUuid(const std::string& uuid)
|
|
||||||
{
|
|
||||||
auto iter = std::find_if(sellers_.begin(), sellers_.end(),
|
|
||||||
[uuid](const auto& a) { return a->getUuidAsString() == uuid; });
|
|
||||||
if (iter == sellers_.end())
|
if (iter == sellers_.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return (*iter).get();
|
return (*iter).get();
|
||||||
|
@ -114,7 +106,8 @@ Seller* Marketplace::findSellerWithUuid(const std::string& uuid)
|
||||||
|
|
||||||
void Marketplace::addArticleToBasket(std::unique_ptr<Article> article)
|
void Marketplace::addArticleToBasket(std::unique_ptr<Article> article)
|
||||||
{
|
{
|
||||||
basket_.insert(basket_.begin(), std::move(article)); // article to the beginning of the basket vector
|
basket_.insert(basket_.begin(),
|
||||||
|
std::move(article)); // article to the beginning of the basket vector
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Marketplace::basketSize() { return basket_.size(); }
|
size_t Marketplace::basketSize() { return basket_.size(); }
|
||||||
|
@ -136,12 +129,12 @@ void Marketplace::finishCurrentSale(std::unique_ptr<Sale> sale)
|
||||||
storeToDb();
|
storeToDb();
|
||||||
}
|
}
|
||||||
|
|
||||||
BasketVec& Marketplace::getBasket() { return basket_; }
|
BasketVec &Marketplace::getBasket() { return basket_; }
|
||||||
|
|
||||||
int Marketplace::getBasketSumInCent()
|
int Marketplace::getBasketSumInCent()
|
||||||
{
|
{
|
||||||
int sum = std::accumulate(basket_.begin(), basket_.end(), 0,
|
int sum = std::accumulate(basket_.begin(), basket_.end(), 0,
|
||||||
[](int a, const auto& b) { return a + b->getPrice(); });
|
[](int a, const auto &b) { return a + b->getPrice(); });
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,39 +148,40 @@ std::string Marketplace::getBasketSumAsString()
|
||||||
void Marketplace::removeSale(boost::uuids::uuid uuid)
|
void Marketplace::removeSale(boost::uuids::uuid uuid)
|
||||||
{
|
{
|
||||||
sales_.erase(std::remove_if(sales_.begin(), sales_.end(),
|
sales_.erase(std::remove_if(sales_.begin(), sales_.end(),
|
||||||
[&uuid](const auto& a) { return a->getUuid() == uuid; }),
|
[&uuid](const auto &a) { return a->getUuid() == uuid; }),
|
||||||
sales_.end());
|
sales_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Marketplace::setSalesToDelete(int cashPointNo)
|
void Marketplace::setSalesToDelete(int cashPointNo)
|
||||||
{
|
{
|
||||||
std::for_each(sales_.begin(), sales_.end(), [cashPointNo](auto& sale) {
|
std::for_each(sales_.begin(), sales_.end(), [cashPointNo](auto &sale) {
|
||||||
if (sale->getSourceNo() == cashPointNo) {
|
if (sale->getSourceNo() == cashPointNo) {
|
||||||
sale->setState(Sale::State::DELETE);
|
sale->setState(Sale::State::DELETE);
|
||||||
for (auto& article : sale->getArticles()) {
|
for (auto &article : sale->getArticles()) {
|
||||||
article->setState(Article::State::DELETE);
|
article->setState(Article::State::DELETE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Marketplace::exportReportToCSV(const fs::path& filePath, int feeInPercent, int maxFeeInEuro)
|
void Marketplace::exportReportToCSV(const fs::path &filePath, int feeInPercent, int maxFeeInEuro)
|
||||||
{
|
{
|
||||||
const char delimiter = ',';
|
const char delimiter = ';';
|
||||||
std::ofstream file(filePath);
|
std::ofstream file(filePath);
|
||||||
|
|
||||||
file << "Verk.Nr." << delimiter << "Nachname" << delimiter << "Vorname" << delimiter
|
file << "Verk.Nr." << delimiter << "Nachname" << delimiter << "Vorname" << delimiter
|
||||||
<< "Anz. gemeldet" << delimiter << "Anz. verkauft" << delimiter << "Umsatz" << delimiter
|
<< "Anz. gemeldet" << delimiter << "Anz. verkauft" << delimiter << "Umsatz" << delimiter
|
||||||
<< "Auszahlung\n";
|
<< "Auszahlung\n";
|
||||||
|
|
||||||
for (const auto& seller : sellers_) {
|
for (const auto &seller : sellers_) {
|
||||||
file << seller->getSellerNo() << delimiter
|
file << seller->getSellerNo() << delimiter
|
||||||
<< escapeCsvValue(seller->getLastName(), delimiter) << delimiter
|
<< escapeCsvValue(seller->getLastName(), delimiter) << delimiter
|
||||||
<< escapeCsvValue(seller->getFirstName(), delimiter) << delimiter
|
<< escapeCsvValue(seller->getFirstName(), delimiter) << delimiter
|
||||||
<< seller->numArticlesOffered() << delimiter << seller->numArticlesSold() << delimiter
|
<< seller->numArticlesOffered() << delimiter << seller->numArticlesSold() << delimiter
|
||||||
<< escapeCsvValue(seller->sumAsString(), delimiter) << delimiter
|
<< escapeCsvValue(seller->sumAsString(), delimiter) << delimiter
|
||||||
<< escapeCsvValue(paymentAsString(seller->sumInCents(), feeInPercent, maxFeeInEuro * 100),
|
<< escapeCsvValue(
|
||||||
delimiter)
|
paymentAsString(seller->sumInCents(), feeInPercent, maxFeeInEuro * 100),
|
||||||
|
delimiter)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +189,7 @@ void Marketplace::exportReportToCSV(const fs::path& filePath, int feeInPercent,
|
||||||
int Marketplace::getOverallSumInCent()
|
int Marketplace::getOverallSumInCent()
|
||||||
{
|
{
|
||||||
int sum = std::accumulate(sellers_.begin(), sellers_.end(), 0,
|
int sum = std::accumulate(sellers_.begin(), sellers_.end(), 0,
|
||||||
[](int a, const auto& b) { return a + b->sumInCents(); });
|
[](int a, const auto &b) { return a + b->sumInCents(); });
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +202,7 @@ std::string Marketplace::getOverallSumAsString()
|
||||||
int Marketplace::getOverallPaymentInCent(int percent, int maxFee)
|
int Marketplace::getOverallPaymentInCent(int percent, int maxFee)
|
||||||
{
|
{
|
||||||
int sum = std::accumulate(
|
int sum = std::accumulate(
|
||||||
sellers_.begin(), sellers_.end(), 0, [percent, maxFee](int a, const auto& b) {
|
sellers_.begin(), sellers_.end(), 0, [percent, maxFee](int a, const auto &b) {
|
||||||
return a + b->sumInCents() - marketFee(b->sumInCents(), percent, maxFee);
|
return a + b->sumInCents() - marketFee(b->sumInCents(), percent, maxFee);
|
||||||
});
|
});
|
||||||
return sum;
|
return sum;
|
||||||
|
@ -246,7 +240,7 @@ std::string paymentAsString(int sumInCent, int percent, int maxFeeInCent)
|
||||||
return formatCentAsEuroString(sumInCent - marketFee(sumInCent, percent, maxFeeInCent));
|
return formatCentAsEuroString(sumInCent - marketFee(sumInCent, percent, maxFeeInCent));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string escapeCsvValue(const std::string& value, const char delimiter)
|
std::string escapeCsvValue(const std::string &value, const char delimiter)
|
||||||
{
|
{
|
||||||
std::stringstream output;
|
std::stringstream output;
|
||||||
bool containsDelim{false};
|
bool containsDelim{false};
|
||||||
|
@ -256,7 +250,7 @@ std::string escapeCsvValue(const std::string& value, const char delimiter)
|
||||||
output << '"';
|
output << '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& symbol : value) {
|
for (auto &symbol : value) {
|
||||||
if (symbol == '"') {
|
if (symbol == '"') {
|
||||||
output << '"' << symbol;
|
output << '"' << symbol;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define MARKETPLACE_H
|
#define MARKETPLACE_H
|
||||||
|
|
||||||
#include "article.h"
|
#include "article.h"
|
||||||
|
#include "database.h"
|
||||||
#include "sale.h"
|
#include "sale.h"
|
||||||
#include "seller.h"
|
#include "seller.h"
|
||||||
|
|
||||||
|
@ -19,26 +20,26 @@ using BasketVec = std::vector<std::unique_ptr<Article>>;
|
||||||
|
|
||||||
class Marketplace
|
class Marketplace
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Marketplace();
|
Marketplace();
|
||||||
|
|
||||||
void storeToDb(bool onlyDelete = false);
|
void storeToDb(bool onlyDelete = false);
|
||||||
void loadFromDb();
|
Database::InitResult loadFromDb();
|
||||||
|
|
||||||
SellersVec& getSellers();
|
SellersVec &getSellers();
|
||||||
SalesVec& getSales();
|
SalesVec &getSales();
|
||||||
int getNextSellerNo();
|
int getNextSellerNo();
|
||||||
int getNextArticleNo();
|
int getNextArticleNo();
|
||||||
int getNumSellersDelete();
|
int getNumSellersDelete();
|
||||||
int getNumArticlesSold();
|
int getNumArticlesSold();
|
||||||
int getNumArticlesOffered();
|
int getNumArticlesOffered();
|
||||||
BasketVec& getBasket();
|
BasketVec &getBasket();
|
||||||
int getBasketSumInCent();
|
int getBasketSumInCent();
|
||||||
std::string getBasketSumAsString();
|
std::string getBasketSumAsString();
|
||||||
|
|
||||||
void sortSellers();
|
void sortSellers();
|
||||||
Seller* findSellerWithSellerNo(int sellerNo);
|
Seller *findSellerWithSellerNo(int sellerNo);
|
||||||
Seller* findSellerWithUuid(const std::string& uuid);
|
Seller *findSellerWithUuid(const std::string &uuid);
|
||||||
void addArticleToBasket(std::unique_ptr<Article> article);
|
void addArticleToBasket(std::unique_ptr<Article> article);
|
||||||
size_t basketSize();
|
size_t basketSize();
|
||||||
void finishCurrentSale(std::unique_ptr<Sale> sale);
|
void finishCurrentSale(std::unique_ptr<Sale> sale);
|
||||||
|
@ -53,12 +54,12 @@ class Marketplace
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void exportReportToCSV(const std::filesystem::path& filePath, int feeInPercent,
|
void exportReportToCSV(const std::filesystem::path &filePath, int feeInPercent,
|
||||||
int maxFeeInEuro);
|
int maxFeeInEuro);
|
||||||
|
|
||||||
friend class ExcelReader;
|
friend class ExcelReader;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SellersVec sellers_;
|
SellersVec sellers_;
|
||||||
SalesVec sales_;
|
SalesVec sales_;
|
||||||
BasketVec basket_;
|
BasketVec basket_;
|
||||||
|
@ -67,6 +68,6 @@ class Marketplace
|
||||||
double marketFee(int sumInCent, int percent, int maxFeeInCent);
|
double marketFee(int sumInCent, int percent, int maxFeeInCent);
|
||||||
std::string marketFeeAsString(int sumInCent, int percent, int maxFeeInCent);
|
std::string marketFeeAsString(int sumInCent, int percent, int maxFeeInCent);
|
||||||
std::string paymentAsString(int sumInCent, int percent, int maxFeeInCent);
|
std::string paymentAsString(int sumInCent, int percent, int maxFeeInCent);
|
||||||
std::string escapeCsvValue(const std::string& value, const char delimiter);
|
std::string escapeCsvValue(const std::string &value, const char delimiter);
|
||||||
|
|
||||||
#endif
|
#endif
|
13
src/core/meson.build
Normal file
13
src/core/meson.build
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
boost = dependency('boost', modules: ['date_time'], static: true)
|
||||||
|
xlnt = dependency('xlnt')
|
||||||
|
sqlite = dependency('sqlite3')
|
||||||
|
|
||||||
|
src = ['database.cpp', 'entity.cpp', 'entityint.cpp', 'entityuuid.cpp',
|
||||||
|
'seller.cpp', 'article.cpp', 'sale.cpp', 'marketplace.cpp',
|
||||||
|
'excelreader.cpp', 'csvreader.cpp', 'jsonutil.cpp', 'utils.cpp']
|
||||||
|
|
||||||
|
core_inc = include_directories('..')
|
||||||
|
|
||||||
|
core_lib = static_library('core', src, dependencies: [boost, xlnt, sqlite, nlohmann_lib, csv_dep])
|
||||||
|
|
||||||
|
core_dep = declare_dependency(link_with: core_lib, include_directories : core_inc)
|
|
@ -3,43 +3,41 @@
|
||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
void Sale::addArticle(Article* articlePtr)
|
void Sale::addArticle(Article *articlePtr)
|
||||||
{
|
{
|
||||||
articlePtr->setSale(this);
|
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)
|
void Sale::removeArticle(const Article *articlePtr)
|
||||||
{
|
{
|
||||||
/* auto it = std::find_if(articles_.begin(), articles_.end(),
|
auto it = std::find(m_articles.begin(), m_articles.end(), articlePtr);
|
||||||
[&articlePtr](auto art) { return art.get() == articlePtr; }); */
|
|
||||||
auto it = std::find(articles_.begin(), articles_.end(), articlePtr);
|
|
||||||
|
|
||||||
if (it != articles_.end()) {
|
if (it != m_articles.end()) {
|
||||||
(*it)->setSale(nullptr);
|
(*it)->setSale(nullptr);
|
||||||
(*it)->setState(
|
(*it)->setState(
|
||||||
Article::State::DELETE); // since we only have ad-hoc articles, that have all been sold
|
Article::State::DELETE); // since we only have ad-hoc articles, that have all been sold
|
||||||
articles_.erase(it);
|
m_articles.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Sale::sumInCents()
|
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(); });
|
[](int a, const Article *b) { return a + b->getPrice(); });
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Sale::sumAsString() { return formatCentAsEuroString(sumInCents()); }
|
std::string Sale::sumAsString() { return formatCentAsEuroString(sumInCents()); }
|
||||||
|
|
||||||
std::string Sale::getTimestamp() const { return 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
|
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);
|
return boost::posix_time::to_simple_string(time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,27 +11,30 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
using ArticlesVec = std::vector<Article*>;
|
using ArticlesVec = std::vector<Article *>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Sale : public Entity
|
class Sale : public EntityUuid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void addArticle(Article* articlePtr);
|
Sale() = default;
|
||||||
void setTimestamp(const std::string& timestamp);
|
Sale(const Sale &) = delete;
|
||||||
|
virtual ~Sale() = default;
|
||||||
|
void addArticle(Article *articlePtr);
|
||||||
|
void setTimestamp(const std::string ×tamp);
|
||||||
|
|
||||||
ArticlesVec& getArticles();
|
ArticlesVec &getArticles();
|
||||||
std::string getTimestamp() const;
|
std::string getTimestamp() const;
|
||||||
std::string getTimestampFormatted() const;
|
std::string getTimestampFormatted() const;
|
||||||
int sumInCents();
|
int sumInCents();
|
||||||
std::string sumAsString();
|
std::string sumAsString();
|
||||||
|
|
||||||
void removeArticle(const Article* articlePtr);
|
void removeArticle(const Article *articlePtr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string timestamp_{
|
std::string m_timestamp{
|
||||||
boost::posix_time::to_iso_extended_string(boost::posix_time::second_clock::local_time())};
|
boost::posix_time::to_iso_extended_string(boost::posix_time::second_clock::local_time())};
|
||||||
mutable ArticlesVec articles_{};
|
mutable ArticlesVec m_articles{};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -5,50 +5,49 @@
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
Seller::Seller(const std::string& firstName, const std::string& lastName, int sellerNo,
|
Seller::Seller(const std::string &firstName, const std::string &lastName, int sellerNo,
|
||||||
int numArticlesOffered)
|
int numArticlesOffered)
|
||||||
: Entity()
|
: EntityInt(sellerNo)
|
||||||
{
|
{
|
||||||
firstName_ = firstName;
|
m_firstName = firstName;
|
||||||
lastName_ = lastName;
|
m_lastName = lastName;
|
||||||
sellerNo_ = sellerNo;
|
m_numArticlesOffered = numArticlesOffered;
|
||||||
numArticlesOffered_ = numArticlesOffered;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Seller::setSellerNo(int seller_no) { sellerNo_ = seller_no; }
|
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)
|
void Seller::addArticle(std::unique_ptr<Article> article)
|
||||||
{
|
{
|
||||||
article->setSeller(this);
|
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 sellerNo_; }
|
int Seller::getSellerNo() const { return getId(); }
|
||||||
|
|
||||||
std::string Seller::getSellerNoAsString() const
|
std::string Seller::getSellerNoAsString() const
|
||||||
{
|
{
|
||||||
std::stringstream selNoStr;
|
std::stringstream selNoStr;
|
||||||
|
|
||||||
selNoStr << std::setfill('0') << std::setw(3) << sellerNo_;
|
selNoStr << std::setfill('0') << std::setw(3) << m_id;
|
||||||
|
|
||||||
return selNoStr.str();
|
return selNoStr.str();
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Article*> Seller::getArticles(bool onlySold) const
|
std::vector<Article *> Seller::getArticles(bool onlySold) const
|
||||||
{
|
{
|
||||||
std::vector<Article*> articles;
|
std::vector<Article *> articles;
|
||||||
for (const auto& article : articles_) {
|
for (const auto &article : m_articles) {
|
||||||
if (onlySold && article->isSold()) {
|
if (onlySold && article->isSold()) {
|
||||||
articles.push_back(article.get());
|
articles.push_back(article.get());
|
||||||
} else if (!onlySold) {
|
} else if (!onlySold) {
|
||||||
|
@ -58,54 +57,54 @@ std::vector<Article*> Seller::getArticles(bool onlySold) const
|
||||||
return articles;
|
return articles;
|
||||||
}
|
}
|
||||||
|
|
||||||
Article* Seller::getArticleByUuid(const std::string& uuidString)
|
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;
|
return art->getUuidAsString() == uuidString;
|
||||||
});
|
});
|
||||||
if (iter == articles_.end())
|
if (iter == m_articles.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return (*iter).get();
|
return (*iter).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Seller::numArticlesSold() const { return static_cast<int>(getArticles(true).size()); }
|
int Seller::numArticlesSold() const { return static_cast<int>(getArticles(true).size()); }
|
||||||
|
|
||||||
int Seller::numArticlesOffered() const { return numArticlesOffered_; }
|
int Seller::numArticlesOffered() const { return m_numArticlesOffered; }
|
||||||
|
|
||||||
int Seller::getMaxArticleNo() const
|
int Seller::getMaxArticleNo() const
|
||||||
{
|
{
|
||||||
auto iter = std::max_element(
|
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(); });
|
[](const auto &a, const auto &b) -> bool { return a->getArticleNo() < b->getArticleNo(); });
|
||||||
if (iter == articles_.end())
|
if (iter == m_articles.end())
|
||||||
return 0;
|
return 0;
|
||||||
return (*iter)->getArticleNo();
|
return (*iter)->getArticleNo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Seller::cleanupArticles()
|
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) {
|
[](const auto &article) {
|
||||||
return article->getState() == Article::State::DELETE;
|
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);
|
article->setState(Article::State::OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Seller::sumInCents()
|
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(); });
|
[](int a, const auto &b) { return a + b->getPrice(); });
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Seller::sumAsString() { return formatCentAsEuroString(sumInCents()); }
|
std::string Seller::sumAsString() { return formatCentAsEuroString(sumInCents()); }
|
||||||
|
|
||||||
bool operator<(const Seller& li, const Seller& re) { return li.sellerNo_ < re.sellerNo_; }
|
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)
|
bool operator<(const std::unique_ptr<Seller> &li, const std::unique_ptr<Seller> &re)
|
||||||
{
|
{
|
||||||
return li->sellerNo_ < re->sellerNo_;
|
return li->m_id < re->m_id;
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
#define SELLER_H
|
#define SELLER_H
|
||||||
|
|
||||||
#include "article.h"
|
#include "article.h"
|
||||||
#include "entity.h"
|
#include "entityint.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -10,17 +10,18 @@
|
||||||
|
|
||||||
// class Article;
|
// class Article;
|
||||||
|
|
||||||
class Seller : public Entity
|
class Seller : public EntityInt
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Seller() = default;
|
Seller() = default;
|
||||||
// virtual ~Seller() = default;
|
Seller(const Seller &) = delete;
|
||||||
Seller(const std::string& firstName, const std::string& lastName, int sellerNo = 0,
|
virtual ~Seller() = default;
|
||||||
|
Seller(const std::string &firstName, const std::string &lastName, int sellerNo = 0,
|
||||||
int numArticlesOffered = 0);
|
int numArticlesOffered = 0);
|
||||||
|
|
||||||
void setSellerNo(int sellerNo);
|
void setSellerNo(int sellerNo);
|
||||||
void setFirstName(const std::string& firstName);
|
void setFirstName(const std::string &firstName);
|
||||||
void setLastName(const std::string& lastName);
|
void setLastName(const std::string &lastName);
|
||||||
void setNumArticlesOffered(int number);
|
void setNumArticlesOffered(int number);
|
||||||
void addArticle(std::unique_ptr<Article> article);
|
void addArticle(std::unique_ptr<Article> article);
|
||||||
void cleanupArticles();
|
void cleanupArticles();
|
||||||
|
@ -31,22 +32,20 @@ class Seller : public Entity
|
||||||
std::string getSellerNoAsString() const;
|
std::string getSellerNoAsString() const;
|
||||||
int numArticlesOffered() const;
|
int numArticlesOffered() const;
|
||||||
int numArticlesSold() const;
|
int numArticlesSold() const;
|
||||||
// int numArticlesTotal() const;
|
std::vector<Article *> getArticles(bool onlySold = true) const;
|
||||||
std::vector<Article*> getArticles(bool onlySold = true) const;
|
Article *getArticleByUuid(const std::string &uuidString);
|
||||||
Article* getArticleByUuid(const std::string& uuidString);
|
|
||||||
int getMaxArticleNo() const;
|
int getMaxArticleNo() const;
|
||||||
int sumInCents();
|
int sumInCents();
|
||||||
std::string sumAsString();
|
std::string sumAsString();
|
||||||
|
|
||||||
friend bool operator<(const Seller& li, const Seller& re);
|
friend bool operator<(const Seller &li, const Seller &re);
|
||||||
friend bool operator<(const std::unique_ptr<Seller>& li, const std::unique_ptr<Seller>& re);
|
friend bool operator<(const std::unique_ptr<Seller> &li, const std::unique_ptr<Seller> &re);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int sellerNo_{-1};
|
int m_numArticlesOffered{};
|
||||||
int numArticlesOffered_{};
|
std::string m_firstName{};
|
||||||
std::string firstName_{};
|
std::string m_lastName{};
|
||||||
std::string lastName_{};
|
std::vector<std::unique_ptr<Article>> m_articles{};
|
||||||
std::vector<std::unique_ptr<Article>> articles_{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,46 +1,70 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <clocale>
|
||||||
|
#include <format>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
//using namespace fmt;
|
||||||
|
|
||||||
std::string formatCentAsEuroString(const int cent, int width)
|
std::string formatCentAsEuroString(const int cent, int width)
|
||||||
{
|
{
|
||||||
std::stringstream currStream;
|
/*std::stringstream currStream;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::locale myLocale("de_DE.utf8");
|
std::locale myLocale("de_DE.utf8");
|
||||||
currStream.imbue(myLocale);
|
currStream.imbue(myLocale);
|
||||||
|
std::cout << ">>> " << fmt::format(myLocale, "{:6.2Lf}", 1.12345) << '\n';
|
||||||
currStream << std::right << std::setw(width) << std::showbase
|
currStream << std::right << std::setw(width) << std::showbase
|
||||||
<< std::put_money(cent, false);
|
<< std::put_money(cent, false);
|
||||||
} catch (std::runtime_error& err) {
|
} catch (std::runtime_error &err) {
|
||||||
currStream << std::fixed << std::setw(width >= 4 ? width - 4 : width)
|
currStream << std::fixed << std::setw(width >= 4 ? width - 4 : width)
|
||||||
<< std::setprecision(2) << cent / 100.0L << " €";
|
<< std::setprecision(2) << cent / 100.0L << " €";
|
||||||
}
|
}
|
||||||
|
|
||||||
return currStream.str();
|
return currStream.str();*/
|
||||||
|
|
||||||
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
|
std::locale myLocale;
|
||||||
|
#else
|
||||||
|
std::locale myLocale{"de_DE.utf8"};
|
||||||
|
#endif
|
||||||
|
return std::format(myLocale, "{:{}.2Lf} €", cent / 100.0L, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<PrinterDevice> convertToPosPrinterDevice(const std::string& device,
|
std::string <rim(std::string &str, const std::string &chars)
|
||||||
const std::string& endpoint)
|
|
||||||
{
|
{
|
||||||
if (device.empty()) {
|
str.erase(0, str.find_first_not_of(chars));
|
||||||
return std::nullopt;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrinterDevice printerDevice;
|
std::string &rtrim(std::string &str, const std::string &chars)
|
||||||
std::string delimiter = ":";
|
{
|
||||||
try {
|
str.erase(str.find_last_not_of(chars) + 1);
|
||||||
printerDevice.idVendor = std::stoi(device.substr(0, device.find(delimiter)), 0, 16);
|
return str;
|
||||||
printerDevice.idProduct = std::stoi(device.substr(device.find(delimiter) + 1), 0, 16);
|
}
|
||||||
if (endpoint.empty()) {
|
|
||||||
printerDevice.endpoint = 0x03;
|
std::string &trim(std::string &str, const std::string &chars)
|
||||||
} else {
|
{
|
||||||
printerDevice.endpoint = std::stoi(endpoint, 0, 16);
|
return ltrim(rtrim(str, chars), chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (std::exception& ex) {
|
bool case_insensitive_match(std::string s1, std::string s2)
|
||||||
throw ex;
|
{
|
||||||
}
|
// convert s1 and s2 into lower case strings
|
||||||
|
transform(s1.begin(), s1.end(), s1.begin(), ::tolower);
|
||||||
return printerDevice;
|
transform(s2.begin(), s2.end(), s2.begin(), ::tolower);
|
||||||
|
if (s1.compare(s2) == 0)
|
||||||
|
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();
|
||||||
}
|
}
|
|
@ -1,14 +1,15 @@
|
||||||
#ifndef UTILS_H
|
#ifndef CORE_UTILS_H
|
||||||
#define UTILS_H
|
#define CORE_UTILS_H
|
||||||
|
|
||||||
#include "posprinter.h"
|
|
||||||
|
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
std::string formatCentAsEuroString(const int cent, int width = 10);
|
std::string formatCentAsEuroString(const int cent, int width = 6);
|
||||||
std::optional<PrinterDevice> convertToPosPrinterDevice(const std::string& vendor,
|
std::string <rim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
|
||||||
const std::string& endpoint);
|
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
|
#endif
|
||||||
|
|
|
@ -8,8 +8,14 @@ set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
# Find the QtWidgets library
|
# Find the QtWidgets library
|
||||||
find_package(Qt5Widgets CONFIG REQUIRED)
|
find_package(Qt6 COMPONENTS Widgets Network PrintSupport CONFIG REQUIRED)
|
||||||
find_package(Qt5PrintSupport CONFIG REQUIRED)
|
#find_package(Qt5Widgets CONFIG REQUIRED)
|
||||||
|
#find_package(Qt5PrintSupport CONFIG REQUIRED)
|
||||||
|
|
||||||
|
# For SingleApplication:
|
||||||
|
#find_package(Qt5Network CONFIG REQUIRED)
|
||||||
|
set(QAPPLICATION_CLASS QApplication)
|
||||||
|
add_compile_definitions(QAPPLICATION_CLASS=${QAPPLICATION_CLASS})
|
||||||
|
|
||||||
set(GUI_SOURCES
|
set(GUI_SOURCES
|
||||||
kima2.cpp
|
kima2.cpp
|
||||||
|
@ -28,11 +34,16 @@ set(GUI_SOURCES
|
||||||
settingsdialog.cpp
|
settingsdialog.cpp
|
||||||
settingsdialog.ui
|
settingsdialog.ui
|
||||||
../../kima2.qrc
|
../../kima2.qrc
|
||||||
|
${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git/singleapplication.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git/singleapplication_p.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(kima2 ${GUI_SOURCES} kima2.rc)
|
add_executable(kima2 ${GUI_SOURCES} kima2.rc)
|
||||||
target_include_directories(kima2 PRIVATE ${PROJECT_BINARY_DIR})
|
target_include_directories(kima2 PRIVATE ${PROJECT_BINARY_DIR})
|
||||||
target_link_libraries(kima2 core printer Qt5::Widgets Qt5::PrintSupport stdc++fs)
|
target_include_directories(kima2 PRIVATE ${PROJECT_SOURCE_DIR}/subprojects/singleapplication/singleapplication.git)
|
||||||
|
# target_link_libraries(kima2 core printer Qt5::Widgets Qt5::PrintSupport Qt5::Network stdc++fs)
|
||||||
|
target_link_libraries(kima2 core printer Qt::Core Qt::PrintSupport Qt::Network)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set_target_properties(kima2 PROPERTIES LINK_FLAGS "-mwindows")
|
set_target_properties(kima2 PROPERTIES LINK_FLAGS "-mwindows")
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
#include "basketmodel.h"
|
#include "basketmodel.h"
|
||||||
|
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QSettings>
|
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
BasketModel::BasketModel(Marketplace* market, QObject* parent)
|
BasketModel::BasketModel(Marketplace* market, QObject* parent)
|
||||||
: QAbstractTableModel(parent), marketplace_(market)
|
: QAbstractTableModel(parent), m_marketplace(market)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int BasketModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
|
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; }
|
int BasketModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 4; }
|
||||||
|
@ -22,7 +22,7 @@ QVariant BasketModel::data(const QModelIndex& index, int role) const
|
||||||
QFont myFont;
|
QFont myFont;
|
||||||
|
|
||||||
QFont myFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
QFont myFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
||||||
if (myFixedFont.fixedPitch() == false) {
|
if (myFixedFont.fixedPitch() == false) {
|
||||||
myFixedFont.setFamily("monospace");
|
myFixedFont.setFamily("monospace");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +46,10 @@ QVariant BasketModel::data(const QModelIndex& index, int role) const
|
||||||
if (role != Qt::DisplayRole)
|
if (role != Qt::DisplayRole)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (marketplace_->basketSize() == 0)
|
if (m_marketplace->basketSize() == 0)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
Article* article = marketplace_->getBasket().at(index.row()).get();
|
Article* article = m_marketplace->getBasket().at(index.row()).get();
|
||||||
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -92,45 +92,45 @@ QVariant BasketModel::headerData(int section, Qt::Orientation orientation, int r
|
||||||
|
|
||||||
void BasketModel::addArticle(Seller* seller, int price, const std::string& desc)
|
void BasketModel::addArticle(Seller* seller, int price, const std::string& desc)
|
||||||
{
|
{
|
||||||
emit beginInsertRows(QModelIndex(), marketplace_->getBasket().size(),
|
emit beginInsertRows(QModelIndex(), m_marketplace->getBasket().size(),
|
||||||
marketplace_->getBasket().size());
|
m_marketplace->getBasket().size());
|
||||||
auto article = std::make_unique<Article>(price);
|
auto article = std::make_unique<Article>(price);
|
||||||
article->createUuid();
|
article->createUuid();
|
||||||
article->setDescription(desc);
|
article->setDescription(desc);
|
||||||
article->setArticleNo(marketplace_->getNextArticleNo());
|
article->setArticleNo(m_marketplace->getNextArticleNo());
|
||||||
article->setSourceNo(QSettings().value("global/cashPointNo").toInt());
|
article->setSourceNo(QSettings().value("global/cashPointNo").toInt());
|
||||||
article->setSeller(seller);
|
article->setSeller(seller);
|
||||||
marketplace_->addArticleToBasket(std::move(article));
|
m_marketplace->addArticleToBasket(std::move(article));
|
||||||
emit endInsertRows();
|
emit endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasketModel::finishSale()
|
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>();
|
auto sale = std::make_unique<Sale>();
|
||||||
sale->createUuid();
|
sale->createUuid();
|
||||||
sale->setSourceNo(QSettings().value("global/cashPointNo").toInt());
|
sale->setSourceNo(QSettings().value("global/cashPointNo").toInt());
|
||||||
marketplace_->finishCurrentSale(std::move(sale));
|
m_marketplace->finishCurrentSale(std::move(sale));
|
||||||
emit endRemoveRows();
|
emit endRemoveRows();
|
||||||
emit basketDataChanged();
|
emit basketDataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasketModel::cancelSale()
|
void BasketModel::cancelSale()
|
||||||
{
|
{
|
||||||
emit beginRemoveRows(QModelIndex(), 0, marketplace_->getBasket().size() - 1);
|
emit beginRemoveRows(QModelIndex(), 0, m_marketplace->getBasket().size() - 1);
|
||||||
marketplace_->getBasket().clear();
|
m_marketplace->getBasket().clear();
|
||||||
emit endRemoveRows();
|
emit endRemoveRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BasketModel::removeRows(int row, int count, const QModelIndex& parent)
|
bool BasketModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||||
{
|
{
|
||||||
auto article = marketplace_->getBasket().at(row).get();
|
auto article = m_marketplace->getBasket().at(row).get();
|
||||||
|
|
||||||
emit beginRemoveRows(parent, row, row + count - 1);
|
emit beginRemoveRows(parent, row, row + count - 1);
|
||||||
marketplace_->getBasket().erase(
|
m_marketplace->getBasket().erase(
|
||||||
std::remove_if(marketplace_->getBasket().begin(), marketplace_->getBasket().end(),
|
std::remove_if(m_marketplace->getBasket().begin(), m_marketplace->getBasket().end(),
|
||||||
[&article](const auto& a) { return a->getUuid() == article->getUuid(); }),
|
[&article](const auto& a) { return a->getUuid() == article->getUuid(); }),
|
||||||
marketplace_->getBasket().end());
|
m_marketplace->getBasket().end());
|
||||||
emit endRemoveRows();
|
emit endRemoveRows();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#ifndef BASKET_MODEL_H
|
#ifndef BASKET_MODEL_H
|
||||||
#define BASKET_MODEL_H
|
#define BASKET_MODEL_H
|
||||||
|
|
||||||
#include <marketplace.h>
|
#include <core/marketplace.h>
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
class BasketModel : public QAbstractTableModel
|
class BasketModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BasketModel(Marketplace* market, QObject* parent = nullptr);
|
explicit BasketModel(Marketplace* market, QObject* parent = nullptr);
|
||||||
|
@ -15,19 +15,16 @@ class BasketModel : public QAbstractTableModel
|
||||||
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
//virtual Qt::ItemFlags flags(const QModelIndex& index) const override;
|
|
||||||
//virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
|
|
||||||
//virtual bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
|
|
||||||
void addArticle(Seller* seller, int price, const std::string& desc);
|
void addArticle(Seller* seller, int price, const std::string& desc);
|
||||||
void finishSale();
|
void finishSale();
|
||||||
void cancelSale();
|
void cancelSale();
|
||||||
virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
|
virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void basketDataChanged();
|
void basketDataChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Marketplace* marketplace_;
|
Marketplace* m_marketplace;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -6,26 +6,27 @@
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QSharedMemory>
|
||||||
|
#include <QStyleFactory>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
#include <singleapplication.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication kimaApp{argc, argv};
|
SingleApplication kimaApp(argc, argv, false, SingleApplication::Mode::User | SingleApplication::ExcludeAppPath | SingleApplication::ExcludeAppVersion);
|
||||||
|
|
||||||
// QCoreApplication::setOrganizationName("RustySoft");
|
// QCoreApplication::setOrganizationName("RustySoft");
|
||||||
QCoreApplication::setOrganizationDomain("rustysoft.de");
|
QCoreApplication::setOrganizationDomain("rustysoft.de");
|
||||||
QCoreApplication::setApplicationName("kima2");
|
QCoreApplication::setApplicationName("kima2");
|
||||||
|
|
||||||
QTranslator qTranslator;
|
QTranslator qtTranslator;
|
||||||
QLocale german(QLocale::German);
|
|
||||||
#ifdef __linux__
|
if (qtTranslator.load(QLocale::system(), u"qtbase"_qs, u"_"_qs,
|
||||||
qTranslator.load("qt_" + german.name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
|
||||||
#endif
|
kimaApp.installTranslator(&qtTranslator);
|
||||||
#ifdef _WIN32
|
}
|
||||||
qTranslator.load("qt_" + german.name(),
|
|
||||||
QApplication::applicationDirPath() + QDir::separator() + "translations");
|
|
||||||
#endif
|
|
||||||
kimaApp.installTranslator(&qTranslator);
|
|
||||||
|
|
||||||
QSettings settings{};
|
QSettings settings{};
|
||||||
while (!settings.contains("global/cashPointNo")) {
|
while (!settings.contains("global/cashPointNo")) {
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include "basketmodel.h"
|
#include "basketmodel.h"
|
||||||
#include "config.h"
|
|
||||||
#include "jsonutil.h"
|
|
||||||
#include "pricedialog.h"
|
#include "pricedialog.h"
|
||||||
#include "reportdialog.h"
|
#include "reportdialog.h"
|
||||||
#include "salemodel.h"
|
#include "salemodel.h"
|
||||||
#include "sellerdialog.h"
|
#include "sellerdialog.h"
|
||||||
#include "settingsdialog.h"
|
#include "settingsdialog.h"
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <utils.h>
|
#include <core/csvreader.h>
|
||||||
|
#include <core/jsonutil.h>
|
||||||
#include <excelreader.h>
|
#include <core/utils.h>
|
||||||
#include <posprinter.h>
|
#include <printer/posprinter.h>
|
||||||
|
#include <printer/utils.h>
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
@ -30,23 +31,31 @@ constexpr int STATUSBAR_TIMEOUT = 5000;
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
{
|
{
|
||||||
ui_.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
marketplace_ = std::make_unique<Marketplace>();
|
m_marketplace = std::make_unique<Marketplace>();
|
||||||
marketplace_->loadFromDb();
|
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 "
|
||||||
|
"umbenannt und eine <b>neue</b> Datei wurde erstellt.")
|
||||||
|
.exec();
|
||||||
|
}
|
||||||
statusBar()->showMessage("Gespeicherte Daten wurden geladen.", STATUSBAR_TIMEOUT);
|
statusBar()->showMessage("Gespeicherte Daten wurden geladen.", STATUSBAR_TIMEOUT);
|
||||||
|
|
||||||
BasketModel* model = new BasketModel(getMarketplace(), ui_.basketView);
|
BasketModel *model = new BasketModel(getMarketplace(), m_ui.basketView);
|
||||||
ui_.basketView->setModel(model);
|
m_ui.basketView->setModel(model);
|
||||||
ui_.basketView->setColumnHidden(0, true); // hide the uuid
|
m_ui.basketView->setColumnHidden(0, true); // hide the uuid
|
||||||
|
|
||||||
setWindowTitle("KIMA2 - Kasse Nr. " + QSettings().value("global/cashPointNo").toString());
|
setWindowTitle("KIMA2 - Kasse Nr. " + QSettings().value("global/cashPointNo").toString());
|
||||||
|
|
||||||
|
m_ui.salesView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
setSaleModel();
|
setSaleModel();
|
||||||
|
|
||||||
connect(ui_.actionQuit, &QAction::triggered, qApp, QApplication::quit);
|
connect(m_ui.actionQuit, &QAction::triggered, qApp, QApplication::closeAllWindows,
|
||||||
connect(ui_.newAction, &QAction::triggered, this, [=]() {
|
Qt::QueuedConnection);
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
auto dlgResult =
|
auto dlgResult =
|
||||||
|
@ -58,46 +67,45 @@ MainWindow::MainWindow()
|
||||||
if (dlgResult == QMessageBox::No)
|
if (dlgResult == QMessageBox::No)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
delete ui_.salesView->model();
|
delete m_ui.salesView->model();
|
||||||
dynamic_cast<BasketModel*>(ui_.basketView->model())->cancelSale();
|
dynamic_cast<BasketModel *>(m_ui.basketView->model())->cancelSale();
|
||||||
marketplace_->clear();
|
m_marketplace->clear();
|
||||||
setSaleModel();
|
setSaleModel();
|
||||||
updateStatLabel();
|
updateStatLabel();
|
||||||
});
|
});
|
||||||
|
|
||||||
ui_.sellerNoEdit->installEventFilter(this);
|
m_ui.sellerNoEdit->installEventFilter(this);
|
||||||
ui_.givenSpinBox->installEventFilter(this);
|
m_ui.givenSpinBox->installEventFilter(this);
|
||||||
|
|
||||||
connect(ui_.actionEditSeller, &QAction::triggered, this,
|
connect(m_ui.actionEditSeller, &QAction::triggered, this,
|
||||||
&MainWindow::onActionEditSellerTriggered);
|
&MainWindow::onActionEditSellerTriggered);
|
||||||
connect(ui_.paidButton, &QPushButton::clicked, this, &MainWindow::onPaidButtonTriggered);
|
connect(m_ui.paidButton, &QPushButton::clicked, this, &MainWindow::onPaidButtonTriggered);
|
||||||
connect(ui_.givenSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
|
connect(m_ui.givenSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
|
||||||
&MainWindow::onGivenSpinBoxValueChanged);
|
&MainWindow::onGivenSpinBoxValueChanged);
|
||||||
connect(ui_.basketView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
connect(m_ui.basketView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||||
&MainWindow::onBasketViewSelectionChanged);
|
&MainWindow::onBasketViewSelectionChanged);
|
||||||
connect(ui_.cancelArticleButton, &QPushButton::clicked, this,
|
connect(m_ui.cancelArticleButton, &QPushButton::clicked, this,
|
||||||
&MainWindow::onCancelArticleButtonClicked);
|
&MainWindow::onCancelArticleButtonClicked);
|
||||||
connect(ui_.cancelSaleButton, &QPushButton::clicked, this,
|
connect(m_ui.cancelSaleButton, &QPushButton::clicked, this,
|
||||||
&MainWindow::onCancelSaleButtonClicked);
|
&MainWindow::onCancelSaleButtonClicked);
|
||||||
connect(ui_.printSaleReceiptButton, &QPushButton::clicked, this,
|
connect(m_ui.printSaleReceiptButton, &QPushButton::clicked, this,
|
||||||
&MainWindow::onPrintSaleReceiptButtonClicked);
|
&MainWindow::onPrintSaleReceiptButtonClicked);
|
||||||
connect(ui_.cancelAllArticlesButton, &QPushButton::clicked, this,
|
connect(m_ui.cancelAllArticlesButton, &QPushButton::clicked, this,
|
||||||
&MainWindow::onCancelAllArticlesButtonClicked);
|
&MainWindow::onCancelAllArticlesButtonClicked);
|
||||||
connect(ui_.aboutQtAction, &QAction::triggered, this, &MainWindow::onAboutQt);
|
connect(m_ui.aboutQtAction, &QAction::triggered, this, &MainWindow::onAboutQt);
|
||||||
connect(ui_.aboutAction, &QAction::triggered, this, &MainWindow::onAbout);
|
connect(m_ui.aboutAction, &QAction::triggered, this, &MainWindow::onAbout);
|
||||||
connect(ui_.openManualAction, &QAction::triggered, this, []() {
|
connect(m_ui.openManualAction, &QAction::triggered, this, []() {
|
||||||
auto locations = QStandardPaths::standardLocations(QStandardPaths::DataLocation);
|
auto locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
|
||||||
for (auto location : locations) {
|
for (auto location : locations) {
|
||||||
if (QFile::exists(location + QString("/Benutzerhandbuch.pdf"))) {
|
if (QFile::exists(location + QString("/Benutzerhandbuch.pdf"))) {
|
||||||
QDesktopServices::openUrl(
|
QDesktopServices::openUrl(
|
||||||
QUrl(QString("file:///") + location + QString("/Benutzerhandbuch.pdf"),
|
QUrl::fromLocalFile(location + QString("/Benutzerhandbuch.pdf")));
|
||||||
QUrl::TolerantMode));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(ui_.licenseAction, &QAction::triggered, this, [=]() {
|
connect(m_ui.licenseAction, &QAction::triggered, this, [this]() {
|
||||||
QString licenseText(
|
QString licenseText(
|
||||||
"Copyright © 2018 Martin Brodbeck\n\n"
|
"Copyright © 2018-2024 Martin Brodbeck\n\n"
|
||||||
"Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der "
|
"Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der "
|
||||||
"zugehörigen Dokumentationen (die \"Software\") erhält, die Erlaubnis erteilt, "
|
"zugehörigen Dokumentationen (die \"Software\") erhält, die Erlaubnis erteilt, "
|
||||||
"sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, "
|
"sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, "
|
||||||
|
@ -116,32 +124,30 @@ MainWindow::MainWindow()
|
||||||
"SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN.");
|
"SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN.");
|
||||||
QMessageBox::information(this, "Lizenzinformation", licenseText);
|
QMessageBox::information(this, "Lizenzinformation", licenseText);
|
||||||
});
|
});
|
||||||
connect(ui_.reportAction, &QAction::triggered, this, [=]() { ReportDialog(this).exec(); });
|
connect(m_ui.reportAction, &QAction::triggered, this, [this]() { ReportDialog(this).exec(); });
|
||||||
connect(ui_.configAction, &QAction::triggered, this, [=]() {
|
connect(m_ui.configAction, &QAction::triggered, this, [this]() {
|
||||||
int result = SettingsDialog(this).exec();
|
int result = SettingsDialog(this).exec();
|
||||||
if (result == QDialog::Accepted) {
|
if (result == QDialog::Accepted) {
|
||||||
delete ui_.salesView->model();
|
delete m_ui.salesView->model();
|
||||||
marketplace_->loadFromDb();
|
m_marketplace->loadFromDb();
|
||||||
setSaleModel();
|
setSaleModel();
|
||||||
}
|
}
|
||||||
this->setWindowTitle("KIMA2 - Kasse Nr. " +
|
this->setWindowTitle("KIMA2 - Kasse Nr. " +
|
||||||
QSettings().value("global/cashPointNo").toString());
|
QSettings().value("global/cashPointNo").toString());
|
||||||
});
|
});
|
||||||
connect(ui_.importSellerExcelAction, &QAction::triggered, this,
|
connect(m_ui.importSellerAction, &QAction::triggered, this,
|
||||||
&MainWindow::onImportSellerExcelActionTriggered);
|
&MainWindow::onImportSellerActionTriggered);
|
||||||
connect(ui_.importSellerJsonAction, &QAction::triggered, this,
|
connect(m_ui.exportSalesJsonAction, &QAction::triggered, this,
|
||||||
&MainWindow::onImportSellerJsonActionTriggered);
|
|
||||||
connect(ui_.exportSellerJsonAction, &QAction::triggered, this,
|
|
||||||
&MainWindow::onExportSellerJsonActionTriggered);
|
|
||||||
connect(ui_.exportSalesJsonAction, &QAction::triggered, this,
|
|
||||||
&MainWindow::onExportSalesJsonActionTriggered);
|
&MainWindow::onExportSalesJsonActionTriggered);
|
||||||
connect(ui_.importSalesJsonAction, &QAction::triggered, this,
|
connect(m_ui.importSalesJsonAction, &QAction::triggered, this,
|
||||||
&MainWindow::onImportSalesJsonActionTriggered);
|
&MainWindow::onImportSalesJsonActionTriggered);
|
||||||
|
|
||||||
readGeometry();
|
readGeometry();
|
||||||
setWindowIcon(QIcon(":/misc/kima2.ico"));
|
setWindowIcon(QIcon(":/misc/kima2.ico"));
|
||||||
|
|
||||||
updateStatLabel();
|
updateStatLabel();
|
||||||
|
m_ui.lastPriceLabel1->setText(formatCentAsEuroString(0).c_str());
|
||||||
|
m_ui.lastPriceLabel2->setText(formatCentAsEuroString(0).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onActionEditSellerTriggered()
|
void MainWindow::onActionEditSellerTriggered()
|
||||||
|
@ -149,11 +155,11 @@ void MainWindow::onActionEditSellerTriggered()
|
||||||
auto dialog = std::make_unique<SellerDialog>(this);
|
auto dialog = std::make_unique<SellerDialog>(this);
|
||||||
int retCode = dialog->exec();
|
int retCode = dialog->exec();
|
||||||
|
|
||||||
delete ui_.salesView->model();
|
delete m_ui.salesView->model();
|
||||||
|
|
||||||
if (retCode == QDialog::Accepted) {
|
if (retCode == QDialog::Accepted) {
|
||||||
marketplace_->sortSellers();
|
m_marketplace->sortSellers();
|
||||||
marketplace_->storeToDb();
|
m_marketplace->storeToDb();
|
||||||
statusBar()->showMessage("Änderungen an den Verkäufer-Stammdaten gespeichert.",
|
statusBar()->showMessage("Änderungen an den Verkäufer-Stammdaten gespeichert.",
|
||||||
STATUSBAR_TIMEOUT);
|
STATUSBAR_TIMEOUT);
|
||||||
} else {
|
} else {
|
||||||
|
@ -167,43 +173,44 @@ void MainWindow::onActionEditSellerTriggered()
|
||||||
|
|
||||||
void MainWindow::setSaleModel()
|
void MainWindow::setSaleModel()
|
||||||
{
|
{
|
||||||
ui_.salesView->setModel(new SaleModel(getMarketplace(), ui_.salesView));
|
m_ui.salesView->setModel(new SaleModel(getMarketplace(), m_ui.salesView));
|
||||||
ui_.salesView->setColumnHidden(2, true);
|
m_ui.salesView->setColumnHidden(2, true);
|
||||||
ui_.salesView->resizeColumnToContents(0);
|
m_ui.salesView->resizeColumnToContents(0);
|
||||||
|
m_ui.salesView->resizeColumnToContents(1);
|
||||||
|
|
||||||
ui_.printSaleReceiptButton->setEnabled(false);
|
m_ui.printSaleReceiptButton->setEnabled(false);
|
||||||
ui_.cancelSaleButton->setEnabled(false);
|
m_ui.cancelSaleButton->setEnabled(false);
|
||||||
|
|
||||||
connect(static_cast<BasketModel*>(ui_.basketView->model()), &BasketModel::basketDataChanged,
|
connect(static_cast<BasketModel *>(m_ui.basketView->model()), &BasketModel::basketDataChanged,
|
||||||
static_cast<SaleModel*>(ui_.salesView->model()), &SaleModel::onBasketDataChanged);
|
static_cast<SaleModel *>(m_ui.salesView->model()), &SaleModel::onBasketDataChanged);
|
||||||
connect(ui_.salesView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
connect(m_ui.salesView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||||
&MainWindow::onSalesViewSelectionChanged);
|
&MainWindow::onSalesViewSelectionChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onPaidButtonTriggered()
|
void MainWindow::onPaidButtonTriggered()
|
||||||
{
|
{
|
||||||
if (marketplace_->basketSize() > 0) {
|
if (m_marketplace->basketSize() > 0) {
|
||||||
QString lastPrice{marketplace_->getBasketSumAsString().c_str()};
|
QString lastPrice{m_marketplace->getBasketSumAsString().c_str()};
|
||||||
dynamic_cast<BasketModel*>(ui_.basketView->model())->finishSale();
|
dynamic_cast<BasketModel *>(m_ui.basketView->model())->finishSale();
|
||||||
ui_.salesView->resizeColumnToContents(0);
|
m_ui.salesView->resizeColumnToContents(0);
|
||||||
ui_.lastPriceLabel1->setText(lastPrice);
|
m_ui.lastPriceLabel1->setText(lastPrice);
|
||||||
ui_.lastPriceLabel2->setText(lastPrice);
|
m_ui.lastPriceLabel2->setText(lastPrice);
|
||||||
ui_.basketSumLabel->setText(formatCentAsEuroString(0).c_str());
|
m_ui.basketSumLabel->setText(formatCentAsEuroString(0).c_str());
|
||||||
ui_.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
m_ui.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
||||||
ui_.drawbackContainerWidget->setEnabled(false);
|
m_ui.drawbackContainerWidget->setEnabled(false);
|
||||||
ui_.sellerNoEdit->setFocus();
|
m_ui.sellerNoEdit->setFocus();
|
||||||
statusBar()->showMessage("Verkaufsvorgang erfolgreich durchgeführt.", STATUSBAR_TIMEOUT);
|
statusBar()->showMessage("Verkaufsvorgang erfolgreich durchgeführt.", STATUSBAR_TIMEOUT);
|
||||||
updateStatLabel();
|
updateStatLabel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::eventFilter(QObject* target, QEvent* event)
|
bool MainWindow::eventFilter(QObject *target, QEvent *event)
|
||||||
{
|
{
|
||||||
if (target == ui_.sellerNoEdit) {
|
if (target == m_ui.sellerNoEdit) {
|
||||||
if (event->type() == QEvent::KeyPress) {
|
if (event->type() == QEvent::KeyPress) {
|
||||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||||
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
|
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
|
||||||
if (keyEvent->modifiers() == Qt::ControlModifier) {
|
if (keyEvent->modifiers() & Qt::ControlModifier) {
|
||||||
checkSellerNo(true);
|
checkSellerNo(true);
|
||||||
} else {
|
} else {
|
||||||
checkSellerNo(false);
|
checkSellerNo(false);
|
||||||
|
@ -212,18 +219,18 @@ bool MainWindow::eventFilter(QObject* target, QEvent* event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (target == ui_.givenSpinBox) {
|
} else if (target == m_ui.givenSpinBox) {
|
||||||
if (event->type() == QEvent::KeyPress) {
|
if (event->type() == QEvent::KeyPress) {
|
||||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||||
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
|
if (keyEvent->key() == Qt::Key::Key_Enter || keyEvent->key() == Qt::Key::Key_Return) {
|
||||||
if (keyEvent->modifiers() == Qt::ControlModifier) {
|
if (keyEvent->modifiers() & Qt::ControlModifier) {
|
||||||
onPaidButtonTriggered();
|
onPaidButtonTriggered();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (keyEvent->key() == Qt::Key::Key_Escape) {
|
} else if (keyEvent->key() == Qt::Key::Key_Escape) {
|
||||||
ui_.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
m_ui.drawbackLabel->setText(formatCentAsEuroString(0).c_str());
|
||||||
ui_.drawbackContainerWidget->setEnabled(false);
|
m_ui.drawbackContainerWidget->setEnabled(false);
|
||||||
ui_.sellerNoEdit->setFocus();
|
m_ui.sellerNoEdit->setFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,15 +241,15 @@ void MainWindow::checkSellerNo(bool ctrlPressed)
|
||||||
{
|
{
|
||||||
using std::regex, std::regex_match, std::smatch;
|
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 (inputText.empty()) {
|
||||||
if (ctrlPressed == false) {
|
if (ctrlPressed == false) {
|
||||||
onPaidButtonTriggered();
|
onPaidButtonTriggered();
|
||||||
} else if (marketplace_->getBasket().size() > 0) {
|
} else if (m_marketplace->getBasket().size() > 0) {
|
||||||
ui_.drawbackContainerWidget->setEnabled(true);
|
m_ui.drawbackContainerWidget->setEnabled(true);
|
||||||
ui_.givenSpinBox->setFocus();
|
m_ui.givenSpinBox->setFocus();
|
||||||
ui_.givenSpinBox->selectAll();
|
m_ui.givenSpinBox->selectAll();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -251,13 +258,13 @@ void MainWindow::checkSellerNo(bool ctrlPressed)
|
||||||
smatch result;
|
smatch result;
|
||||||
|
|
||||||
if (!regex_match(inputText, result, pattern)) {
|
if (!regex_match(inputText, result, pattern)) {
|
||||||
ui_.sellerNoEdit->clear();
|
m_ui.sellerNoEdit->clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sellerNo = std::stoi(result[0]);
|
int sellerNo = std::stoi(result[0]);
|
||||||
|
|
||||||
auto seller = marketplace_->findSellerWithSellerNo(sellerNo);
|
auto seller = m_marketplace->findSellerWithSellerNo(sellerNo);
|
||||||
if (seller) {
|
if (seller) {
|
||||||
PriceDialog priceDialog(this);
|
PriceDialog priceDialog(this);
|
||||||
if (sellerNo == 0) {
|
if (sellerNo == 0) {
|
||||||
|
@ -267,52 +274,52 @@ void MainWindow::checkSellerNo(bool ctrlPressed)
|
||||||
if (dialogResult == QDialog::Accepted) {
|
if (dialogResult == QDialog::Accepted) {
|
||||||
int price = priceDialog.getPrice();
|
int price = priceDialog.getPrice();
|
||||||
std::string desc = priceDialog.getDescription();
|
std::string desc = priceDialog.getDescription();
|
||||||
dynamic_cast<BasketModel*>(ui_.basketView->model())->addArticle(seller, price, desc);
|
dynamic_cast<BasketModel *>(m_ui.basketView->model())->addArticle(seller, price, desc);
|
||||||
ui_.basketView->resizeColumnToContents(1);
|
m_ui.basketView->resizeColumnToContents(1);
|
||||||
ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str());
|
m_ui.basketSumLabel->setText(m_marketplace->getBasketSumAsString().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_.sellerNoEdit->clear();
|
m_ui.sellerNoEdit->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onGivenSpinBoxValueChanged(double value)
|
void MainWindow::onGivenSpinBoxValueChanged(double value)
|
||||||
{
|
{
|
||||||
int givenInCent = std::round(value * 100);
|
int givenInCent = std::round(value * 100);
|
||||||
int basketSumInCent = marketplace_->getBasketSumInCent();
|
int basketSumInCent = m_marketplace->getBasketSumInCent();
|
||||||
int drawback = givenInCent - basketSumInCent;
|
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,
|
void MainWindow::onBasketViewSelectionChanged(const QItemSelection &selected,
|
||||||
[[maybe_unused]] const QItemSelection& deselected)
|
[[maybe_unused]] const QItemSelection &deselected)
|
||||||
{
|
{
|
||||||
if (selected.size() > 0) {
|
if (selected.size() > 0) {
|
||||||
ui_.cancelArticleButton->setEnabled(true);
|
m_ui.cancelArticleButton->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
ui_.cancelArticleButton->setEnabled(false);
|
m_ui.cancelArticleButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onSalesViewSelectionChanged(const QItemSelection& selected,
|
void MainWindow::onSalesViewSelectionChanged(const QItemSelection &selected,
|
||||||
[[maybe_unused]] const QItemSelection& deselected)
|
[[maybe_unused]] const QItemSelection &deselected)
|
||||||
{
|
{
|
||||||
if (selected.size() > 0) {
|
if (selected.size() > 0) {
|
||||||
ui_.cancelSaleButton->setEnabled(true);
|
m_ui.cancelSaleButton->setEnabled(true);
|
||||||
if (!selected.indexes()[0].parent().isValid())
|
if (!selected.indexes()[0].parent().isValid())
|
||||||
ui_.printSaleReceiptButton->setEnabled(true);
|
m_ui.printSaleReceiptButton->setEnabled(true);
|
||||||
else
|
else
|
||||||
ui_.printSaleReceiptButton->setEnabled(false);
|
m_ui.printSaleReceiptButton->setEnabled(false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ui_.cancelSaleButton->setEnabled(false);
|
m_ui.cancelSaleButton->setEnabled(false);
|
||||||
ui_.printSaleReceiptButton->setEnabled(false);
|
m_ui.printSaleReceiptButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
|
void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
|
||||||
{
|
{
|
||||||
auto selModel = ui_.basketView->selectionModel();
|
auto selModel = m_ui.basketView->selectionModel();
|
||||||
if (selModel->hasSelection() == false)
|
if (selModel->hasSelection() == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -329,22 +336,23 @@ void MainWindow::onCancelArticleButtonClicked([[maybe_unused]] bool checked)
|
||||||
|
|
||||||
// Deleting the rows, beginning with the last one!
|
// Deleting the rows, beginning with the last one!
|
||||||
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
||||||
ui_.basketView->model()->removeRow(iter->row());
|
m_ui.basketView->model()->removeRow(iter->row());
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_.basketSumLabel->setText(marketplace_->getBasketSumAsString().c_str()); // Update basket sum
|
m_ui.basketSumLabel->setText(
|
||||||
ui_.sellerNoEdit->setFocus();
|
m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
|
||||||
|
m_ui.sellerNoEdit->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onCancelSaleButtonClicked([[maybe_unused]] bool checked)
|
void MainWindow::onCancelSaleButtonClicked([[maybe_unused]] bool checked)
|
||||||
{
|
{
|
||||||
auto selModel = ui_.salesView->selectionModel();
|
auto selModel = m_ui.salesView->selectionModel();
|
||||||
if (selModel->hasSelection() == false)
|
if (selModel->hasSelection() == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto dlgResult =
|
auto dlgResult =
|
||||||
QMessageBox(QMessageBox::Icon::Warning, "Sind Sie sicher?",
|
QMessageBox(QMessageBox::Icon::Warning, "Sind Sie sicher?",
|
||||||
"Möchten Sie wirklich stornieren?",
|
"Möchten Sie wirklich aus abgeschlossenen Verkäufen stornieren?",
|
||||||
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, this)
|
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, this)
|
||||||
.exec();
|
.exec();
|
||||||
if (dlgResult == QMessageBox::No)
|
if (dlgResult == QMessageBox::No)
|
||||||
|
@ -355,16 +363,25 @@ void MainWindow::onCancelSaleButtonClicked([[maybe_unused]] bool checked)
|
||||||
|
|
||||||
// Deleting the rows, beginning with the last one!
|
// Deleting the rows, beginning with the last one!
|
||||||
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
||||||
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 (m_ui.salesView->model()->rowCount() > 0) {
|
||||||
|
lastPriceValue =
|
||||||
|
m_ui.salesView->model()->data(m_ui.salesView->model()->index(0, 1)).toString();
|
||||||
|
}
|
||||||
|
m_ui.lastPriceLabel1->setText(lastPriceValue);
|
||||||
|
m_ui.lastPriceLabel2->setText(lastPriceValue);
|
||||||
|
|
||||||
updateStatLabel();
|
updateStatLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
|
void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
|
||||||
{
|
{
|
||||||
auto selModel = ui_.salesView->selectionModel();
|
auto selModel = m_ui.salesView->selectionModel();
|
||||||
if (selModel->hasSelection() == false)
|
if (selModel->hasSelection() == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -373,7 +390,7 @@ void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
|
||||||
QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString();
|
QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString();
|
||||||
|
|
||||||
auto indexes = selModel->selectedRows();
|
auto indexes = selModel->selectedRows();
|
||||||
auto& sale = marketplace_->getSales().at(indexes[0].row());
|
auto &sale = m_marketplace->getSales().at(indexes[0].row());
|
||||||
|
|
||||||
auto printerDevice =
|
auto printerDevice =
|
||||||
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
|
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
|
||||||
|
@ -387,12 +404,13 @@ void MainWindow::onPrintSaleReceiptButtonClicked([[maybe_unused]] bool checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printer->isValid())
|
if (printer->isValid())
|
||||||
printer->printSaleReceipt(sale.get(), settings.value("global/commune", "Dettingen").toString().toStdString());
|
printer->printSaleReceipt(
|
||||||
|
sale.get(), settings.value("global/commune", "Dettingen").toString().toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onCancelAllArticlesButtonClicked([[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;
|
return;
|
||||||
|
|
||||||
auto dlgResult =
|
auto dlgResult =
|
||||||
|
@ -403,10 +421,11 @@ void MainWindow::onCancelAllArticlesButtonClicked([[maybe_unused]] bool checked)
|
||||||
if (dlgResult == QMessageBox::No)
|
if (dlgResult == QMessageBox::No)
|
||||||
return;
|
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
|
m_ui.basketSumLabel->setText(
|
||||||
ui_.sellerNoEdit->setFocus();
|
m_marketplace->getBasketSumAsString().c_str()); // Update basket sum
|
||||||
|
m_ui.sellerNoEdit->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onAboutQt() { QMessageBox::aboutQt(this); }
|
void MainWindow::onAboutQt() { QMessageBox::aboutQt(this); }
|
||||||
|
@ -422,9 +441,9 @@ void MainWindow::onAbout()
|
||||||
">info@rustysoft.de</a>></p>");
|
">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",
|
QMessageBox(QMessageBox::Icon::Information, "Import nicht möglich",
|
||||||
"Der Import ist nicht möglich, da schon Verkäufe getätigt wurden.",
|
"Der Import ist nicht möglich, da schon Verkäufe getätigt wurden.",
|
||||||
QMessageBox::StandardButton::Ok, this)
|
QMessageBox::StandardButton::Ok, this)
|
||||||
|
@ -432,59 +451,31 @@ void MainWindow::onImportSellerExcelActionTriggered()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMessageBox(
|
auto filename =
|
||||||
QMessageBox::Icon::Information, "Bitte beachten",
|
QFileDialog::getOpenFileName(this, "Verkäufer importieren", QString(),
|
||||||
"<b>Achtung:</b> Importieren Sie die Verkäuferdaten nur auf <b>einer (!)</b> "
|
"Alle unterstützte Dateien (*.csv);;CSV Dateien (*.csv)");
|
||||||
"KIMA2-Installation.<br /> "
|
|
||||||
"Verteilen Sie die Daten auf die anderen Installationen unbedingt über eine JSON-Datei!",
|
if (filename.isEmpty())
|
||||||
QMessageBox::StandardButton::Ok, this)
|
return;
|
||||||
|
|
||||||
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
|
fs::path filePath(filename.toStdWString());
|
||||||
|
#else
|
||||||
|
fs::path filePath(filename.toStdString());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::size_t numImported{};
|
||||||
|
numImported = CsvReader::readSellersFromFile(filePath, m_marketplace.get());
|
||||||
|
|
||||||
|
updateStatLabel();
|
||||||
|
|
||||||
|
using namespace std::string_literals;
|
||||||
|
std::ostringstream msg;
|
||||||
|
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();
|
.exec();
|
||||||
|
|
||||||
auto filename = QFileDialog::getOpenFileName(this, "Verkäufer importieren", QString(),
|
|
||||||
"Excel Dateien (*.xlsx *.xls)");
|
|
||||||
|
|
||||||
if (filename.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
fs::path filePath(filename.toStdWString());
|
|
||||||
|
|
||||||
ExcelReader::readSellersFromFile(filePath, marketplace_.get());
|
|
||||||
updateStatLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
fs::path filePath(filename.toStdWString());
|
|
||||||
|
|
||||||
JsonUtil::importSellers(filePath, marketplace_.get());
|
|
||||||
updateStatLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onExportSellerJsonActionTriggered()
|
|
||||||
{
|
|
||||||
auto filename = QFileDialog::getSaveFileName(
|
|
||||||
this, "Verkäufer exportieren", QString("kima2_verkaeufer.json"), "JSON Dateien (*.json)");
|
|
||||||
|
|
||||||
if (filename.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
fs::path filePath(filename.toStdWString());
|
|
||||||
|
|
||||||
JsonUtil::exportSellers(filePath, marketplace_.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onExportSalesJsonActionTriggered()
|
void MainWindow::onExportSalesJsonActionTriggered()
|
||||||
|
@ -499,9 +490,13 @@ void MainWindow::onExportSalesJsonActionTriggered()
|
||||||
if (filename.isEmpty())
|
if (filename.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
fs::path filePath(filename.toStdWString());
|
fs::path filePath(filename.toStdWString());
|
||||||
|
#else
|
||||||
|
fs::path filePath(filename.toStdString());
|
||||||
|
#endif
|
||||||
|
|
||||||
JsonUtil::exportSales(filePath, marketplace_.get(),
|
JsonUtil::exportSales(filePath, m_marketplace.get(),
|
||||||
settings.value("global/cashPointNo").toInt());
|
settings.value("global/cashPointNo").toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,23 +504,30 @@ void MainWindow::onImportSalesJsonActionTriggered()
|
||||||
{
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
auto filename = QFileDialog::getOpenFileName(this, "Umsätze/Transaktionen importieren",
|
auto filenames = QFileDialog::getOpenFileNames(this, "Umsätze/Transaktionen importieren",
|
||||||
QString(), "JSON Dateien (*.json)");
|
QString(), "JSON Dateien (*.json)");
|
||||||
|
|
||||||
if (filename.isEmpty())
|
if (filenames.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fs::path filePath(filename.toStdWString());
|
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 {
|
try {
|
||||||
JsonUtil::importSales(filePath, marketplace_.get(),
|
JsonUtil::importSales(filePath, m_marketplace.get(),
|
||||||
settings.value("global/cashPointNo").toInt());
|
settings.value("global/cashPointNo").toInt());
|
||||||
} catch (std::runtime_error& err) {
|
} catch (std::runtime_error &err) {
|
||||||
QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok,
|
QMessageBox(QMessageBox::Icon::Warning, "Import nicht möglich", err.what(), QMessageBox::Ok,
|
||||||
this)
|
this)
|
||||||
.exec();
|
.exec();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setSaleModel();
|
setSaleModel();
|
||||||
updateStatLabel();
|
updateStatLabel();
|
||||||
}
|
}
|
||||||
|
@ -550,7 +552,7 @@ void MainWindow::readGeometry()
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::closeEvent(QCloseEvent* event)
|
void MainWindow::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
writeGeometry();
|
writeGeometry();
|
||||||
event->accept();
|
event->accept();
|
||||||
|
@ -560,9 +562,9 @@ void MainWindow::updateStatLabel()
|
||||||
{
|
{
|
||||||
std::string statistics("<b>KIMA2 - Version ");
|
std::string statistics("<b>KIMA2 - Version ");
|
||||||
statistics += PROJECT_VERSION;
|
statistics += PROJECT_VERSION;
|
||||||
statistics += "</b><br />Verkäufer: " + std::to_string(marketplace_->getSellers().size() - 1);
|
statistics += "</b><br />Verkäufer: " + std::to_string(m_marketplace->getSellers().size() - 1);
|
||||||
statistics += "<br />Kunden: " + std::to_string(marketplace_->getSales().size());
|
statistics += "<br />Kunden: " + std::to_string(m_marketplace->getSales().size());
|
||||||
statistics += "<br />Umsatz: " + marketplace_->getOverallSumAsString();
|
statistics += "<br />Umsatz: " + m_marketplace->getOverallSumAsString();
|
||||||
|
|
||||||
ui_.statLabel->setText(statistics.c_str());
|
m_ui.statLabel->setText(statistics.c_str());
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
#include <marketplace.h>
|
#include <core/marketplace.h>
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QtGui/QCloseEvent>
|
#include <QtGui/QCloseEvent>
|
||||||
|
@ -16,7 +16,7 @@ class MainWindow : public QMainWindow
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow();
|
||||||
Marketplace* getMarketplace() { return marketplace_.get(); }
|
Marketplace* getMarketplace() { return m_marketplace.get(); }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onBasketViewSelectionChanged(const QItemSelection& selected,
|
void onBasketViewSelectionChanged(const QItemSelection& selected,
|
||||||
|
@ -29,7 +29,7 @@ class MainWindow : public QMainWindow
|
||||||
void onCancelAllArticlesButtonClicked(bool checked);
|
void onCancelAllArticlesButtonClicked(bool checked);
|
||||||
void onAboutQt();
|
void onAboutQt();
|
||||||
void onAbout();
|
void onAbout();
|
||||||
virtual bool eventFilter(QObject *target, QEvent *event) override;
|
virtual bool eventFilter(QObject* target, QEvent* event) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void closeEvent(QCloseEvent* event) override;
|
virtual void closeEvent(QCloseEvent* event) override;
|
||||||
|
@ -39,9 +39,7 @@ class MainWindow : public QMainWindow
|
||||||
void checkSellerNo(bool ctrlPressed = false);
|
void checkSellerNo(bool ctrlPressed = false);
|
||||||
void onPaidButtonTriggered();
|
void onPaidButtonTriggered();
|
||||||
void onGivenSpinBoxValueChanged(double value);
|
void onGivenSpinBoxValueChanged(double value);
|
||||||
void onImportSellerExcelActionTriggered();
|
void onImportSellerActionTriggered();
|
||||||
void onImportSellerJsonActionTriggered();
|
|
||||||
void onExportSellerJsonActionTriggered();
|
|
||||||
void onExportSalesJsonActionTriggered();
|
void onExportSalesJsonActionTriggered();
|
||||||
void onImportSalesJsonActionTriggered();
|
void onImportSalesJsonActionTriggered();
|
||||||
void setSaleModel();
|
void setSaleModel();
|
||||||
|
@ -49,8 +47,8 @@ class MainWindow : public QMainWindow
|
||||||
void readGeometry();
|
void readGeometry();
|
||||||
void updateStatLabel();
|
void updateStatLabel();
|
||||||
|
|
||||||
Ui::MainWindow ui_;
|
Ui::MainWindow m_ui;
|
||||||
std::unique_ptr<Marketplace> marketplace_;
|
std::unique_ptr<Marketplace> m_marketplace;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -112,7 +112,11 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDoubleSpinBox" name="givenSpinBox"/>
|
<widget class="QDoubleSpinBox" name="givenSpinBox">
|
||||||
|
<property name="maximum">
|
||||||
|
<double>999.990000000000009</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
|
@ -436,16 +440,8 @@ drucken</string>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>&Verkäufer</string>
|
<string>&Verkäufer</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="importSellerMenu">
|
|
||||||
<property name="title">
|
|
||||||
<string>Importieren</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="importSellerExcelAction"/>
|
|
||||||
<addaction name="importSellerJsonAction"/>
|
|
||||||
</widget>
|
|
||||||
<addaction name="actionEditSeller"/>
|
<addaction name="actionEditSeller"/>
|
||||||
<addaction name="importSellerMenu"/>
|
<addaction name="importSellerAction"/>
|
||||||
<addaction name="exportSellerJsonAction"/>
|
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuHilfe">
|
<widget class="QMenu" name="menuHilfe">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -509,9 +505,9 @@ drucken</string>
|
||||||
<string>Exportieren für andere Kasse (JSON)</string>
|
<string>Exportieren für andere Kasse (JSON)</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="importSellerExcelAction">
|
<action name="importSellerActionX">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Aus Excel-Datei (initial)</string>
|
<string>Aus CSV-Datei (initial)</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="importSellerJsonAction">
|
<action name="importSellerJsonAction">
|
||||||
|
@ -544,6 +540,11 @@ drucken</string>
|
||||||
<string>Lizenz</string>
|
<string>Lizenz</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="importSellerAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>Importieren (aus CSV-Datei)</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
23
src/gui/meson.build
Normal file
23
src/gui/meson.build
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
qt5 = import('qt5')
|
||||||
|
qt5_dep = dependency('qt5', modules: ['Core', 'Gui', 'PrintSupport', 'Network'])
|
||||||
|
|
||||||
|
thread_dep = dependency('threads')
|
||||||
|
|
||||||
|
|
||||||
|
src = ['kima2.cpp', 'mainwindow.cpp', 'sellerdialog.cpp', 'sellermodel.cpp',
|
||||||
|
'pricedialog.cpp', 'basketmodel.cpp', 'salemodel.cpp', 'reportdialog.cpp',
|
||||||
|
'reportmodel.cpp', 'settingsdialog.cpp']
|
||||||
|
|
||||||
|
ui = ['mainwindow.ui', 'sellerdialog.ui', 'pricedialog.ui', 'reportdialog.ui', 'settingsdialog.ui']
|
||||||
|
|
||||||
|
processed = qt5.preprocess(moc_headers : ['basketmodel.h', 'mainwindow.h', 'pricedialog.h',
|
||||||
|
'reportdialog.h', 'sellerdialog.h', 'settingsdialog.h',
|
||||||
|
'sellermodel.h', 'salemodel.h'],
|
||||||
|
ui_files : ui,
|
||||||
|
qresources : '../../kima2.qrc',
|
||||||
|
dependencies: qt5_dep)
|
||||||
|
|
||||||
|
kima2 = executable('kima2', sources : [src, processed],
|
||||||
|
dependencies : [qt5_dep, singleapp_dep, core_dep, printer_dep, thread_dep],
|
||||||
|
include_directories : [configuration_inc],
|
||||||
|
install : true)
|
|
@ -6,34 +6,31 @@
|
||||||
|
|
||||||
PriceDialog::PriceDialog(QWidget* parent, bool forceDesc, Qt::WindowFlags f) : QDialog(parent, f)
|
PriceDialog::PriceDialog(QWidget* parent, bool forceDesc, Qt::WindowFlags f) : QDialog(parent, f)
|
||||||
{
|
{
|
||||||
forceDesc_ = forceDesc;
|
m_forceDesc = forceDesc;
|
||||||
ui_.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
ui_.priceSpinBox->setFocus();
|
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()
|
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",
|
QMessageBox(QMessageBox::Icon::Warning, "Falsche Preiseingabe",
|
||||||
"Es sind nur 0,50 Cent-Schritte erlaubt.", QMessageBox::StandardButton::Ok,
|
"Es sind nur 0,50 Cent-Schritte erlaubt.", QMessageBox::StandardButton::Ok,
|
||||||
this)
|
this)
|
||||||
.exec();
|
.exec();
|
||||||
} else if (forceDesc_ && ui_.descEdit->text().trimmed().isEmpty()) {
|
} else if (m_forceDesc && m_ui.descEdit->text().trimmed().isEmpty()) {
|
||||||
QMessageBox(QMessageBox::Icon::Warning, "Artikelbeschreibung fehlt",
|
QMessageBox(QMessageBox::Icon::Warning, "Artikelbeschreibung fehlt",
|
||||||
"Da Sie auf das Sonderkonto buchen ist eine Artikelbeschreibung erforderlich.",
|
"Da Sie auf das Sonderkonto buchen ist eine Artikelbeschreibung erforderlich.",
|
||||||
QMessageBox::StandardButton::Ok, this)
|
QMessageBox::StandardButton::Ok, this)
|
||||||
.exec();
|
.exec();
|
||||||
ui_.descEdit->setFocus();
|
m_ui.descEdit->setFocus();
|
||||||
} else {
|
} else {
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PriceDialog::setForceDesc(bool force)
|
void PriceDialog::setForceDesc(bool force) { m_forceDesc = force; }
|
||||||
{
|
|
||||||
forceDesc_ = force;
|
|
||||||
}
|
|
|
@ -19,8 +19,8 @@ class PriceDialog : public QDialog
|
||||||
private:
|
private:
|
||||||
void on_model_duplicateSellerNo(const QString& message);
|
void on_model_duplicateSellerNo(const QString& message);
|
||||||
virtual void accept() override;
|
virtual void accept() override;
|
||||||
Ui::PriceDialog ui_;
|
Ui::PriceDialog m_ui;
|
||||||
bool forceDesc_;
|
bool m_forceDesc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>201</width>
|
<width>266</width>
|
||||||
<height>127</height>
|
<height>128</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -18,6 +18,11 @@
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>16</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Preis</string>
|
<string>Preis</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -28,6 +33,11 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QDoubleSpinBox" name="priceSpinBox">
|
<widget class="QDoubleSpinBox" name="priceSpinBox">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>16</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<double>-999.990000000000009</double>
|
<double>-999.990000000000009</double>
|
||||||
</property>
|
</property>
|
||||||
|
@ -51,6 +61,18 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLineEdit" name="descEdit">
|
<widget class="QLineEdit" name="descEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>200</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="placeholderText">
|
<property name="placeholderText">
|
||||||
<string>(optional)</string>
|
<string>(optional)</string>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include <posprinter.h>
|
#include <core/utils.h>
|
||||||
#include <utils.h>
|
#include <printer/posprinter.h>
|
||||||
|
#include <printer/utils.h>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
|
@ -16,22 +17,22 @@
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
ReportDialog::ReportDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f)
|
ReportDialog::ReportDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f)
|
||||||
{
|
{
|
||||||
ui_.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
market_ = dynamic_cast<MainWindow*>(parent)->getMarketplace();
|
m_market = dynamic_cast<MainWindow *>(parent)->getMarketplace();
|
||||||
model_ = std::make_unique<ReportModel>(market_, ui_.reportView);
|
m_model = std::make_unique<ReportModel>(m_market, m_ui.reportView);
|
||||||
ui_.reportView->setModel(model_.get());
|
m_ui.reportView->setModel(m_model.get());
|
||||||
ui_.reportView->hideColumn(0);
|
m_ui.reportView->hideColumn(0);
|
||||||
ui_.reportView->setRowHidden(0, true); // hide the special "Sonderkonto" user
|
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);
|
&ReportDialog::onExportCsvButtonClicked);
|
||||||
connect(ui_.printReportButton, &QPushButton::clicked, this,
|
connect(m_ui.printReportButton, &QPushButton::clicked, this,
|
||||||
&ReportDialog::onPrintReportButtonClicked);
|
&ReportDialog::onPrintReportButtonClicked);
|
||||||
connect(ui_.printSellerReceiptButton, &QPushButton::clicked, this,
|
connect(m_ui.printSellerReceiptButton, &QPushButton::clicked, this,
|
||||||
&ReportDialog::onPrintSellerReceiptButtonClicked);
|
&ReportDialog::onPrintSellerReceiptButtonClicked);
|
||||||
connect(ui_.reportView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
connect(m_ui.reportView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||||
&ReportDialog::onReportViewSelectionChanged);
|
&ReportDialog::onReportViewSelectionChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +48,13 @@ void ReportDialog::onExportCsvButtonClicked()
|
||||||
if (filename.isEmpty())
|
if (filename.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
fs::path filePath(filename.toStdWString());
|
fs::path filePath(filename.toStdWString());
|
||||||
|
#else
|
||||||
|
fs::path filePath(filename.toStdString());
|
||||||
|
#endif
|
||||||
|
|
||||||
market_->exportReportToCSV(filePath, feeInPercent, maxFeeInEuro);
|
m_market->exportReportToCSV(filePath, feeInPercent, maxFeeInEuro);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReportDialog::onPrintReportButtonClicked()
|
void ReportDialog::onPrintReportButtonClicked()
|
||||||
|
@ -70,8 +75,8 @@ void ReportDialog::onPrintReportButtonClicked()
|
||||||
QPainter painter;
|
QPainter painter;
|
||||||
int height = printer.height();
|
int height = printer.height();
|
||||||
int width = printer.width();
|
int width = printer.width();
|
||||||
const double ENTRIES_PER_PAGE = 51;
|
const double ENTRIES_PER_PAGE = 45;
|
||||||
const auto& sellers = market_->getSellers();
|
const auto &sellers = m_market->getSellers();
|
||||||
unsigned int numPages = std::ceil(sellers.size() / ENTRIES_PER_PAGE);
|
unsigned int numPages = std::ceil(sellers.size() / ENTRIES_PER_PAGE);
|
||||||
|
|
||||||
painter.begin(&printer);
|
painter.begin(&printer);
|
||||||
|
@ -102,7 +107,7 @@ void ReportDialog::onPrintReportButtonClicked()
|
||||||
for (unsigned int j = 0;
|
for (unsigned int j = 0;
|
||||||
j < ENTRIES_PER_PAGE && (i - 1) * ENTRIES_PER_PAGE + j < sellers.size(); ++j) {
|
j < ENTRIES_PER_PAGE && (i - 1) * ENTRIES_PER_PAGE + j < sellers.size(); ++j) {
|
||||||
int idx = (i - 1) * ENTRIES_PER_PAGE + j;
|
int idx = (i - 1) * ENTRIES_PER_PAGE + j;
|
||||||
if (sellers.at(idx)->getUuidAsString() == "11111111-1111-1111-1111-111111111111") {
|
if (sellers.at(idx)->getId() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
content += QString("%1 %2 %3 %4 %5 %6 %7\n")
|
content += QString("%1 %2 %3 %4 %5 %6 %7\n")
|
||||||
|
@ -121,7 +126,7 @@ void ReportDialog::onPrintReportButtonClicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
// pieces booked on the special account "Sonderkonto"
|
// pieces booked on the special account "Sonderkonto"
|
||||||
const auto specialSeller = market_->findSellerWithUuid("11111111-1111-1111-1111-111111111111");
|
const auto specialSeller = m_market->findSellerWithSellerNo(0);
|
||||||
if (specialSeller && specialSeller->numArticlesSold() > 0) {
|
if (specialSeller && specialSeller->numArticlesSold() > 0) {
|
||||||
printer.newPage();
|
printer.newPage();
|
||||||
painter.setFont(QFont("Arial", 16, QFont::Bold));
|
painter.setFont(QFont("Arial", 16, QFont::Bold));
|
||||||
|
@ -131,7 +136,7 @@ void ReportDialog::onPrintReportButtonClicked()
|
||||||
QString content("Einzelteile ohne Nummer\n=======================\n\n");
|
QString content("Einzelteile ohne Nummer\n=======================\n\n");
|
||||||
unsigned int lines{0};
|
unsigned int lines{0};
|
||||||
unsigned int pages{1};
|
unsigned int pages{1};
|
||||||
for (const auto& article : specialSeller->getArticles(true)) {
|
for (const auto &article : specialSeller->getArticles(true)) {
|
||||||
content += QString("- %1:").arg(article->getDescription().substr(0, 45).c_str(), -45);
|
content += QString("- %1:").arg(article->getDescription().substr(0, 45).c_str(), -45);
|
||||||
content += QString("%1\n").arg(article->getPriceAsString().c_str(), 11);
|
content += QString("%1\n").arg(article->getPriceAsString().c_str(), 11);
|
||||||
++lines;
|
++lines;
|
||||||
|
@ -158,8 +163,8 @@ void ReportDialog::onPrintReportButtonClicked()
|
||||||
"Auswertung Kindersachenmarkt");
|
"Auswertung Kindersachenmarkt");
|
||||||
painter.setFont(fixedFont);
|
painter.setFont(fixedFont);
|
||||||
QString content("Gesamtstatistik\n===============\n\n");
|
QString content("Gesamtstatistik\n===============\n\n");
|
||||||
int numArticlesOffered = market_->getNumArticlesOffered();
|
int numArticlesOffered = m_market->getNumArticlesOffered();
|
||||||
int numArticlesSold = market_->getNumArticlesSold();
|
int numArticlesSold = m_market->getNumArticlesSold();
|
||||||
double percentArticlesSold =
|
double percentArticlesSold =
|
||||||
(static_cast<double>(numArticlesSold) / static_cast<double>(numArticlesOffered)) * 100;
|
(static_cast<double>(numArticlesSold) / static_cast<double>(numArticlesOffered)) * 100;
|
||||||
content += QString("Registrierte Verkäufer: %1\n").arg(sellers.size() - 1, 6);
|
content += QString("Registrierte Verkäufer: %1\n").arg(sellers.size() - 1, 6);
|
||||||
|
@ -167,14 +172,14 @@ void ReportDialog::onPrintReportButtonClicked()
|
||||||
content += QString("Verkaufte Artikel: %1 (%L2 %)\n")
|
content += QString("Verkaufte Artikel: %1 (%L2 %)\n")
|
||||||
.arg(numArticlesSold, 6)
|
.arg(numArticlesSold, 6)
|
||||||
.arg(percentArticlesSold, 0, 'f', 2);
|
.arg(percentArticlesSold, 0, 'f', 2);
|
||||||
content += QString("Anzahl Kunden: %1\n\n").arg(market_->getSales().size(), 6);
|
content += QString("Anzahl Kunden: %1\n\n").arg(m_market->getSales().size(), 6);
|
||||||
content += QString("Gesamtumsatz: %1\n").arg(market_->getOverallSumAsString().c_str(), 10);
|
content += QString("Gesamtumsatz: %1\n").arg(m_market->getOverallSumAsString().c_str(), 10);
|
||||||
content +=
|
content +=
|
||||||
QString("Ausgezahlt: %1\n")
|
QString("Ausgezahlt: %1\n")
|
||||||
.arg(market_->getOverallPaymentAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10);
|
.arg(m_market->getOverallPaymentAsString(feeInPercent, maxFeeInEuro * 100).c_str(), 10);
|
||||||
content +=
|
content +=
|
||||||
QString("Verbleibend: %1\n\n")
|
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("(Einbehaltener Prozentsatz: %1 %)\n").arg(feeInPercent, 3);
|
||||||
content += QString("(Maximal einbehaltener Betrag: %1 €)\n").arg(maxFeeInEuro, 3);
|
content += QString("(Maximal einbehaltener Betrag: %1 €)\n").arg(maxFeeInEuro, 3);
|
||||||
|
|
||||||
|
@ -191,12 +196,12 @@ void ReportDialog::onPrintSellerReceiptButtonClicked()
|
||||||
QString posPrinterDevice = settings.value("global/posPrinterDevice", "").toString();
|
QString posPrinterDevice = settings.value("global/posPrinterDevice", "").toString();
|
||||||
QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString();
|
QString posPrinterEndpoint = settings.value("global/posPrinterEndpoint", "").toString();
|
||||||
|
|
||||||
auto selModel = ui_.reportView->selectionModel();
|
auto selModel = m_ui.reportView->selectionModel();
|
||||||
if (selModel->hasSelection() == false)
|
if (selModel->hasSelection() == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto indexes = selModel->selectedRows();
|
auto indexes = selModel->selectedRows();
|
||||||
auto& seller = market_->getSellers().at(indexes[0].row());
|
auto &seller = m_market->getSellers().at(indexes[0].row());
|
||||||
|
|
||||||
auto printerDevice =
|
auto printerDevice =
|
||||||
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
|
convertToPosPrinterDevice(posPrinterDevice.toStdString(), posPrinterEndpoint.toStdString());
|
||||||
|
@ -215,12 +220,12 @@ void ReportDialog::onPrintSellerReceiptButtonClicked()
|
||||||
settings.value("global/commune", "Dettingen").toString().toStdString());
|
settings.value("global/commune", "Dettingen").toString().toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReportDialog::onReportViewSelectionChanged(const QItemSelection& selected,
|
void ReportDialog::onReportViewSelectionChanged(const QItemSelection &selected,
|
||||||
[[maybe_unused]] const QItemSelection& deselected)
|
[[maybe_unused]] const QItemSelection &deselected)
|
||||||
{
|
{
|
||||||
if (selected.size() > 0) {
|
if (selected.size() > 0) {
|
||||||
ui_.printSellerReceiptButton->setEnabled(true);
|
m_ui.printSellerReceiptButton->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
ui_.printSellerReceiptButton->setEnabled(false);
|
m_ui.printSellerReceiptButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include "reportmodel.h"
|
#include "reportmodel.h"
|
||||||
|
|
||||||
#include <marketplace.h>
|
#include <core/marketplace.h>
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
|
@ -24,9 +24,10 @@ class ReportDialog : public QDialog
|
||||||
void onReportViewSelectionChanged(const QItemSelection& selected,
|
void onReportViewSelectionChanged(const QItemSelection& selected,
|
||||||
const QItemSelection& deselected);
|
const QItemSelection& deselected);
|
||||||
|
|
||||||
private : Ui::ReportDialog ui_;
|
private:
|
||||||
Marketplace* market_;
|
Ui::ReportDialog m_ui;
|
||||||
std::unique_ptr<ReportModel> model_;
|
Marketplace* m_market;
|
||||||
|
std::unique_ptr<ReportModel> m_model;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -5,16 +5,16 @@
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
ReportModel::ReportModel(Marketplace* market, QObject* parent)
|
ReportModel::ReportModel(Marketplace* market, QObject* parent)
|
||||||
: QAbstractTableModel(parent), market_(market)
|
: QAbstractTableModel(parent), m_market(market)
|
||||||
{
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
feeInPercent_ = settings.value("global/feeInPercent").toInt();
|
m_feeInPercent = settings.value("global/feeInPercent").toInt();
|
||||||
maxFeeInCent_ = settings.value("global/maxFeeInEuro").toInt() * 100;
|
m_maxFeeInCent = settings.value("global/maxFeeInEuro").toInt() * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReportModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
|
int ReportModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
|
||||||
{
|
{
|
||||||
return static_cast<int>(market_->getSellers().size());
|
return static_cast<int>(m_market->getSellers().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReportModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 7; }
|
int ReportModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 7; }
|
||||||
|
@ -52,14 +52,14 @@ QVariant ReportModel::data(const QModelIndex& index, int role) const
|
||||||
if (role != Qt::DisplayRole)
|
if (role != Qt::DisplayRole)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (market_->getSellers().size() == 0)
|
if (m_market->getSellers().size() == 0)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
Seller* seller = market_->getSellers().at(index.row()).get();
|
Seller* seller = m_market->getSellers().at(index.row()).get();
|
||||||
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0:
|
case 0:
|
||||||
return seller->getUuidAsString().c_str();
|
return seller->getId();
|
||||||
case 1:
|
case 1:
|
||||||
return seller->getSellerNo();
|
return seller->getSellerNo();
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -71,7 +71,7 @@ QVariant ReportModel::data(const QModelIndex& index, int role) const
|
||||||
case 5:
|
case 5:
|
||||||
return seller->sumAsString().c_str();
|
return seller->sumAsString().c_str();
|
||||||
case 6:
|
case 6:
|
||||||
return paymentAsString(seller->sumInCents(), feeInPercent_, maxFeeInCent_).c_str();
|
return paymentAsString(seller->sumInCents(), m_feeInPercent, m_maxFeeInCent).c_str();
|
||||||
default:
|
default:
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef REPORT_MODEL_H
|
#ifndef REPORT_MODEL_H
|
||||||
#define REPORT_MODEL_H
|
#define REPORT_MODEL_H
|
||||||
|
|
||||||
#include <marketplace.h>
|
#include <core/marketplace.h>
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ class ReportModel : public QAbstractTableModel
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Marketplace* market_;
|
Marketplace* m_market;
|
||||||
int feeInPercent_{};
|
int m_feeInPercent{};
|
||||||
int maxFeeInCent_{};
|
int m_maxFeeInCent{};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,6 +1,6 @@
|
||||||
#include "salemodel.h"
|
#include "salemodel.h"
|
||||||
|
|
||||||
#include <article.h>
|
#include <core/article.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
SaleModel::SaleModel(Marketplace* market, QObject* parent) : QAbstractItemModel(parent)
|
SaleModel::SaleModel(Marketplace* market, QObject* parent) : QAbstractItemModel(parent)
|
||||||
{
|
{
|
||||||
marketplace_ = market;
|
m_marketplace = market;
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex SaleModel::index(int row, int column, const QModelIndex& parent) const
|
QModelIndex SaleModel::index(int row, int column, const QModelIndex& parent) const
|
||||||
|
@ -18,7 +18,7 @@ QModelIndex SaleModel::index(int row, int column, const QModelIndex& parent) con
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
Sale* sale = marketplace_->getSales().at(row).get();
|
Sale* sale = m_marketplace->getSales().at(row).get();
|
||||||
return createIndex(row, column, sale);
|
return createIndex(row, column, sale);
|
||||||
} else if (!parent.parent().isValid()) {
|
} else if (!parent.parent().isValid()) {
|
||||||
Sale* sale = static_cast<Sale*>(parent.internalPointer());
|
Sale* sale = static_cast<Sale*>(parent.internalPointer());
|
||||||
|
@ -44,15 +44,15 @@ QModelIndex SaleModel::parent(const QModelIndex& index) const
|
||||||
Sale* sale{};
|
Sale* sale{};
|
||||||
Article* article{};
|
Article* article{};
|
||||||
|
|
||||||
Entity* ent = static_cast<Entity*>(index.internalPointer());
|
EntityUuid* ent = static_cast<EntityUuid*>(index.internalPointer());
|
||||||
|
|
||||||
sale = dynamic_cast<Sale*>(ent);
|
sale = dynamic_cast<Sale*>(ent);
|
||||||
|
|
||||||
if (sale) {
|
if (sale) {
|
||||||
if (sale == rootItem.get())
|
if (sale == m_rootItem.get())
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
else {
|
else {
|
||||||
return createIndex(-1, 0, rootItem.get());
|
return createIndex(-1, 0, m_rootItem.get());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
article = dynamic_cast<Article*>(ent);
|
article = dynamic_cast<Article*>(ent);
|
||||||
|
@ -80,7 +80,7 @@ QVariant SaleModel::data(const QModelIndex& index, int role) const
|
||||||
if (role == Qt::FontRole) {
|
if (role == Qt::FontRole) {
|
||||||
QFont myFont;
|
QFont myFont;
|
||||||
QFont myFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
QFont myFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
||||||
if (myFixedFont.fixedPitch() == false) {
|
if (myFixedFont.fixedPitch() == false) {
|
||||||
myFixedFont.setFamily("monospace");
|
myFixedFont.setFamily("monospace");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,9 @@ QVariant SaleModel::data(const QModelIndex& index, int role) const
|
||||||
Article* article = static_cast<Article*>(index.internalPointer());
|
Article* article = static_cast<Article*>(index.internalPointer());
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0:
|
case 0:
|
||||||
return (std::string("Verk. ") + article->getSeller()->getSellerNoAsString() + " (" + article->getCompleteArticleNo() + ")").c_str();
|
return (std::string("Verk. ") + article->getSeller()->getSellerNoAsString() + " (" +
|
||||||
|
article->getCompleteArticleNo() + ")")
|
||||||
|
.c_str();
|
||||||
case 1:
|
case 1:
|
||||||
return article->getPriceAsString().c_str();
|
return article->getPriceAsString().c_str();
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -130,7 +132,7 @@ int SaleModel::rowCount(const QModelIndex& parent) const
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
return marketplace_->getSales().size();
|
return m_marketplace->getSales().size();
|
||||||
} else if (!parent.parent().isValid()) {
|
} else if (!parent.parent().isValid()) {
|
||||||
Sale* sale = static_cast<Sale*>(parent.internalPointer());
|
Sale* sale = static_cast<Sale*>(parent.internalPointer());
|
||||||
return sale->getArticles().size();
|
return sale->getArticles().size();
|
||||||
|
@ -165,7 +167,7 @@ QVariant SaleModel::headerData(int section, Qt::Orientation orientation, int rol
|
||||||
void SaleModel::onBasketDataChanged()
|
void SaleModel::onBasketDataChanged()
|
||||||
{
|
{
|
||||||
emit beginResetModel();
|
emit beginResetModel();
|
||||||
auto& sales = marketplace_->getSales();
|
auto& sales = m_marketplace->getSales();
|
||||||
std::sort(sales.begin(), sales.end(), [](const auto& lhs, const auto& rhs) {
|
std::sort(sales.begin(), sales.end(), [](const auto& lhs, const auto& rhs) {
|
||||||
return lhs->getTimestamp() > rhs->getTimestamp();
|
return lhs->getTimestamp() > rhs->getTimestamp();
|
||||||
});
|
});
|
||||||
|
@ -177,11 +179,11 @@ bool SaleModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
// remove complete sale
|
// remove complete sale
|
||||||
emit beginRemoveRows(parent, row, row + count - 1);
|
emit beginRemoveRows(parent, row, row + count - 1);
|
||||||
auto& sale = marketplace_->getSales().at(row);
|
auto& sale = m_marketplace->getSales().at(row);
|
||||||
sale->setState(Sale::State::DELETE);
|
sale->setState(Sale::State::DELETE);
|
||||||
std::for_each(sale->getArticles().begin(), sale->getArticles().end(),
|
std::for_each(sale->getArticles().begin(), sale->getArticles().end(),
|
||||||
[](auto& a) { a->setState(Article::State::DELETE); });
|
[](auto& a) { a->setState(Article::State::DELETE); });
|
||||||
marketplace_->storeToDb();
|
m_marketplace->storeToDb();
|
||||||
emit endRemoveRows();
|
emit endRemoveRows();
|
||||||
|
|
||||||
} else if (!parent.parent().isValid()) {
|
} else if (!parent.parent().isValid()) {
|
||||||
|
@ -197,7 +199,7 @@ bool SaleModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||||
sale->setState(Sale::State::DELETE);
|
sale->setState(Sale::State::DELETE);
|
||||||
}
|
}
|
||||||
emit beginRemoveRows(parent.parent(), 0, 0);
|
emit beginRemoveRows(parent.parent(), 0, 0);
|
||||||
marketplace_->storeToDb();
|
m_marketplace->storeToDb();
|
||||||
emit endRemoveRows();
|
emit endRemoveRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef SALEMODEL_H
|
#ifndef SALEMODEL_H
|
||||||
#define SALEMODEL_H
|
#define SALEMODEL_H
|
||||||
|
|
||||||
#include <marketplace.h>
|
#include <core/marketplace.h>
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ class SaleModel : public QAbstractItemModel
|
||||||
public:
|
public:
|
||||||
explicit SaleModel(Marketplace* market, QObject* parent = nullptr);
|
explicit SaleModel(Marketplace* market, QObject* parent = nullptr);
|
||||||
virtual QModelIndex index(int row, int column,
|
virtual QModelIndex index(int row, int column,
|
||||||
const QModelIndex& parent = QModelIndex()) const override;
|
const QModelIndex& parent = QModelIndex()) const override;
|
||||||
virtual QModelIndex parent(const QModelIndex& index) const override;
|
virtual QModelIndex parent(const QModelIndex& index) const override;
|
||||||
virtual QVariant data(const QModelIndex& index, int role) const override;
|
virtual QVariant data(const QModelIndex& index, int role) const override;
|
||||||
virtual int rowCount(const QModelIndex& parent) const override;
|
virtual int rowCount(const QModelIndex& parent) const override;
|
||||||
|
@ -24,8 +24,8 @@ class SaleModel : public QAbstractItemModel
|
||||||
void onBasketDataChanged();
|
void onBasketDataChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Marketplace* marketplace_;
|
Marketplace* m_marketplace;
|
||||||
std::unique_ptr<Sale> rootItem{new Sale()};
|
std::unique_ptr<Sale> m_rootItem{new Sale()};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -7,25 +7,25 @@
|
||||||
|
|
||||||
SellerDialog::SellerDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f)
|
SellerDialog::SellerDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f)
|
||||||
{
|
{
|
||||||
ui_.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
ui_.editButton->setVisible(false);
|
m_ui.editButton->setVisible(false);
|
||||||
market_ = dynamic_cast<MainWindow*>(parent)->getMarketplace();
|
m_market = dynamic_cast<MainWindow*>(parent)->getMarketplace();
|
||||||
model_ = std::make_unique<SellerModel>(market_, ui_.tableView);
|
m_model = std::make_unique<SellerModel>(m_market, m_ui.tableView);
|
||||||
ui_.tableView->setModel(model_.get());
|
m_ui.tableView->setModel(m_model.get());
|
||||||
ui_.tableView->setColumnHidden(0, true); // hide the uuid
|
m_ui.tableView->setColumnHidden(0, true); // hide the uuid
|
||||||
ui_.tableView->setRowHidden(0, true); // hide the special "Sonderkonto" user
|
m_ui.tableView->setRowHidden(0, true); // hide the special "Sonderkonto" user
|
||||||
connect(ui_.newButton, &QPushButton::clicked, this, &SellerDialog::on_newButton_clicked);
|
connect(m_ui.newButton, &QPushButton::clicked, this, &SellerDialog::on_newButton_clicked);
|
||||||
connect(ui_.deleteButton, &QPushButton::clicked, this, &SellerDialog::on_deleteButton_clicked);
|
connect(m_ui.deleteButton, &QPushButton::clicked, this, &SellerDialog::on_deleteButton_clicked);
|
||||||
connect(model_.get(), &SellerModel::duplicateSellerNo, this,
|
connect(m_model.get(), &SellerModel::duplicateSellerNo, this,
|
||||||
&SellerDialog::on_model_duplicateSellerNo);
|
&SellerDialog::on_model_duplicateSellerNo);
|
||||||
connect(ui_.tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
connect(m_ui.tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||||
&SellerDialog::onSellerViewSelectionChanged);
|
&SellerDialog::onSellerViewSelectionChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SellerDialog::on_newButton_clicked()
|
void SellerDialog::on_newButton_clicked()
|
||||||
{
|
{
|
||||||
// Don't allow new seller if market has already started
|
// Don't allow new seller if market has already started
|
||||||
if (market_->getSales().size() > 0) {
|
if (m_market->getSales().size() > 0) {
|
||||||
QMessageBox(QMessageBox::Icon::Warning, "Hinweis",
|
QMessageBox(QMessageBox::Icon::Warning, "Hinweis",
|
||||||
"Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) "
|
"Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) "
|
||||||
"können Sie keine Verkäufer mehr hinzufügen.",
|
"können Sie keine Verkäufer mehr hinzufügen.",
|
||||||
|
@ -34,22 +34,22 @@ void SellerDialog::on_newButton_clicked()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_.tableView->reset();
|
m_ui.tableView->reset();
|
||||||
ui_.tableView->model()->insertRows(ui_.tableView->model()->rowCount(), 1);
|
m_ui.tableView->model()->insertRows(m_ui.tableView->model()->rowCount(), 1);
|
||||||
ui_.tableView->scrollToBottom();
|
m_ui.tableView->scrollToBottom();
|
||||||
ui_.tableView->selectRow(ui_.tableView->model()->rowCount() - 1);
|
m_ui.tableView->selectRow(m_ui.tableView->model()->rowCount() - 1);
|
||||||
QModelIndex idx = ui_.tableView->model()->index(ui_.tableView->model()->rowCount() - 1, 2);
|
QModelIndex idx = m_ui.tableView->model()->index(m_ui.tableView->model()->rowCount() - 1, 2);
|
||||||
ui_.tableView->setCurrentIndex(idx);
|
m_ui.tableView->setCurrentIndex(idx);
|
||||||
ui_.tableView->edit(idx);
|
m_ui.tableView->edit(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SellerDialog::on_deleteButton_clicked()
|
void SellerDialog::on_deleteButton_clicked()
|
||||||
{
|
{
|
||||||
auto selModel = ui_.tableView->selectionModel();
|
auto selModel = m_ui.tableView->selectionModel();
|
||||||
if (selModel->hasSelection() == false)
|
if (selModel->hasSelection() == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (market_->getSales().size() > 0) {
|
if (m_market->getSales().size() > 0) {
|
||||||
QMessageBox(QMessageBox::Icon::Warning, "Hinweis",
|
QMessageBox(QMessageBox::Icon::Warning, "Hinweis",
|
||||||
"Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) "
|
"Da die Verkaufsphase schon begonnen hat (Artikel wurden bereits verkauft) "
|
||||||
"können Sie keine Verkäufer mehr löschen.",
|
"können Sie keine Verkäufer mehr löschen.",
|
||||||
|
@ -60,7 +60,8 @@ void SellerDialog::on_deleteButton_clicked()
|
||||||
|
|
||||||
auto dlgResult =
|
auto dlgResult =
|
||||||
QMessageBox(QMessageBox::Icon::Warning, "Sind Sie sicher?",
|
QMessageBox(QMessageBox::Icon::Warning, "Sind Sie sicher?",
|
||||||
"Löschen wirkt sich direkt auf die Datenbank aus. Möchten Sie fortfahren?",
|
"Löschen wirkt sich <b>sofort</b> auf die Datenbank aus. Sie können den "
|
||||||
|
"Vorgang nicht rückgängig machen. Möchten Sie fortfahren?",
|
||||||
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, this)
|
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, this)
|
||||||
.exec();
|
.exec();
|
||||||
if (dlgResult == QMessageBox::No)
|
if (dlgResult == QMessageBox::No)
|
||||||
|
@ -71,7 +72,7 @@ void SellerDialog::on_deleteButton_clicked()
|
||||||
|
|
||||||
// Deleting the rows, beginning with the last one!
|
// Deleting the rows, beginning with the last one!
|
||||||
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
for (auto iter = indexes.constEnd() - 1; iter >= indexes.constBegin(); --iter) {
|
||||||
ui_.tableView->model()->removeRow(iter->row());
|
m_ui.tableView->model()->removeRow(iter->row());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,8 +102,8 @@ void SellerDialog::onSellerViewSelectionChanged(const QItemSelection& selected,
|
||||||
[[maybe_unused]] const QItemSelection& deselected)
|
[[maybe_unused]] const QItemSelection& deselected)
|
||||||
{
|
{
|
||||||
if (selected.size() > 0) {
|
if (selected.size() > 0) {
|
||||||
ui_.deleteButton->setEnabled(true);
|
m_ui.deleteButton->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
ui_.deleteButton->setEnabled(false);
|
m_ui.deleteButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -26,9 +26,9 @@ class SellerDialog : public QDialog
|
||||||
void on_deleteButton_clicked();
|
void on_deleteButton_clicked();
|
||||||
void on_model_duplicateSellerNo(const QString& message);
|
void on_model_duplicateSellerNo(const QString& message);
|
||||||
virtual void accept() override;
|
virtual void accept() override;
|
||||||
Ui::SellerDialog ui_;
|
Ui::SellerDialog m_ui;
|
||||||
Marketplace* market_;
|
Marketplace* m_market;
|
||||||
std::unique_ptr<SellerModel> model_;
|
std::unique_ptr<SellerModel> m_model;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -5,13 +5,13 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
SellerModel::SellerModel(Marketplace* market, QObject* parent)
|
SellerModel::SellerModel(Marketplace* market, QObject* parent)
|
||||||
: QAbstractTableModel(parent), marketplace_(market)
|
: QAbstractTableModel(parent), m_marketplace(market)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SellerModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
|
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; }
|
int SellerModel::columnCount([[maybe_unused]] const QModelIndex& parent) const { return 5; }
|
||||||
|
@ -21,17 +21,14 @@ QVariant SellerModel::data(const QModelIndex& index, int role) const
|
||||||
if (role != Qt::DisplayRole)
|
if (role != Qt::DisplayRole)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (marketplace_->getSellers().size() == 0)
|
if (m_marketplace->getSellers().size() == 0)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
Seller* seller = marketplace_->getSellers().at(index.row()).get();
|
Seller* seller = m_marketplace->getSellers().at(index.row()).get();
|
||||||
|
|
||||||
/* if (seller->getState() == Seller::State::DELETE)
|
|
||||||
return QVariant();
|
|
||||||
*/
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0:
|
case 0:
|
||||||
return seller->getUuidAsString().c_str();
|
return seller->getId();
|
||||||
case 1:
|
case 1:
|
||||||
return seller->getSellerNo();
|
return seller->getSellerNo();
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -81,21 +78,21 @@ bool SellerModel::setData(const QModelIndex& index, const QVariant& value, int r
|
||||||
if (role != Qt::EditRole)
|
if (role != Qt::EditRole)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Seller* seller = marketplace_->getSellers().at(index.row()).get();
|
Seller* seller = m_marketplace->getSellers().at(index.row()).get();
|
||||||
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0:
|
case 0:
|
||||||
seller->setUuidFromString(value.toString().toStdString());
|
seller->setId(value.toInt());
|
||||||
break;
|
break;
|
||||||
case 1: {
|
case 1: {
|
||||||
if (value.toInt() < 0)
|
if (value.toInt() < 0)
|
||||||
return false;
|
return false;
|
||||||
auto iter =
|
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) {
|
[&value](const std::unique_ptr<Seller>& s) {
|
||||||
return value.toInt() == s->getSellerNo();
|
return value.toInt() == s->getSellerNo();
|
||||||
});
|
});
|
||||||
if (iter != marketplace_->getSellers().end()) {
|
if (iter != m_marketplace->getSellers().end()) {
|
||||||
emit duplicateSellerNo(
|
emit duplicateSellerNo(
|
||||||
"Die Verkäufernummer muss eindeutig sein.\n(Möglicherweise wird die Nummer von "
|
"Die Verkäufernummer muss eindeutig sein.\n(Möglicherweise wird die Nummer von "
|
||||||
"einem (ausgeblendeten) Eintrag, der zum Löschen vorgemerkt ist, verwendet.)");
|
"einem (ausgeblendeten) Eintrag, der zum Löschen vorgemerkt ist, verwendet.)");
|
||||||
|
@ -126,9 +123,8 @@ bool SellerModel::insertRows(int row, int count, const QModelIndex& parent)
|
||||||
{
|
{
|
||||||
emit beginInsertRows(parent, row, row + count - 1);
|
emit beginInsertRows(parent, row, row + count - 1);
|
||||||
auto seller = std::make_unique<Seller>();
|
auto seller = std::make_unique<Seller>();
|
||||||
seller->createUuid();
|
seller->setSellerNo(m_marketplace->getNextSellerNo());
|
||||||
seller->setSellerNo(marketplace_->getNextSellerNo());
|
m_marketplace->getSellers().push_back(std::move(seller));
|
||||||
marketplace_->getSellers().push_back(std::move(seller));
|
|
||||||
emit endInsertRows();
|
emit endInsertRows();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -136,21 +132,21 @@ bool SellerModel::insertRows(int row, int count, const QModelIndex& parent)
|
||||||
|
|
||||||
bool SellerModel::removeRows(int row, int count, const QModelIndex& parent)
|
bool SellerModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||||
{
|
{
|
||||||
auto seller = marketplace_->getSellers().at(row).get();
|
auto seller = m_marketplace->getSellers().at(row).get();
|
||||||
if (seller->getState() == Seller::State::NEW) {
|
if (seller->getState() == Seller::State::NEW) {
|
||||||
emit beginRemoveRows(parent, row, row + count - 1);
|
emit beginRemoveRows(parent, row, row + count - 1);
|
||||||
marketplace_->getSellers().erase(
|
m_marketplace->getSellers().erase(
|
||||||
std::remove_if(marketplace_->getSellers().begin(), marketplace_->getSellers().end(),
|
std::remove_if(m_marketplace->getSellers().begin(), m_marketplace->getSellers().end(),
|
||||||
[&seller](const std::unique_ptr<Seller>& a) {
|
[&seller](const std::unique_ptr<Seller>& a) {
|
||||||
return a->getUuid() == seller->getUuid();
|
return a->getId() == seller->getId();
|
||||||
}),
|
}),
|
||||||
marketplace_->getSellers().end());
|
m_marketplace->getSellers().end());
|
||||||
emit endRemoveRows();
|
emit endRemoveRows();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
emit beginRemoveRows(parent, row, row + count - 1);
|
emit beginRemoveRows(parent, row, row + count - 1);
|
||||||
seller->setState(Seller::State::DELETE);
|
seller->setState(Seller::State::DELETE);
|
||||||
marketplace_->storeToDb(true);
|
m_marketplace->storeToDb(true);
|
||||||
emit endRemoveRows();
|
emit endRemoveRows();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,31 @@
|
||||||
#ifndef SELLER_MODEL_H
|
#ifndef SELLER_MODEL_H
|
||||||
#define SELLER_MODEL_H
|
#define SELLER_MODEL_H
|
||||||
|
|
||||||
#include <marketplace.h>
|
#include <core/marketplace.h>
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
class SellerModel : public QAbstractTableModel
|
class SellerModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SellerModel(Marketplace* market, QObject* parent = nullptr);
|
explicit SellerModel(Marketplace *market, QObject *parent = nullptr);
|
||||||
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
virtual Qt::ItemFlags flags(const QModelIndex& index) const override;
|
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
|
virtual bool setData(const QModelIndex &index, const QVariant &value,
|
||||||
virtual bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
|
int role = Qt::EditRole) override;
|
||||||
virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
|
virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||||
|
virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void duplicateSellerNo(const QString& message);
|
void duplicateSellerNo(const QString &message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Marketplace* marketplace_;
|
Marketplace *m_marketplace;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include <database.h>
|
#include <core/database.h>
|
||||||
#include <posprinter.h>
|
#include <core/utils.h>
|
||||||
#include <utils.h>
|
#include <printer/posprinter.h>
|
||||||
|
#include <printer/utils.h>
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
@ -12,9 +13,9 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f)
|
SettingsDialog::SettingsDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f)
|
||||||
{
|
{
|
||||||
ui_.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
QSettings settings{};
|
QSettings settings{};
|
||||||
int cashPointNo = settings.value("global/cashPointNo").toInt();
|
int cashPointNo = settings.value("global/cashPointNo").toInt();
|
||||||
|
@ -25,25 +26,25 @@ SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(par
|
||||||
int maxFeeInEuro = settings.value("global/maxFeeInEuro").toInt();
|
int maxFeeInEuro = settings.value("global/maxFeeInEuro").toInt();
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
market_ = dynamic_cast<MainWindow*>(parent)->getMarketplace();
|
m_market = dynamic_cast<MainWindow *>(parent)->getMarketplace();
|
||||||
|
|
||||||
ui_.cashPointNoSpinBox->setValue(cashPointNo);
|
m_ui.cashPointNoSpinBox->setValue(cashPointNo);
|
||||||
ui_.communeEdit->setText(commune);
|
m_ui.communeEdit->setText(commune);
|
||||||
ui_.posPrinterDeviceEdit->setText(posPrinterDevice);
|
m_ui.posPrinterDeviceEdit->setText(posPrinterDevice);
|
||||||
ui_.posPrinterEndpointEdit->setText(posPrinterEndpoint);
|
m_ui.posPrinterEndpointEdit->setText(posPrinterEndpoint);
|
||||||
ui_.feePercentSpinBox->setValue(feeInPercent);
|
m_ui.feePercentSpinBox->setValue(feeInPercent);
|
||||||
ui_.maxFeeSpinBox->setValue(maxFeeInEuro);
|
m_ui.maxFeeSpinBox->setValue(maxFeeInEuro);
|
||||||
|
|
||||||
connect(ui_.testPosPrinterButton, &QPushButton::clicked, this, [=]() {
|
connect(m_ui.testPosPrinterButton, &QPushButton::clicked, this, [this]() {
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
try {
|
try {
|
||||||
if (ui_.posPrinterDeviceEdit->text().isEmpty()) {
|
if (m_ui.posPrinterDeviceEdit->text().isEmpty()) {
|
||||||
PosPrinter printer;
|
PosPrinter printer;
|
||||||
printer.printTest();
|
printer.printTest();
|
||||||
} else {
|
} else {
|
||||||
std::string posPrinterDeviceString = ui_.posPrinterDeviceEdit->text().toStdString();
|
std::string posPrinterDeviceString = m_ui.posPrinterDeviceEdit->text().toStdString();
|
||||||
std::string posPrinterEndpointString =
|
std::string posPrinterEndpointString =
|
||||||
ui_.posPrinterEndpointEdit->text().toStdString();
|
m_ui.posPrinterEndpointEdit->text().toStdString();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto printerDevice =
|
auto printerDevice =
|
||||||
|
@ -54,7 +55,7 @@ SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(par
|
||||||
printer.printTest();
|
printer.printTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (std::exception&) {
|
} catch (std::exception &) {
|
||||||
QMessageBox(QMessageBox::Icon::Warning, "Falsche Eingabe",
|
QMessageBox(QMessageBox::Icon::Warning, "Falsche Eingabe",
|
||||||
QString("Eingabeformat für Device (hexadezimale IDs): "
|
QString("Eingabeformat für Device (hexadezimale IDs): "
|
||||||
"<VendorID>:<ProductID>\nBeispiel: 0416:5011\n "
|
"<VendorID>:<ProductID>\nBeispiel: 0416:5011\n "
|
||||||
|
@ -64,7 +65,7 @@ SettingsDialog::SettingsDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(par
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (std::runtime_error& err) {
|
} catch (std::runtime_error &err) {
|
||||||
QMessageBox(QMessageBox::Icon::Warning, "Bondrucker Fehler",
|
QMessageBox(QMessageBox::Icon::Warning, "Bondrucker Fehler",
|
||||||
QString("Test schlug fehl: ") + err.what(), QMessageBox::StandardButton::Ok,
|
QString("Test schlug fehl: ") + err.what(), QMessageBox::StandardButton::Ok,
|
||||||
this)
|
this)
|
||||||
|
@ -79,17 +80,17 @@ void SettingsDialog::accept()
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
int oldCashPointNo = settings.value("global/cashPointNo").toInt();
|
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/commune", m_ui.communeEdit->text().trimmed());
|
||||||
settings.setValue("global/posPrinterDevice", ui_.posPrinterDeviceEdit->text().trimmed());
|
settings.setValue("global/posPrinterDevice", m_ui.posPrinterDeviceEdit->text().trimmed());
|
||||||
settings.setValue("global/posPrinterEndpoint", ui_.posPrinterEndpointEdit->text().trimmed());
|
settings.setValue("global/posPrinterEndpoint", m_ui.posPrinterEndpointEdit->text().trimmed());
|
||||||
settings.setValue("global/feeInPercent", ui_.feePercentSpinBox->value());
|
settings.setValue("global/feeInPercent", m_ui.feePercentSpinBox->value());
|
||||||
settings.setValue("global/maxFeeInEuro", ui_.maxFeeSpinBox->value());
|
settings.setValue("global/maxFeeInEuro", m_ui.maxFeeSpinBox->value());
|
||||||
|
|
||||||
if (oldCashPointNo != newCashPointNo) {
|
if (oldCashPointNo != newCashPointNo) {
|
||||||
int result{0};
|
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?",
|
result = QMessageBox(QMessageBox::Icon::Question, "Sind Sie sicher?",
|
||||||
"Möchten Sie die Kassen-Nr wirklich ändern? Diese muss über alle "
|
"Möchten Sie die Kassen-Nr wirklich ändern? Diese muss über alle "
|
||||||
"Installationen hinweg eindeutig sein.",
|
"Installationen hinweg eindeutig sein.",
|
||||||
|
@ -102,7 +103,7 @@ void SettingsDialog::accept()
|
||||||
if (result == QMessageBox::Yes) {
|
if (result == QMessageBox::Yes) {
|
||||||
try {
|
try {
|
||||||
Database().updateCashPointNo(oldCashPointNo, newCashPointNo);
|
Database().updateCashPointNo(oldCashPointNo, newCashPointNo);
|
||||||
} catch (std::exception& ex) {
|
} catch (std::exception &ex) {
|
||||||
std::string errMsg("Das Ändern der Kassen-Nr. ist fehlgeschlagen: ");
|
std::string errMsg("Das Ändern der Kassen-Nr. ist fehlgeschlagen: ");
|
||||||
errMsg.append(ex.what());
|
errMsg.append(ex.what());
|
||||||
QMessageBox(QMessageBox::Icon::Critical, "Fehler", errMsg.c_str(),
|
QMessageBox(QMessageBox::Icon::Critical, "Fehler", errMsg.c_str(),
|
||||||
|
@ -111,7 +112,7 @@ void SettingsDialog::accept()
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
settings.setValue("global/cashPointNo", ui_.cashPointNoSpinBox->value());
|
settings.setValue("global/cashPointNo", m_ui.cashPointNoSpinBox->value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,14 @@
|
||||||
|
|
||||||
#include "ui_settingsdialog.h"
|
#include "ui_settingsdialog.h"
|
||||||
|
|
||||||
#include <marketplace.h>
|
#include <core/marketplace.h>
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
class SettingsDialog : public QDialog
|
class SettingsDialog : public QDialog
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SettingsDialog(QWidget* parent = nullptr,
|
SettingsDialog(QWidget* parent = nullptr,
|
||||||
Qt::WindowFlags f = Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
Qt::WindowFlags f = Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||||
|
@ -17,8 +19,8 @@ class SettingsDialog : public QDialog
|
||||||
void accept() override;
|
void accept() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::SettingsDialog ui_;
|
Ui::SettingsDialog m_ui;
|
||||||
Marketplace* market_{};
|
Marketplace* m_market{};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
3
src/meson.build
Normal file
3
src/meson.build
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
subdir('core')
|
||||||
|
subdir('printer')
|
||||||
|
subdir('gui')
|
|
@ -1,6 +1,6 @@
|
||||||
set(Boost_USE_STATIC_LIBS ON)
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
|
|
||||||
find_package(Boost 1.62 REQUIRED)
|
find_package(Boost 1.78 REQUIRED)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
find_package(LIBUSB REQUIRED)
|
find_package(LIBUSB REQUIRED)
|
||||||
|
@ -11,6 +11,7 @@ endif()
|
||||||
|
|
||||||
set(PRINTER_SOURCES
|
set(PRINTER_SOURCES
|
||||||
posprinter.cpp
|
posprinter.cpp
|
||||||
|
utils.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(printer STATIC ${PRINTER_SOURCES})
|
add_library(printer STATIC ${PRINTER_SOURCES})
|
||||||
|
@ -19,4 +20,4 @@ if(WIN32)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(printer core ${LibUSB_LIBRARIES})
|
target_link_libraries(printer core ${LibUSB_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
target_include_directories(printer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories(printer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/.. ${Boost_INCLUDE_DIRS})
|
||||||
|
|
9
src/printer/meson.build
Normal file
9
src/printer/meson.build
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
libusb = dependency('libusb-1.0')
|
||||||
|
|
||||||
|
src = ['posprinter.cpp', 'utils.cpp']
|
||||||
|
|
||||||
|
printer_inc = include_directories('..')
|
||||||
|
|
||||||
|
printer_lib = static_library('printer', src, dependencies: [libusb, core_dep])
|
||||||
|
|
||||||
|
printer_dep = declare_dependency(link_with : printer_lib, include_directories : printer_inc)
|
|
@ -1,6 +1,6 @@
|
||||||
#include "posprinter.h"
|
#include "posprinter.h"
|
||||||
|
|
||||||
#include <marketplace.h>
|
#include <core/marketplace.h>
|
||||||
|
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef POS_PRINTER_H
|
#ifndef POS_PRINTER_H
|
||||||
#define POS_PRINTER_H
|
#define POS_PRINTER_H
|
||||||
|
|
||||||
#include <sale.h>
|
#include <core/sale.h>
|
||||||
#include <seller.h>
|
#include <core/seller.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -36,7 +36,8 @@ class PosPrinter
|
||||||
void printHeader(const std::string& commune = "Musterhausen");
|
void printHeader(const std::string& commune = "Musterhausen");
|
||||||
void printTest();
|
void printTest();
|
||||||
void printSaleReceipt(Sale* sale, const std::string& commune = "Dettingen");
|
void printSaleReceipt(Sale* sale, const std::string& commune = "Dettingen");
|
||||||
void printSellerReceipt(Seller* seller, const int percent, const int maxFeeInCent, const std::string& commune = "Dettingen");
|
void printSellerReceipt(Seller* seller, const int percent, const int maxFeeInCent,
|
||||||
|
const std::string& commune = "Dettingen");
|
||||||
bool isValid();
|
bool isValid();
|
||||||
|
|
||||||
struct Command {
|
struct Command {
|
||||||
|
|
26
src/printer/utils.cpp
Normal file
26
src/printer/utils.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
std::optional<PrinterDevice> convertToPosPrinterDevice(const std::string& device,
|
||||||
|
const std::string& endpoint)
|
||||||
|
{
|
||||||
|
if (device.empty()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrinterDevice printerDevice;
|
||||||
|
std::string delimiter = ":";
|
||||||
|
try {
|
||||||
|
printerDevice.idVendor = std::stoi(device.substr(0, device.find(delimiter)), 0, 16);
|
||||||
|
printerDevice.idProduct = std::stoi(device.substr(device.find(delimiter) + 1), 0, 16);
|
||||||
|
if (endpoint.empty()) {
|
||||||
|
printerDevice.endpoint = 0x03;
|
||||||
|
} else {
|
||||||
|
printerDevice.endpoint = std::stoi(endpoint, 0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (std::exception& ex) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return printerDevice;
|
||||||
|
}
|
12
src/printer/utils.h
Normal file
12
src/printer/utils.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef PRINTER_UTILS_H
|
||||||
|
#define PRINTER_UTILS_H
|
||||||
|
|
||||||
|
#include "posprinter.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
std::optional<PrinterDevice> convertToPosPrinterDevice(const std::string& vendor,
|
||||||
|
const std::string& endpoint);
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,3 +2,4 @@ if(NOT KIMA2_USE_EXTERNAL_JSON)
|
||||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||||
add_subdirectory(nlohmann_json EXCLUDE_FROM_ALL)
|
add_subdirectory(nlohmann_json EXCLUDE_FROM_ALL)
|
||||||
endif()
|
endif()
|
||||||
|
#add_subdirectory(csv-parser)
|
1
subprojects/nlohmann_json
Submodule
1
subprojects/nlohmann_json
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03
|
27
subprojects/singleapplication/meson.build
Normal file
27
subprojects/singleapplication/meson.build
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
project('singleapplication')
|
||||||
|
|
||||||
|
qt5 = import('qt5')
|
||||||
|
dep_qt5 = dependency('qt5', modules: ['Core', 'Widgets', 'Network'])
|
||||||
|
|
||||||
|
singleapp_inc = include_directories('singleapplication.git')
|
||||||
|
|
||||||
|
singleapp_moc = qt5.preprocess(
|
||||||
|
moc_headers: ['singleapplication.git/singleapplication.h', 'singleapplication.git/singleapplication_p.h'],
|
||||||
|
moc_extra_arguments: ['-DQAPPLICATION_CLASS=QApplication'],
|
||||||
|
dependencies: dep_qt5
|
||||||
|
)
|
||||||
|
|
||||||
|
singleapp_lib = static_library('SingleApplication',
|
||||||
|
['singleapplication.git/singleapplication.cpp', 'singleapplication.git/singleapplication_p.cpp', singleapp_moc],
|
||||||
|
include_directories: singleapp_inc,
|
||||||
|
cpp_args : '-DQAPPLICATION_CLASS=QApplication',
|
||||||
|
dependencies: dep_qt5
|
||||||
|
)
|
||||||
|
|
||||||
|
singleapp_dep = declare_dependency(
|
||||||
|
include_directories: singleapp_inc,
|
||||||
|
link_with: singleapp_lib
|
||||||
|
)
|
||||||
|
|
||||||
|
# On windows, SingleApplication needs to be linked against advapi32. This is
|
||||||
|
# done by adding 'advapi32' to cpp_winlibs, where it should be by default.
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 8c48163c4d3fbba603cfe8a5b94046c9dad71825
|
|
@ -9,14 +9,14 @@
|
||||||
BOOST_AUTO_TEST_CASE(create_uuid_nil)
|
BOOST_AUTO_TEST_CASE(create_uuid_nil)
|
||||||
{
|
{
|
||||||
Seller seller{};
|
Seller seller{};
|
||||||
BOOST_TEST(seller.getUuid().is_nil() == true);
|
BOOST_TEST(seller.getId().is_nil() == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(create_uuid)
|
BOOST_AUTO_TEST_CASE(create_uuid)
|
||||||
{
|
{
|
||||||
Seller seller{};
|
Seller seller{};
|
||||||
seller.createUuid();
|
seller.createUuid();
|
||||||
BOOST_TEST(seller.getUuid().is_nil() == false);
|
BOOST_TEST(seller.getId().is_nil() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(create_many)
|
BOOST_AUTO_TEST_CASE(create_many)
|
||||||
|
@ -25,7 +25,7 @@ BOOST_AUTO_TEST_CASE(create_many)
|
||||||
std::array<Seller, QUANTITY> sellers;
|
std::array<Seller, QUANTITY> sellers;
|
||||||
for (unsigned i = 0; i < sellers.size(); i++) {
|
for (unsigned i = 0; i < sellers.size(); i++) {
|
||||||
sellers[i] = Seller();
|
sellers[i] = Seller();
|
||||||
sellers[i].createUuid();
|
//sellers[i].createUuid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue