Compare commits
286 Commits
1fd67a6ee2
...
feature/ap
| Author | SHA256 | Date | |
|---|---|---|---|
|
|
76fdc880c7 | ||
|
|
45f19d80d0 | ||
|
|
0ae153617b | ||
|
|
2832becccf | ||
|
|
cf5822c950 | ||
|
|
f0382a960e | ||
|
|
a720dfebeb | ||
|
|
ddf35a55a8 | ||
|
|
1e9ba40b6b | ||
|
|
fc9b1c0801 | ||
|
|
3083406b1b | ||
|
|
f172468ba6 | ||
| eda50e036a | |||
|
|
7c66dcf890 | ||
| 8fec981409 | |||
| 16ba24b13d | |||
|
|
309f1f58d7 | ||
|
|
445c183e71 | ||
| 7b8c3630f8 | |||
| d125b56564 | |||
|
|
7f5675c06d | ||
|
|
30493dbdbf | ||
|
|
41ecdb658c | ||
| 6e8c2f340c | |||
| 76c4be7a7a | |||
| 8236bd32e6 | |||
|
|
480dd673c4 | ||
| 3520c65879 | |||
| a821956a67 | |||
| 46cba58ebe | |||
| a7a1cd4913 | |||
| 34bd7409df | |||
| 6df02d9ff2 | |||
| 9499eace9b | |||
|
|
721232a975 | ||
| 8f6efac11e | |||
|
|
83f64f9af8 | ||
| d6034a5299 | |||
|
|
dc1ea604f7 | ||
| 15b14387df | |||
| fadd3d1b9e | |||
|
|
fb06cea060 | ||
| 648753823f | |||
| 495252c408 | |||
|
|
5cf5676d9b | ||
|
|
9a6d59a19b | ||
| 5b7e364c20 | |||
| ce26d6d223 | |||
|
|
13416edd25 | ||
| c49e4ebacd | |||
| 7b1f5cd3cc | |||
| 325e396774 | |||
| f20cebab14 | |||
| bd7cba5430 | |||
| 607cccfb07 | |||
| 8b82b49982 | |||
|
|
9ff0a0fbce | ||
|
|
ef77e4c17d | ||
| 7b0ec6ed99 | |||
|
|
7099102e13 | ||
|
|
343e15c873 | ||
|
|
2704177fdb | ||
| 773d398f8c | |||
| 714a12e2d3 | |||
| 898d808b1f | |||
| e3053be72e | |||
| ac6a83c352 | |||
|
|
469b8d0a21 | ||
| 0834ee8905 | |||
| c8114d9e54 | |||
| 002575baa1 | |||
| 66fce857ba | |||
| 767200096f | |||
| 55a35d0931 | |||
| 2a01433cf0 | |||
| 66c1b168c8 | |||
| f61f1e5c8f | |||
| 4c07689a4a | |||
| 5bf1d8de08 | |||
| 09a0daad66 | |||
| 5b031e9d8d | |||
| 155794e489 | |||
| 712df39383 | |||
| f5b32d6621 | |||
| c132b6830a | |||
| a6bed81aaf | |||
| 78ede0fad8 | |||
| 26759be1cb | |||
| 35c977c89e | |||
| bd232a2a28 | |||
| b414a050be | |||
| 821da47f98 | |||
| fb81b764f1 | |||
| e81407b43d | |||
| 73542e8089 | |||
| 89e96422cc | |||
| eacd3dacc7 | |||
| e0ec99098e | |||
| 6bf6ff3111 | |||
| 4c62834369 | |||
| e528729181 | |||
| d7928d25fc | |||
| bd2316dbfb | |||
| 82b3c2d403 | |||
| 8ee303227e | |||
| 2a09fed57a | |||
| e7d0b7cdb5 | |||
| f0cde5ec20 | |||
| 3738bf1c6e | |||
| dec4ca59f0 | |||
| 0f253c518d | |||
| 7228d5fae9 | |||
| e2410d0852 | |||
| a68ae311bf | |||
| cc25f85771 | |||
| fdaae34678 | |||
| b468c3d078 | |||
| 5ff4749247 | |||
| 80bd2c9be2 | |||
| bfd1d0974d | |||
| b162117a80 | |||
| 3eeb6ab910 | |||
| aca38067d0 | |||
| 1f5e9c01e8 | |||
| 42c7a9c33a | |||
| 0813c3c8c0 | |||
| bcc616d3b5 | |||
| f710db48de | |||
| a709aa6da1 | |||
| 83d44cf3c7 | |||
| b5c3b56fb3 | |||
| 931a99c06b | |||
| 337f383701 | |||
| af04b3baa1 | |||
| 0b55556fb4 | |||
| 0923365cbd | |||
| 74b00c0b94 | |||
| 716915f333 | |||
| 538399b59a | |||
| 8e9fe46b96 | |||
| ba08715c9a | |||
| 104aba8347 | |||
| 338733a0fb | |||
| d512d1d8b0 | |||
| 00e535bb13 | |||
| 103b172a60 | |||
| c2edfab9a2 | |||
| 180f8e5ae9 | |||
| dab3df3b14 | |||
| 75dc64b4f3 | |||
| afad232068 | |||
| d870736dab | |||
| fc197246a6 | |||
| 705bffc8d3 | |||
| e94a9f9900 | |||
| f035f60910 | |||
| f2969aeafe | |||
| 3fc795f962 | |||
| 416b9cb5b1 | |||
| 3eadad5d5b | |||
| 80a269a729 | |||
| 8f41c240ac | |||
| 1d5201454c | |||
| b66c8ba41e | |||
| dcb4df631f | |||
| edaad51ea7 | |||
| 7f26e4d898 | |||
| 493e5383fb | |||
| 576d8bc977 | |||
| e583beecbe | |||
| 6182c275d0 | |||
| 1582194753 | |||
| f39cb0fcaf | |||
| 4e378d290c | |||
| ba37903a5d | |||
| 82c33d80b5 | |||
| 0365439c50 | |||
| 960759eeab | |||
| 903a2b8dc1 | |||
| 559ad1b882 | |||
| 59e5fadd26 | |||
| 81ec81f411 | |||
| 3858d7a46a | |||
| 89dc1d3010 | |||
| e7c9406aa3 | |||
| 07a3fe6c13 | |||
| b318694acb | |||
| 9ea0c94674 | |||
| e2fe0c89c0 | |||
| 9a8be0409a | |||
| 7c61b2a532 | |||
| 8830e277ec | |||
| 6fd0c5e770 | |||
| d25d4861f9 | |||
| 959810c9e3 | |||
| 77922d104c | |||
| 28c32dba8a | |||
| f9dfcf95bf | |||
| 3f33fbfdfb | |||
| cf7bde958b | |||
| 3acafaea32 | |||
| 5f08435816 | |||
| 1900100b54 | |||
| 2c9fc6380a | |||
| 17445ff594 | |||
| 4dfe986111 | |||
| 82cbfb8daf | |||
| f4bd9c296a | |||
| 5865b33c1d | |||
| 50720596c6 | |||
| 6e91637792 | |||
| 7157176b5b | |||
| b028638d56 | |||
| 2bc0730fbf | |||
| 5bf35ce12a | |||
| 294ceab157 | |||
| 7f4410c7ea | |||
| 70ad4d557b | |||
| 6b0e8e316f | |||
| 77052d8ef7 | |||
| 4a5545ce18 | |||
| 3df853b5c9 | |||
| 12eb6cf2f4 | |||
| 93efaabe6d | |||
| 304f9cabc5 | |||
| 4f8500ca98 | |||
| ddcf3e5a14 | |||
| dc2f6a5bb0 | |||
| d0f2644fe5 | |||
| a9804cbde1 | |||
| 3d5035ffb3 | |||
| 0e8e03dc5d | |||
| a89fe6e1d5 | |||
| 86618200ba | |||
| e61c51a026 | |||
| 54eb836dd1 | |||
| b6368718ca | |||
| 9f5e4af741 | |||
| 167d5ff3fe | |||
| fe011fd0bd | |||
| 0914322e2d | |||
| 0da5aae997 | |||
| 1a115fecda | |||
| 28c6e35dd6 | |||
| 0e568cd325 | |||
| a40e657922 | |||
| 5ab1c8d82a | |||
| 226a49a523 | |||
| fa5005cb73 | |||
| e543f316db | |||
| 9197102772 | |||
| 2e7c3c8032 | |||
| 7a00bb793f | |||
| 0bb5f718f1 | |||
| b0299596ab | |||
| f6dd06e4df | |||
| d7b2243919 | |||
| 5274fdb0c4 | |||
| 6849fc0d86 | |||
| 8c406ba625 | |||
| 9bb2df841d | |||
| bde021c7d3 | |||
| 18c600c7c7 | |||
| ca4d8f6b9c | |||
| 29228cf65d | |||
| 33782aa785 | |||
| d11743bacf | |||
| 24a5255bac | |||
| bbad3b5fcb | |||
| 78dfc93ba8 | |||
| 1907485152 | |||
| 8150b90a2d | |||
| a8bb0623cc | |||
| 9b30f5e127 | |||
| 493270efc1 | |||
| 4ecec8e25b | |||
| 840bf16a22 | |||
| f384b3201f | |||
| c2f7cfc37b | |||
| 6969007358 | |||
| 64d4fa3305 | |||
| fcdcf3b0d9 | |||
| cce7c57036 | |||
| 8518d06797 | |||
| 864255625f | |||
| fb5b23efbb |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -197,6 +197,8 @@ venv.bak/
|
|||||||
|
|
||||||
.qtcreator/
|
.qtcreator/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# mypy
|
# mypy
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
.dmypy.json
|
.dmypy.json
|
||||||
@@ -225,3 +227,5 @@ cython_debug/
|
|||||||
.directory
|
.directory
|
||||||
|
|
||||||
|
|
||||||
|
rc_*.py
|
||||||
|
.DS_STORE
|
||||||
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
17
.idea/QtSettings.xml
generated
Normal file
17
.idea/QtSettings.xml
generated
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="QtSettings">
|
||||||
|
<option name="mySettingsPerProfile">
|
||||||
|
<map>
|
||||||
|
<entry key="">
|
||||||
|
<value>
|
||||||
|
<PerProfileState>
|
||||||
|
<option name="myCustomQmlPath" value="/opt/homebrew/share/qt/qml" />
|
||||||
|
<option name="myCustomQtBinPath" value="/opt/homebrew/bin" />
|
||||||
|
</PerProfileState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
12
.idea/dataSources.xml
generated
Normal file
12
.idea/dataSources.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
|
<data-source source="LOCAL" name="pyqcrm@bearybot.selfhost.co" uuid="ed28331b-481b-40e7-9295-d9cdae9fd4f2">
|
||||||
|
<driver-ref>mariadb</driver-ref>
|
||||||
|
<synchronize>true</synchronize>
|
||||||
|
<jdbc-driver>org.mariadb.jdbc.Driver</jdbc-driver>
|
||||||
|
<jdbc-url>jdbc:mariadb://bearybot.selfhost.co:8080/pyqcrm</jdbc-url>
|
||||||
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
|
</data-source>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
16
.idea/discord.xml
generated
Normal file
16
.idea/discord.xml
generated
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DiscordProjectSettings">
|
||||||
|
<option name="show" value="PROJECT_FILES" />
|
||||||
|
<option name="nameOverrideEnabled" value="true" />
|
||||||
|
<option name="nameOverrideText" value="the qml thing (╯°□°)╯︵ ┻━┻" />
|
||||||
|
<option name="description" value="" />
|
||||||
|
<option name="applicationTheme" value="default" />
|
||||||
|
<option name="iconsTheme" value="default" />
|
||||||
|
<option name="button1Title" value="" />
|
||||||
|
<option name="button1Url" value="" />
|
||||||
|
<option name="button2Title" value="" />
|
||||||
|
<option name="button2Url" value="" />
|
||||||
|
<option name="customApplicationId" value="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
7
.idea/misc.xml
generated
Normal file
7
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Python 3.12 (pyqcrm)" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (pyqcrm)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/pyqcrm.iml" filepath="$PROJECT_DIR$/.idea/pyqcrm.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
10
.idea/pyqcrm.iml
generated
Normal file
10
.idea/pyqcrm.iml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.12 (pyqcrm)" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
22
.idea/qmlSettings.xml
generated
Normal file
22
.idea/qmlSettings.xml
generated
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="QmlSettings">
|
||||||
|
<option name="mySettingsPerProfile">
|
||||||
|
<map>
|
||||||
|
<entry key="">
|
||||||
|
<value>
|
||||||
|
<PerProfileState>
|
||||||
|
<option name="myExtraQmlPaths">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/TeroStyle" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="myLSPEnabled" value="true" />
|
||||||
|
<option name="myQmlFormatEnabled" value="true" />
|
||||||
|
</PerProfileState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
17
.idea/runConfigurations/Compile_pyqcrm_qrc.xml
generated
Normal file
17
.idea/runConfigurations/Compile_pyqcrm_qrc.xml
generated
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Compile pyqcrm.qrc" type="ShConfigurationType">
|
||||||
|
<option name="SCRIPT_TEXT" value=".venv/bin/pyside6-rcc -o rc_pyqcrm.py pyqcrm.qrc" />
|
||||||
|
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||||
|
<option name="SCRIPT_PATH" value=".venv/bin/pyside6-rcc" />
|
||||||
|
<option name="SCRIPT_OPTIONS" value="-o rc_qml.py qml.qrc" />
|
||||||
|
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||||
|
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||||
|
<option name="INTERPRETER_PATH" value="/bin/zsh" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="EXECUTE_IN_TERMINAL" value="false" />
|
||||||
|
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
||||||
|
<envs />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
17
.idea/runConfigurations/Compile_qml_qrc.xml
generated
Normal file
17
.idea/runConfigurations/Compile_qml_qrc.xml
generated
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Compile qml.qrc" type="ShConfigurationType">
|
||||||
|
<option name="SCRIPT_TEXT" value=".venv/bin/pyside6-rcc -o rc_qml.py qml.qrc" />
|
||||||
|
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||||
|
<option name="SCRIPT_PATH" value=".venv/bin/pyside6-rcc" />
|
||||||
|
<option name="SCRIPT_OPTIONS" value="-o rc_qml.py qml.qrc" />
|
||||||
|
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||||
|
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||||
|
<option name="INTERPRETER_PATH" value="/bin/zsh" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="EXECUTE_IN_TERMINAL" value="false" />
|
||||||
|
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
||||||
|
<envs />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
31
.idea/runConfigurations/main.xml
generated
Normal file
31
.idea/runConfigurations/main.xml
generated
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="main" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
|
||||||
|
<module name="pyqcrm" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
<env name="QT_LOGGING_RULES" value="*.debug=true; qt.*.debug=false" />
|
||||||
|
<env name="QT_LOGGING_TO_CONSOLE" value="1" />
|
||||||
|
<env name="QT_QML_DEBUG" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="SDK_NAME" value="Python 3.12 (pyqcrm)" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||||
|
<option name="IS_MODULE_SDK" value="false" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Compile qml.qrc" run_configuration_type="ShConfigurationType" />
|
||||||
|
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Compile pyqcrm.qrc" run_configuration_type="ShConfigurationType" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
6
.idea/sqldialects.xml
generated
Normal file
6
.idea/sqldialects.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="SqlDialectMappings">
|
||||||
|
<file url="file://$PROJECT_DIR$/doc/db_schemer_v1.1-pyqcrm-202503171158_clean.sql" dialect="MariaDB" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
BIN
Dienstleistungen.docx
Normal file
BIN
Dienstleistungen.docx
Normal file
Binary file not shown.
202
Gui/AddContact.qml
Normal file
202
Gui/AddContact.qml
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Frame
|
||||||
|
{
|
||||||
|
id: addContactFrame
|
||||||
|
property alias contactGrid: addContactLayout
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: addContactLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
// Layout.fillWidth: true
|
||||||
|
// Layout.fillHeight: true
|
||||||
|
// Layout.alignment: Qt.AlignTop
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 9
|
||||||
|
property alias fname: firstname
|
||||||
|
property alias lname: lastname
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Anrede")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "title"
|
||||||
|
id: title
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: ["Herr", "Frau"]
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Vorname")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "firstname"
|
||||||
|
id: firstname
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Nachname")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "lastname"
|
||||||
|
id: lastname
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Position")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "jobdescription"
|
||||||
|
id: jobdescription
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("E-Mail")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "email"
|
||||||
|
id: emailcontact
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderText: qsTr("beispiel@domain.de")
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([\+!#$%&‘\*\–\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Telefon")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "telephonecontact"
|
||||||
|
id: telephonecontact
|
||||||
|
Layout.fillWidth: true
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([+0-9]{1})([0-9]{1,17})/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Mobil")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "cellphone"
|
||||||
|
id: cellphone
|
||||||
|
Layout.fillWidth: true
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([+0-9]{1})([0-9]{1,17})/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Geburtsdatum")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "birthday"
|
||||||
|
id: birthday
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderText: qsTr("TT.MM.JJJJ")
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
|
||||||
|
{
|
||||||
|
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
|
||||||
|
}
|
||||||
|
Keys.onPressed: (event)=>
|
||||||
|
{
|
||||||
|
if (event.key !== Qt.Key_Backspace)
|
||||||
|
{
|
||||||
|
var len = birthday.length
|
||||||
|
var bd = birthday.text
|
||||||
|
if (len === 2 || len === 5) birthday.text = bd + "."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Priorität")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "rank"
|
||||||
|
id: rank
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: ["Nein", "Ja"]
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Rechnung")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "invoice"
|
||||||
|
id: invoice
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
objectName: "combo"
|
||||||
|
model: ["Nein", "Ja"]
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Mahnung")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "due"
|
||||||
|
id: due
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: ["Nein", "Ja"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkContactField()
|
||||||
|
{
|
||||||
|
if (!firstname.text.trim() || !lastname.text.trim())
|
||||||
|
{
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
Gui/AddCustomer.qml
Normal file
120
Gui/AddCustomer.qml
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import "../js/qmldict.js" as JsLib
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
property var new_business: null
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 15
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Kunden anlegen")
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: 35
|
||||||
|
}
|
||||||
|
CheckBox
|
||||||
|
{
|
||||||
|
id: checkAddContact
|
||||||
|
text: qsTr("Ansprechpartner hinzufügen")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
checked: false
|
||||||
|
onCheckStateChanged:
|
||||||
|
{
|
||||||
|
checkFields()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
id: addCustomer
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 45
|
||||||
|
Frame
|
||||||
|
{
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
CustomerView
|
||||||
|
{
|
||||||
|
id: customerView
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AddContact
|
||||||
|
{
|
||||||
|
id: addContactFrame
|
||||||
|
visible: checkAddContact.checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Abbrechen")
|
||||||
|
onClicked: contentStack.pop()
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: saveBtn
|
||||||
|
text: qsTr("Speichern")
|
||||||
|
enabled: false
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
if (!checkAddContact.checked)
|
||||||
|
{
|
||||||
|
new_business = JsLib.parseForm(customerView)
|
||||||
|
business_model.addBusiness(new_business, 0)
|
||||||
|
contentStack.pop()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_business = JsLib.parseForm(customerView)
|
||||||
|
var new_contact = JsLib.parseForm(addContactFrame.contactGrid)
|
||||||
|
contact_model.addContact(new_contact)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: spacer3
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
//Component.onCompleted: contact_model.contactIdReady.connect(onContactId)
|
||||||
|
|
||||||
|
Connections
|
||||||
|
{
|
||||||
|
target: contact_model
|
||||||
|
|
||||||
|
function onContactIdReady()
|
||||||
|
{
|
||||||
|
var con_id = arguments[0]
|
||||||
|
business_model.addBusiness(new_business, con_id)
|
||||||
|
contentStack.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkFields()
|
||||||
|
{
|
||||||
|
if(checkAddContact.checked)
|
||||||
|
{
|
||||||
|
if(!customerView.checkBusinessField() || !addContactFrame.checkContactField())
|
||||||
|
saveBtn.enabled = false
|
||||||
|
else
|
||||||
|
saveBtn.enabled = true
|
||||||
|
}
|
||||||
|
else if (!customerView.checkBusinessField())
|
||||||
|
saveBtn.enabled = false
|
||||||
|
else
|
||||||
|
saveBtn.enabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
230
Gui/AddNewObject.qml
Normal file
230
Gui/AddNewObject.qml
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: newObject
|
||||||
|
|
||||||
|
columns: 4
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
rowSpacing: 9
|
||||||
|
|
||||||
|
|
||||||
|
//// New grid row
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Straße*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "street"
|
||||||
|
id: street
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Nr.*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "houseno"
|
||||||
|
id: houseno
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
// New grid row
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("PLZ")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "postcode"
|
||||||
|
id: postcode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
onCurrentTextChanged: checkFields()
|
||||||
|
onEditTextChanged: checkFields()
|
||||||
|
onActivated: currentValue
|
||||||
|
model: address_model
|
||||||
|
textRole: "display"
|
||||||
|
popup.height: 300
|
||||||
|
currentIndex: -1
|
||||||
|
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
|
||||||
|
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([0-9]{1,5})/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ort")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "city"
|
||||||
|
id: city
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
onEditTextChanged: checkFields()
|
||||||
|
onCurrentTextChanged: checkFields()
|
||||||
|
model: address_model
|
||||||
|
textRole: "city"
|
||||||
|
popup.height: 300
|
||||||
|
currentIndex: -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// New grid row
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Parteien")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinBox
|
||||||
|
{
|
||||||
|
property string name: "units"
|
||||||
|
id: partitions
|
||||||
|
Layout.fillWidth: true
|
||||||
|
from: 1
|
||||||
|
to: 100
|
||||||
|
value: 1
|
||||||
|
editable: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Stockwerke")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinBox
|
||||||
|
{
|
||||||
|
property string name: "floors"
|
||||||
|
id: floors
|
||||||
|
Layout.fillWidth: true
|
||||||
|
from: 1
|
||||||
|
to: 100
|
||||||
|
value: 1
|
||||||
|
editable: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// New grid row
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Zwischenetage")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "mezzanin"
|
||||||
|
id: mezzanin
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: [qsTr("Ja"), qsTr("Nein")]
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Aufzug")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "lift"
|
||||||
|
id: lift
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: [qsTr("Ja"), qsTr("Nein")]
|
||||||
|
}
|
||||||
|
|
||||||
|
//New grid row
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Objekt-Nr.")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "objectno"
|
||||||
|
id: objectno
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
placeholderText: qsTr("0 oder leer um eine Nummer automatisch zu generieren")
|
||||||
|
placeholderTextColor: "pink"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Besonderheiten")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "remarks"
|
||||||
|
id: remarks
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
//// New grid row
|
||||||
|
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Reinigungsmittel wo?*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "cleaningproducts"
|
||||||
|
id: cleaningproducts
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkObjectField()
|
||||||
|
{
|
||||||
|
|
||||||
|
return street.text.trim() && houseno.text.trim() &&
|
||||||
|
|
||||||
|
(postcode.editText.trim() || postcode.currentText.trim()) &&
|
||||||
|
(city.editText.trim() || city.currentText.trim()) &&
|
||||||
|
cleaningproducts.text.trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
213
Gui/AddNewOffer.qml
Normal file
213
Gui/AddNewOffer.qml
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: newObject
|
||||||
|
|
||||||
|
columns: 4
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
rowSpacing: 9
|
||||||
|
|
||||||
|
//New Grid
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Objekt:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
font: Typography.h2
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
//New grid row
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Objekt-Nr.")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "objectno"
|
||||||
|
id: objectno
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Objekt hinzufügen")
|
||||||
|
icon.source: "qrc:/images/PlusCircle.svg"
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// New grid row
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Straße")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "street"
|
||||||
|
id: street
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
// onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Nr.*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "houseno"
|
||||||
|
id: houseno
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
// onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
// New grid row
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("PLZ")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "postcode"
|
||||||
|
id: postcode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
// onCurrentTextChanged: checkFields()
|
||||||
|
// onEditTextChanged: checkFields()
|
||||||
|
onActivated: currentValue
|
||||||
|
model: address_model
|
||||||
|
textRole: "display"
|
||||||
|
popup.height: 300
|
||||||
|
currentIndex: -1
|
||||||
|
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
|
||||||
|
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([0-9]{1,5})/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ort")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "city"
|
||||||
|
id: city
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
// onEditTextChanged: checkFields()
|
||||||
|
// onCurrentTextChanged: checkFields()
|
||||||
|
model: address_model
|
||||||
|
textRole: "city"
|
||||||
|
popup.height: 300
|
||||||
|
currentIndex: -1
|
||||||
|
}
|
||||||
|
|
||||||
|
//New Grid
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Kunde:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
font: Typography.h2
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
//New grid row
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Kunden-Nr.")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "customerno"
|
||||||
|
id: customerno
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Kunde hinzufügen")
|
||||||
|
icon.source: "qrc:/images/PlusCircle.svg"
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// New grid row
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Kunden-Name")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
|
||||||
|
id: customerName
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// function checkObjectField()
|
||||||
|
// {
|
||||||
|
|
||||||
|
// return street.text.trim() && houseno.text.trim() &&
|
||||||
|
|
||||||
|
// (postcode.editText.trim() || postcode.currentText.trim()) &&
|
||||||
|
// (city.editText.trim() || city.currentText.trim()) &&
|
||||||
|
// cleaningproducts.text.trim()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
150
Gui/AddObject.qml
Normal file
150
Gui/AddObject.qml
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import "../js/qmldict.js" as JsLib
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
property var new_object: null
|
||||||
|
//property alias checkAddContact: checkAddContact
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 15
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Objekt anlegen")
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: 35
|
||||||
|
}
|
||||||
|
CheckBox
|
||||||
|
{
|
||||||
|
id: checkAddObjectContact
|
||||||
|
text: qsTr("Ansprechpartner hinzufügen")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
checked: false
|
||||||
|
onCheckStateChanged:
|
||||||
|
{
|
||||||
|
checkFields()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
id: addObject
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 45
|
||||||
|
|
||||||
|
Frame
|
||||||
|
{
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
AddNewObject
|
||||||
|
{
|
||||||
|
id: newObject
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectAddOns
|
||||||
|
{
|
||||||
|
id: addObjectLayout
|
||||||
|
visible: checkAddObjectContact.checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Abbrechen")
|
||||||
|
onClicked: contentStack.pop()
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
property var new_object: null
|
||||||
|
id: saveBtn
|
||||||
|
text: qsTr("Speichern")
|
||||||
|
enabled: false
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
new_object = JsLib.parseForm(newObject)
|
||||||
|
new_object['lift'] = new_object['lift'] === 'Ja' ? 1 : 0
|
||||||
|
new_object['mezzanin'] = new_object['mezzanin'] === 'Ja' ? 1 : 0
|
||||||
|
object_model.addObject(new_object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: spacer3
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
//object_model.objectAdded.connect(onObjectAdded)
|
||||||
|
//contact_model.objectContactAdded.connect(onObjectContact)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Connections
|
||||||
|
{
|
||||||
|
target: object_model
|
||||||
|
|
||||||
|
function onObjectIdReady()
|
||||||
|
{
|
||||||
|
var obj_id = arguments[0]
|
||||||
|
if (checkAddObjectContact.checked && obj_id)
|
||||||
|
{
|
||||||
|
var new_objecto = addObjectLayout.getForm()
|
||||||
|
contact_model.addObjectContact(new_objecto, obj_id)
|
||||||
|
object_model.viewCriterion("Alle")
|
||||||
|
}
|
||||||
|
|
||||||
|
contentStack.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// function onObjectAdded(added, oid)
|
||||||
|
// {
|
||||||
|
// if (!added)
|
||||||
|
// console.log(qsTr("Fehler beim Objekt-Anlegen!"))
|
||||||
|
// if (checkAddObjectContact.checked && oid)
|
||||||
|
// {
|
||||||
|
// var new_objecto = addObjectLayout.getForm()
|
||||||
|
|
||||||
|
// contact_model.addObjectContact(new_objecto, oid)
|
||||||
|
// }
|
||||||
|
// else appLoader.source = "ObjectTable.qml"
|
||||||
|
// }
|
||||||
|
|
||||||
|
// function onObjectContact(added)
|
||||||
|
// {
|
||||||
|
// if (!added)
|
||||||
|
// console.log(qsTr("Fehler beim Objekt-Kontakt-Anlegen!"))
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// //object_model.viewCriterion("Alle")
|
||||||
|
// appLoader.source = "ObjectTable.qml"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
function checkFields()
|
||||||
|
{
|
||||||
|
if(checkAddObjectContact.checked)
|
||||||
|
{
|
||||||
|
if(!newObject.checkObjectField() || !addObjectLayout.contactPerson.contacts || !addObjectLayout.contactPerson.contacts.length)
|
||||||
|
saveBtn.enabled = false
|
||||||
|
else
|
||||||
|
saveBtn.enabled = true
|
||||||
|
}
|
||||||
|
else if (!newObject.checkObjectField())
|
||||||
|
saveBtn.enabled = false
|
||||||
|
else
|
||||||
|
saveBtn.enabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
130
Gui/AddObjectEmployee.qml
Normal file
130
Gui/AddObjectEmployee.qml
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
ApplicationWindow
|
||||||
|
{
|
||||||
|
id: addMitarbeiter
|
||||||
|
title: qsTr("Objekt - Neuer Mitarbeiter")
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 10
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Mitarbeiter zuweisen")
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
font.pixelSize: 35
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 4
|
||||||
|
columnSpacing: 6
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Eingesetzter Mitarbeiter")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
id: assignee
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Lohn Mitarbeiter pro Stunde")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: wage
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Einsatzdauer")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: duration
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Reinigungstage")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: cleanDays
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Tätigkeiten")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: tasks
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ertrag")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: output
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 5
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Abbrechen")
|
||||||
|
onClicked: addMitarbeiter.close()
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Hinzufügen")
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
if (duration.text.trim() !== "" && wage.text.trim() !== "" && cleanDays.text.trim() !== "" && tasks.text.trim() !== "" && output.text.trim() !== "")
|
||||||
|
{
|
||||||
|
var ne = {
|
||||||
|
"assignee": assignee.currentText,
|
||||||
|
"duration": duration.text.trim(),
|
||||||
|
"wage": wage.text.trim(),
|
||||||
|
"cleandays": cleanDays.text.trim(),
|
||||||
|
"tasks": tasks.text.trim(),
|
||||||
|
"output": output.text.trim(),
|
||||||
|
};
|
||||||
|
addMitarbeiter.addNewEmployee(ne)
|
||||||
|
addMitarbeiter.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signal addNewEmployee(var new_employee)
|
||||||
|
}
|
||||||
112
Gui/AddOffer.qml
Normal file
112
Gui/AddOffer.qml
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import "../js/qmldict.js" as JsLib
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
property var new_object: null
|
||||||
|
//property alias checkAddContact: checkAddContact
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 15
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Angebot anlegen")
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: 35
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
id: addObject
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 45
|
||||||
|
|
||||||
|
Frame
|
||||||
|
{
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
AddNewOffer
|
||||||
|
{
|
||||||
|
id: newOffer
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Abbrechen")
|
||||||
|
onClicked: contentStack.pop()
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
property var new_object: null
|
||||||
|
id: saveBtn
|
||||||
|
text: qsTr("Speichern")
|
||||||
|
enabled: false
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
// new_object = JsLib.parseForm(newObject)
|
||||||
|
// new_object['lift'] = new_object['lift'] === 'Ja' ? 1 : 0
|
||||||
|
// new_object['mezzanin'] = new_object['mezzanin'] === 'Ja' ? 1 : 0
|
||||||
|
// object_model.addObject(new_object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: spacer3
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
//object_model.objectAdded.connect(onObjectAdded)
|
||||||
|
//contact_model.objectContactAdded.connect(onObjectContact)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Connections
|
||||||
|
// {
|
||||||
|
// target: object_model
|
||||||
|
|
||||||
|
// function onObjectIdReady()
|
||||||
|
// {
|
||||||
|
// var obj_id = arguments[0]
|
||||||
|
// if (checkAddObjectContact.checked && obj_id)
|
||||||
|
// {
|
||||||
|
// var new_objecto = addObjectLayout.getForm()
|
||||||
|
// contact_model.addObjectContact(new_objecto, obj_id)
|
||||||
|
// object_model.viewCriterion("Alle")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// appLoader.source = "ObjectTable.qml"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// function checkFields()
|
||||||
|
// {
|
||||||
|
// if(checkAddObjectContact.checked)
|
||||||
|
// {
|
||||||
|
// if(!newObject.checkObjectField() || !addObjectLayout.contactPerson.contacts || !addObjectLayout.contactPerson.contacts.length)
|
||||||
|
// saveBtn.enabled = false
|
||||||
|
// else
|
||||||
|
// saveBtn.enabled = true
|
||||||
|
// }
|
||||||
|
// else if (!newObject.checkObjectField())
|
||||||
|
// saveBtn.enabled = false
|
||||||
|
// else
|
||||||
|
// saveBtn.enabled = true
|
||||||
|
// }
|
||||||
|
}
|
||||||
91
Gui/AdminUserConfig.qml
Normal file
91
Gui/AdminUserConfig.qml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: createUserGrid
|
||||||
|
columns: 2
|
||||||
|
columnSpacing: 5
|
||||||
|
rowSpacing: 9
|
||||||
|
// anchors.fill: parent
|
||||||
|
|
||||||
|
property string name: "user"
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Admin User erstellen")
|
||||||
|
font.pixelSize: 40
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
padding: 15
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: benutzerNamelabel
|
||||||
|
text: qsTr("Benutzername:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: benutzerName
|
||||||
|
placeholderText: qsTr("Hier Benutzername eingeben")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 3
|
||||||
|
property string name: "PYQCRM_USER"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Passwort:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: password
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
placeholderText: qsTr("Hier Passwort eingeben")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
property string name: "PYQCRM_USER_PASS"
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Info:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: gecos
|
||||||
|
placeholderText: qsTr("Zusätzliche Info")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
property string name: "PYQCRM_USER_INFO"
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
config.adminNotAvailable.connect(adminNotAvailable)
|
||||||
|
|
||||||
|
}
|
||||||
|
function adminNotAvailable()
|
||||||
|
{
|
||||||
|
benutzerName.placeholderText = qsTr ("Benutzername ist bereits vergeben")
|
||||||
|
benutzerName.clear()
|
||||||
|
benutzerNamelabel.color = "red"
|
||||||
|
benutzerNamelabel.font.bold = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
57
Gui/BackupSettings.qml
Normal file
57
Gui/BackupSettings.qml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import QtCore
|
||||||
|
import "../js/qmldict.js" as JsLib
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: 150
|
||||||
|
columns: 2
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: qsTr("Sicherung")
|
||||||
|
font.pixelSize: 35
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Konfiguration")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: saveConfig
|
||||||
|
text: qsTr("Jetzt sichern!")
|
||||||
|
onClicked: utilityDialogs.item.backup_config.open()
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Verschlüsselung")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: saveEncryption
|
||||||
|
text: qsTr("Jetzt sichern!")
|
||||||
|
onClicked: utilityDialogs.item.backup_encrypt_pw.open()
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: spacer
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader
|
||||||
|
{
|
||||||
|
id: utilityDialogs
|
||||||
|
source: "UtilityDialogs.qml"
|
||||||
|
}
|
||||||
|
}
|
||||||
122
Gui/CompanyConf.qml
Normal file
122
Gui/CompanyConf.qml
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
property alias name: companyName
|
||||||
|
property alias street: street
|
||||||
|
property alias house: houseno
|
||||||
|
property alias zipcode: zipcode
|
||||||
|
property alias city: city
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: 50
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Namen")
|
||||||
|
// font.pixelSize: 57
|
||||||
|
// font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: companyName
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Straße")
|
||||||
|
// font.pixelSize: 57
|
||||||
|
// font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: street
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Haus-Nr.")
|
||||||
|
// font.pixelSize: 57
|
||||||
|
// font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: houseno
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("PLZ")
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
id: zipcode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
model: address_model
|
||||||
|
textRole: "display"
|
||||||
|
popup.height: 300
|
||||||
|
onCurrentIndexChanged: city.currentIndex = zipcode.currentIndex
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([0-9]{1,5})/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Stadt")
|
||||||
|
// font.pixelSize: 57
|
||||||
|
// font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
id: city
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
model: address_model
|
||||||
|
textRole: "city"
|
||||||
|
popup.height: 300
|
||||||
|
currentIndex: -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
var c = config.getCompanyInfo()
|
||||||
|
if (Object.keys(c).length)
|
||||||
|
{
|
||||||
|
companyName.text = c['NAME']
|
||||||
|
street.text = c['STREET']
|
||||||
|
houseno.text = c['HOUSE']
|
||||||
|
zipcode.editText = c['ZIPCODE']
|
||||||
|
city.editText = c['CITY']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
174
Gui/CustomerContactDetails.qml
Normal file
174
Gui/CustomerContactDetails.qml
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 25
|
||||||
|
Layout.leftMargin: 7
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: contactLabel
|
||||||
|
color: "darksalmon"
|
||||||
|
font.bold: true
|
||||||
|
text: qsTr("Ansprechpartner")
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: contact? contact['contact']['salute'] + " " + contact['contact']['fname'] + " " + contact['contact']['lname']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Geburtsdatum")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: contact? contact['contact']['birthday']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("E-Mail")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: contact? contact['contact']['email']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Position")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: contact? contact['contact']['position']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Priorität")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: contact? contact['contact']['priority']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Telefon")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: contact? contact['contact']['phone']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Handy")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: contact? contact['contact']['cell']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Abrechnung")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: contact? contact['contact']['invoice']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Mahnung")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: contact? contact['contact']['reminder']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
if (contact && contact['contact']['salute'] === "Frau")
|
||||||
|
contactLabel.text = qsTr("Ansprechpartnerin")
|
||||||
|
}
|
||||||
|
}
|
||||||
61
Gui/CustomerDetails.qml
Normal file
61
Gui/CustomerDetails.qml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
property int selectedClient: -1
|
||||||
|
property var client: null
|
||||||
|
property var contact: null
|
||||||
|
id: clDet
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Zurück")
|
||||||
|
onClicked: contentStack.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
SplitView
|
||||||
|
{
|
||||||
|
id: clDetView
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
leftPadding: 9
|
||||||
|
rightPadding: 9
|
||||||
|
|
||||||
|
CustomerDetailsView
|
||||||
|
{
|
||||||
|
id: customerDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomerContactDetails
|
||||||
|
{
|
||||||
|
id: contactDetails
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
NoCustomerContact
|
||||||
|
{
|
||||||
|
id: noCustomerContact
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
//Layout.columnSpan: 2
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
//business_model.onRowClicked(selectedClient)
|
||||||
|
client = business_model.getClientDetails()
|
||||||
|
if (client['business']['contactid'] > 0)
|
||||||
|
{
|
||||||
|
contact = contact_model.getContactDetails(client['business']['contactid'])
|
||||||
|
contactDetails.visible = true
|
||||||
|
}
|
||||||
|
else noCustomerContact.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
225
Gui/CustomerDetailsView.qml
Normal file
225
Gui/CustomerDetailsView.qml
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 25
|
||||||
|
SplitView.preferredWidth: clDetView.width / 3 * 1.8
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Steuer-ID")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['tax']? client['business']['tax']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Anmerkungen")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['info']? client['business']['info']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Kundenname")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['company']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("CEO")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['ceo']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Telefon")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['phone']? client['business']['phone']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Handy")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['cell']? client['business']['cell']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Webseite")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: clientWebsite
|
||||||
|
color: "goldenrod"
|
||||||
|
font.underline: false
|
||||||
|
text: client['business']['website']? '<a href="' + client['business']['website'] + '">' + client['business']['website'] + '</a>': ""
|
||||||
|
onLinkActivated:
|
||||||
|
{
|
||||||
|
var web_protocol = /^((http|https):\/\/)/;
|
||||||
|
var client_website = !web_protocol.test(client['business']['website'])? "https://" + client['business']['website']: client['business']['website'];
|
||||||
|
Qt.openUrlExternally(client_website)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("E-Mail")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: clientEmail
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['email']? '<a href="mailto:' + client['business']['email'] + '">' + client['business']['email'] + '</a>': ""
|
||||||
|
onLinkActivated: Qt.openUrlExternally('mailto:' + client['business']['email'])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Straße")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['street']? client['business']['tax']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Haus-Nr.")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['house']? client['business']['house']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("PLZ")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['zip']? client['business']['zip']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
text: qsTr("Stadt")
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: client['business']['city']? client['business']['city']: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
// Item
|
||||||
|
// {
|
||||||
|
// Layout.columnSpan: 2
|
||||||
|
// Layout.fillHeight: true
|
||||||
|
// }
|
||||||
|
}
|
||||||
271
Gui/CustomerView.qml
Normal file
271
Gui/CustomerView.qml
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: customerView
|
||||||
|
columns: 4
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
rowSpacing: 9
|
||||||
|
property alias businesstxt: firmenName
|
||||||
|
property alias street: streetid
|
||||||
|
property alias postcodetxt: postcode
|
||||||
|
property alias citytxt: city
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: lblFirmenName
|
||||||
|
text: qsTr("Firmenname*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "business"
|
||||||
|
|
||||||
|
id: firmenName
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Straße*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "street"
|
||||||
|
id: streetid
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Nr.*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "houseno"
|
||||||
|
id: housenoid
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([0-9a-zA-Z\-]{1,6})/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("PLZ")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "postcode"
|
||||||
|
id: postcode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
onCurrentTextChanged: checkFields()
|
||||||
|
onEditTextChanged: checkFields()
|
||||||
|
onActivated: currentValue
|
||||||
|
model: address_model
|
||||||
|
textRole: "display"
|
||||||
|
popup.height: 300
|
||||||
|
currentIndex: -1
|
||||||
|
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([0-9]{1,5})/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ort")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "city"
|
||||||
|
id: city
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
onEditTextChanged: checkFields()
|
||||||
|
onCurrentTextChanged: checkFields()
|
||||||
|
model: address_model
|
||||||
|
textRole: "city"
|
||||||
|
popup.height: 300
|
||||||
|
currentIndex: -1
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Telefon")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "telephone"
|
||||||
|
id: telephone
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([+0-9]{1})([0-9]{1,17})/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Mobil")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "cellphone"
|
||||||
|
id: cellphone
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([+0-9]{1})([0-9]{1,17})/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("E-Mail")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "email"
|
||||||
|
id: email
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderText: qsTr("beispiel@domain.de")
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /([\+!#$%&‘\*\–\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Homepage")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "homepage"
|
||||||
|
id: homepage
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
placeholderText: "www.oschkarischtverhaftetwegensexy.jinx"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Geschäftsführer")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "ceo"
|
||||||
|
id: ceo
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("USt-IdNr")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "taxno"
|
||||||
|
id: taxno
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Typ")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "typeid"
|
||||||
|
id: typeid
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: business_type
|
||||||
|
textRole: "display"
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Info")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignTop
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView
|
||||||
|
{
|
||||||
|
id: infoView
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 100
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
ScrollBar.horizontal: ScrollBar
|
||||||
|
{
|
||||||
|
policy: ScrollBar.AlwaysOn
|
||||||
|
}
|
||||||
|
|
||||||
|
TextArea
|
||||||
|
{
|
||||||
|
property string name: "customerinfo"
|
||||||
|
id: customerInfo
|
||||||
|
implicitWidth: parent.width
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
color: customerInfo.palette.base
|
||||||
|
border.color: customerInfo.activeFocus? customerInfo.palette.highlight: customerInfo.palette.base
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function checkBusinessField()
|
||||||
|
{
|
||||||
|
if (!firmenName.text.trim() || !streetid.text.trim())
|
||||||
|
{
|
||||||
|
return false
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!postcode.editText.trim() || !postcode.currentText || !city.editText.trim() || !city.currentText)
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
177
Gui/CustomersTable.qml
Normal file
177
Gui/CustomersTable.qml
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Qt.labs.qmlmodels
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
property var availableFilters: ["Name", "Adresse", "PLZ", "Ort"]
|
||||||
|
|
||||||
|
function viewCriterion(criterion)
|
||||||
|
{
|
||||||
|
business_model.viewCriterion(criterion.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
Component.onCompleted: contentStack.pop()
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
|
||||||
|
SearchBar
|
||||||
|
{
|
||||||
|
}
|
||||||
|
QuickFilter {
|
||||||
|
onSelectedChanged: (name) => {
|
||||||
|
business_model.viewCriterion(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
model: ListModel {
|
||||||
|
ListElement {
|
||||||
|
|
||||||
|
name: "Alle"
|
||||||
|
text: qsTr("Alle")
|
||||||
|
selected: true
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Interessent"
|
||||||
|
text: qsTr("Interessent")
|
||||||
|
selected: false
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Kunde"
|
||||||
|
text: qsTr("Kunde")
|
||||||
|
selected: false
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Lieferant"
|
||||||
|
text: qsTr("Lieferant")
|
||||||
|
selected: false
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Erledigt"
|
||||||
|
text: qsTr("Erledigt")
|
||||||
|
selected: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: addCustomer
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
icon.source: "qrc:/images/PlusCircle.svg"
|
||||||
|
text: qsTr("Kunde Hinzufügen")
|
||||||
|
onClicked: contentStack.push("AddCustomer.qml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.verticalStretchFactor: 1
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
HorizontalHeaderView
|
||||||
|
{
|
||||||
|
id: horizontalHeader
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: 40
|
||||||
|
movableColumns: true //@disable-check M16
|
||||||
|
syncView: customerTable
|
||||||
|
|
||||||
|
delegate: Rectangle
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
border.color: addCustomer.palette.base
|
||||||
|
color: addCustomer.palette.alternateBase
|
||||||
|
implicitHeight: 40
|
||||||
|
implicitWidth: 1
|
||||||
|
|
||||||
|
Text
|
||||||
|
{
|
||||||
|
color: addCustomer.palette.text
|
||||||
|
elide: Text.ElideRight
|
||||||
|
height: parent.height
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: model.display
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TableView {
|
||||||
|
id: customerTable
|
||||||
|
|
||||||
|
property real newWidth: 0
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
alternatingRows: true
|
||||||
|
columnSpacing: 1
|
||||||
|
model: business_model
|
||||||
|
resizableColumns: true
|
||||||
|
rowSpacing: 2
|
||||||
|
selectionBehavior: TableView.SelectRows
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
ScrollBar.vertical: ScrollBar {
|
||||||
|
policy: customerTable.contentHeight > customerTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
||||||
|
}
|
||||||
|
delegate: Rectangle {
|
||||||
|
required property bool current
|
||||||
|
required property bool selected
|
||||||
|
|
||||||
|
color: selected ? addCustomer.palette.highlight //palette.highlight
|
||||||
|
: (customerTable.alternatingRows && row % 2 !== 0 ? addCustomer.palette.base // palette.base
|
||||||
|
: addCustomer.palette.alternateBase) //palette.alternateBase)
|
||||||
|
implicitHeight: 25
|
||||||
|
implicitWidth: customerTable.width / customerTable.columns
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: addCustomer.palette.text
|
||||||
|
elide: Text.ElideRight
|
||||||
|
height: parent.height
|
||||||
|
leftPadding: 9
|
||||||
|
text: model.display == null ? "" : model.display // @disable-check M126
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
|
||||||
|
property bool hovered: false
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onDoubleClicked: {
|
||||||
|
business_model.onRowClicked(row);
|
||||||
|
contentStack.push("CustomerDetails.qml", {
|
||||||
|
selectedClient: row
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onEntered: {
|
||||||
|
customerTable.selectionModel.select(customerTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectionModel: ItemSelectionModel {
|
||||||
|
id: selModel
|
||||||
|
|
||||||
|
model: customerTable.model
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
110
Gui/Dashboard.qml
Normal file
110
Gui/Dashboard.qml
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.top: Navigation.bottom
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.bottomMargin: 3
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: "dimgrey"
|
||||||
|
radius: 45
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: contractButton
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
border.color: "steelblue"
|
||||||
|
border.width: 1
|
||||||
|
color: "darkslategray"
|
||||||
|
height: 145
|
||||||
|
radius: 45
|
||||||
|
width: 300
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: "lightgoldenrodyellow"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 45
|
||||||
|
text: qsTr("Aufträge")
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onExited: {
|
||||||
|
contractButton.color = "darkslategray";
|
||||||
|
contractButton.border.color = "steelblue";
|
||||||
|
contractButton.border.width = 1;
|
||||||
|
}
|
||||||
|
onHoveredChanged: {
|
||||||
|
var w = contractButton.border.width === 3 ? 1 : 3;
|
||||||
|
contractButton.border.width = w;
|
||||||
|
}
|
||||||
|
onPressed: {
|
||||||
|
contractButton.color = "darkolivegreen";
|
||||||
|
contractButton.border.width = 3;
|
||||||
|
contractButton.border.color = "skyblue";
|
||||||
|
console.log("Aufträge...");
|
||||||
|
}
|
||||||
|
onReleased: {
|
||||||
|
contractButton.color = "darkslategray";
|
||||||
|
contractButton.border.width = 1;
|
||||||
|
contractButton.border.color = "steelblue";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: offerButton
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
border.color: "steelblue"
|
||||||
|
border.width: 1
|
||||||
|
color: "darkslategray"
|
||||||
|
height: 145
|
||||||
|
radius: 45
|
||||||
|
width: 300
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: "lightgoldenrodyellow"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 45
|
||||||
|
text: qsTr("Angebote")
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onExited: {
|
||||||
|
offerButton.color = "darkslategray";
|
||||||
|
offerButton.border.color = "steelblue";
|
||||||
|
offerButton.border.width = 1;
|
||||||
|
}
|
||||||
|
onHoveredChanged: {
|
||||||
|
var w = offerButton.border.width === 3 ? 1 : 3;
|
||||||
|
offerButton.border.width = w;
|
||||||
|
}
|
||||||
|
onPressed: {
|
||||||
|
offerButton.color = "darkolivegreen";
|
||||||
|
offerButton.border.width = 3;
|
||||||
|
offerButton.border.color = "skyblue";
|
||||||
|
console.log("Angebote...");
|
||||||
|
}
|
||||||
|
onReleased: {
|
||||||
|
offerButton.color = "darkslategray";
|
||||||
|
offerButton.border.width = 1;
|
||||||
|
offerButton.border.color = "steelblue";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
122
Gui/DbConfiguration.qml
Normal file
122
Gui/DbConfiguration.qml
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
property alias dbHost: dbHost
|
||||||
|
property alias dbPort: dbPort
|
||||||
|
property alias dbName: dbName
|
||||||
|
property alias dbUserName: dbUserName
|
||||||
|
property alias dbPassword: dbPassword
|
||||||
|
id: dbGrid
|
||||||
|
columns: 2
|
||||||
|
columnSpacing: 5
|
||||||
|
rowSpacing: 9
|
||||||
|
|
||||||
|
property string name: "database"
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Datenbank Einstellungen")
|
||||||
|
font.pixelSize: 40
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
padding: 15
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("DB-Host:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: dbHost
|
||||||
|
placeholderText: qsTr("Hier Host eingeben")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
property string name: "DB_HOST"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("DB-Port:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: dbPort
|
||||||
|
placeholderText: qsTr("Hier DB-Port eingeben")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
validator: IntValidator{bottom: 1025; top: 65535;}
|
||||||
|
property string name: "DB_PORT"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("DB-Name:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: dbName
|
||||||
|
placeholderText: qsTr("Hier DB-Name eingeben")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
property string name: "DB_NAME"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("DB-Benutzername:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: dbUserName
|
||||||
|
placeholderText: qsTr("Hier DB-Benutzername eingeben")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
property string name: "DB_USER"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("DB-Passwort:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: dbPassword
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
placeholderText: qsTr("Hier DB-Passwort eingeben")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
property string name: "DB_PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
var db = config.getDbConf()
|
||||||
|
if (Object.keys(db).length)
|
||||||
|
{
|
||||||
|
dbHost.text = db['DB_HOST']
|
||||||
|
dbPort.text = db['DB_PORT']
|
||||||
|
dbName.text = db['DB_NAME']
|
||||||
|
dbUserName.text = db['DB_USER']
|
||||||
|
dbPassword.text = db['DB_PASS']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
Gui/Employees/AddApplicant.qml
Normal file
37
Gui/Employees/AddApplicant.qml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import TeroStyle
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
ApplicantForm {
|
||||||
|
id: applicantForm
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.verticalStretchFactor: 1
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
Button {
|
||||||
|
icon.source: "qrc:/images/ArrowLeftCircle-Outline.svg"
|
||||||
|
text: qsTr("Verwerfen")
|
||||||
|
|
||||||
|
onClicked: contentStack.pop()
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
enabled: applicantForm.valid
|
||||||
|
icon.source: "qrc:/images/CheckCircle.svg"
|
||||||
|
text: qsTr("Speichern")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
applicantModel.createApplicant(applicantForm.value);
|
||||||
|
contentStack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
102
Gui/Employees/AddEmployee.qml
Normal file
102
Gui/Employees/AddEmployee.qml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import "../../js/qmldict.js" as JsLib
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: colPar
|
||||||
|
|
||||||
|
function checkFields() {
|
||||||
|
if (!personalData.checkPersonalField())
|
||||||
|
saveBtn.enabled = false;
|
||||||
|
else
|
||||||
|
saveBtn.enabled = true;
|
||||||
|
}
|
||||||
|
function onAddNewEmployee(added) {
|
||||||
|
if (added) {
|
||||||
|
console.log('addedsuccesfully');
|
||||||
|
contentStack.pop();
|
||||||
|
} else {
|
||||||
|
console.log('failedtoadd');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.fill: parent
|
||||||
|
implicitWidth: parent.width
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
employee_model.addedNewEmployee.connect(onAddNewEmployee);
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: headline
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||||
|
font.pixelSize: 35
|
||||||
|
text: qsTr("Mitarbeiter / Bewerber hinzufügen")
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
Frame {
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.horizontalStretchFactor: 1
|
||||||
|
|
||||||
|
EmployeePersonalData {
|
||||||
|
id: personalData
|
||||||
|
|
||||||
|
implicitWidth: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Frame {
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.horizontalStretchFactor: 1
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
implicitWidth: parent.width
|
||||||
|
|
||||||
|
EmployeeBankData {
|
||||||
|
id: bankAccount
|
||||||
|
|
||||||
|
}
|
||||||
|
EmployeeNationalInsurance {
|
||||||
|
id: nationalInsurance
|
||||||
|
}
|
||||||
|
EmployeeVarious {
|
||||||
|
id: applicantVarious
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: qsTr("Abbrechen")
|
||||||
|
|
||||||
|
onClicked: contentStack.pop()
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: saveBtn
|
||||||
|
|
||||||
|
enabled: false
|
||||||
|
text: qsTr("Speichern")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
const new_applicant = JsLib.parseForm(personalData, bankAccount, nationalInsurance, applicantVarious);
|
||||||
|
employee_model.addEmployee(new_applicant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
218
Gui/Employees/ApplicantForm.qml
Normal file
218
Gui/Employees/ApplicantForm.qml
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls.impl
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import TeroStyle
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
readonly property int fieldM: 235
|
||||||
|
readonly property int fieldS: 110
|
||||||
|
readonly property bool valid: emailAddress.acceptableInput && firstName.acceptableInput && houseNumber.acceptableInput && lastName.acceptableInput && mobileNumber.acceptableInput && phoneNumber.acceptableInput && salutation.acceptableInput&& street.acceptableInput && title.acceptableInput && zipCode.acceptableInput
|
||||||
|
readonly property var value: QtObject {
|
||||||
|
readonly property string emailAddress: emailAddress.text ?? ""
|
||||||
|
readonly property string firstName: firstName.text ?? ""
|
||||||
|
readonly property string houseNumber: houseNumber.text ?? ""
|
||||||
|
readonly property string lastName: lastName.text ?? ""
|
||||||
|
readonly property string mobileNumber: mobileNumber.text ?? ""
|
||||||
|
readonly property string phoneNumber: phoneNumber.text ?? ""
|
||||||
|
readonly property string salutation: salutation.text ?? ""
|
||||||
|
readonly property string street: street.text ?? ""
|
||||||
|
readonly property string title: title.currentText
|
||||||
|
readonly property int zipCode: zipCode.currentIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
function setValue(value) {
|
||||||
|
title.currentIndex = value.title ?? 0;
|
||||||
|
firstName.text = value.firstName ?? "";
|
||||||
|
lastName.text = value.lastName ?? "";
|
||||||
|
street.text = value.street ?? "";
|
||||||
|
houseNumber.text = value.houseNumber ?? "";
|
||||||
|
zipCode.currentIndex = value.zipCode ?? -1;
|
||||||
|
phoneNumber.text = value.phoneNumber ?? "";
|
||||||
|
mobileNumber.text = value.mobileNumber ?? "";
|
||||||
|
emailAddress.text = value.emailAddress ?? "";
|
||||||
|
salutation.text = value.salutation ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
IconLabel {
|
||||||
|
color: Colors.foreground
|
||||||
|
font: Typography.h2
|
||||||
|
icon.color: Colors.foreground
|
||||||
|
icon.height: Typography.h2.pixelSize
|
||||||
|
icon.source: "qrc:/images/UserCircle"
|
||||||
|
icon.width: Typography.h2.pixelSize
|
||||||
|
spacing: Dimensions.m
|
||||||
|
text: qsTr("Stammdaten")
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
spacing: Dimensions.m
|
||||||
|
|
||||||
|
Field {
|
||||||
|
label: qsTr("Anrede")
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: title
|
||||||
|
|
||||||
|
implicitWidth: fieldM
|
||||||
|
model: [qsTr("Keine Angabe"), qsTr("Herr"), qsTr("Frau")]
|
||||||
|
|
||||||
|
onCurrentTextChanged: {
|
||||||
|
switch (title.currentIndex) {
|
||||||
|
case 1:
|
||||||
|
salutation.text = "Sehr geehrter Herr ";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
salutation.text = "Sehr geehrte Frau ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
salutation.text = "Guten Tag ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("Vorname")
|
||||||
|
mandatory: true
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: firstName
|
||||||
|
|
||||||
|
implicitWidth: fieldM
|
||||||
|
placeholderText: qsTr("Max")
|
||||||
|
|
||||||
|
validator: NotEmptyValidator {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("Nachname")
|
||||||
|
mandatory: true
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: lastName
|
||||||
|
|
||||||
|
implicitWidth: fieldM
|
||||||
|
placeholderText: qsTr("Mustermann")
|
||||||
|
|
||||||
|
validator: NotEmptyValidator {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
spacing: Dimensions.m
|
||||||
|
|
||||||
|
Field {
|
||||||
|
label: qsTr("Straße")
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: street
|
||||||
|
|
||||||
|
implicitWidth: fieldM
|
||||||
|
placeholderText: qsTr("Musterstraße")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("Hausnummer")
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: houseNumber
|
||||||
|
|
||||||
|
implicitWidth: fieldS
|
||||||
|
placeholderText: qsTr("1a")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("PLZ")
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: zipCode
|
||||||
|
|
||||||
|
currentIndex: -1
|
||||||
|
editable: true
|
||||||
|
implicitWidth: fieldS
|
||||||
|
model: address_model
|
||||||
|
textRole: "display"
|
||||||
|
|
||||||
|
onActivated: currentValue
|
||||||
|
onCurrentIndexChanged: city.currentIndex = zipCode.currentIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("Ort")
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: city
|
||||||
|
|
||||||
|
currentIndex: -1
|
||||||
|
editable: true
|
||||||
|
implicitWidth: fieldM
|
||||||
|
model: address_model
|
||||||
|
textRole: "city"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconLabel {
|
||||||
|
color: Colors.foreground
|
||||||
|
font: Typography.h2
|
||||||
|
icon.color: Colors.foreground
|
||||||
|
icon.height: Typography.h2.pixelSize
|
||||||
|
icon.source: "qrc:/images/Phone"
|
||||||
|
icon.width: Typography.h2.pixelSize
|
||||||
|
spacing: Dimensions.m
|
||||||
|
text: qsTr("Kontakt")
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
spacing: Dimensions.m
|
||||||
|
|
||||||
|
Field {
|
||||||
|
label: qsTr("Telefonnummer")
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: phoneNumber
|
||||||
|
|
||||||
|
implicitWidth: fieldM
|
||||||
|
placeholderText: "+49 1234 567890"
|
||||||
|
|
||||||
|
validator: OptionalPhoneNumberValidator {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("Mobil")
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: mobileNumber
|
||||||
|
|
||||||
|
implicitWidth: fieldM
|
||||||
|
placeholderText: "+49 123 4567891011"
|
||||||
|
|
||||||
|
validator: OptionalPhoneNumberValidator {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("E-Mail Adresse")
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: emailAddress
|
||||||
|
|
||||||
|
implicitWidth: fieldM
|
||||||
|
placeholderText: "tero@example.org"
|
||||||
|
|
||||||
|
validator: OptionalEmailAddressValidator {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("Briefanrede")
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: salutation
|
||||||
|
|
||||||
|
implicitWidth: fieldM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
Gui/Employees/EmployeeBankData.qml
Normal file
51
Gui/Employees/EmployeeBankData.qml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: bankAccount
|
||||||
|
columns: 2
|
||||||
|
property alias jobstatus: title
|
||||||
|
property alias longest: longest
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: longest
|
||||||
|
text: qsTr("Beschäftigungsverhältnis")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "jobstatus"
|
||||||
|
id: title
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: [qsTr("Vollzeit"), qsTr("Teilzeit"), qsTr("Minijob"), qsTr("Ausgeschieden")]
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("IBAN")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "iban"
|
||||||
|
id: iban
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Bank")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "bank"
|
||||||
|
id: bankname
|
||||||
|
Layout.fillWidth: true
|
||||||
|
model: ["",qsTr("Sparkasse"),qsTr("Volksbank")]
|
||||||
|
editable: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
34
Gui/Employees/EmployeeDetails.qml
Normal file
34
Gui/Employees/EmployeeDetails.qml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import TeroStyle
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
property int row: -1
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
onRowChanged: {
|
||||||
|
if (row !== -1) {
|
||||||
|
applicantForm.setValue(applicantModel.applicant(row))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicantForm {
|
||||||
|
id: applicantForm
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.verticalStretchFactor: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: qsTr("Als Mitarbeiter:in Einstellen")
|
||||||
|
icon.source: "qrc:/images/InboxArrowDown.svg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
263
Gui/Employees/EmployeeNationalInsurance.qml
Normal file
263
Gui/Employees/EmployeeNationalInsurance.qml
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: nationalInsurance
|
||||||
|
columns: 2
|
||||||
|
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
Layout.preferredWidth: bankAccount.longest.width
|
||||||
|
text: qsTr("Herkunftsland")
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "country"
|
||||||
|
id: nation
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
model: [qsTr("Deutschland"), qsTr("Syrien")]
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Sozialversicherungs-Nr")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "socialno"
|
||||||
|
id: socialno
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Steuer-ID")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "taxno"
|
||||||
|
id: taxnumber
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Krankenkasse")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "medicalinsurance"
|
||||||
|
id: medicalinsurance
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Knappschaft")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
visible: bankAccount.jobstatus.currentText === "Minijob" ? 1:0
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "knappschaft"
|
||||||
|
id: knappschaft
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: bankAccount.jobstatus.currentText === "Minijob" ? 1:0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ausweistyp")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "idtype"
|
||||||
|
id: idtype
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
model: [qsTr("Personalausweis"), qsTr("Reisepass")]
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ausweis Nr.")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "idnumber"
|
||||||
|
id: idnumber
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ausweis gültig bis")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "idexpiry"
|
||||||
|
id: idexpiry
|
||||||
|
Layout.fillWidth: true
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
|
||||||
|
}
|
||||||
|
Keys.onPressed: (event)=>
|
||||||
|
{
|
||||||
|
if (event.key !== Qt.Key_Backspace)
|
||||||
|
{
|
||||||
|
var len = idexpiry.length
|
||||||
|
var bd = idexpiry.text
|
||||||
|
if (len === 2 || len === 5) idexpiry.text = bd + "."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ausstellungsort")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "idauthority"
|
||||||
|
id: idauthority
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: test
|
||||||
|
text: qsTr("Ausgestellt am")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "idissued"
|
||||||
|
id: idissued
|
||||||
|
Layout.fillWidth: true
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
|
||||||
|
}
|
||||||
|
Keys.onPressed: (event)=>
|
||||||
|
{
|
||||||
|
if (event.key !== Qt.Key_Backspace)
|
||||||
|
{
|
||||||
|
var len = idissued.length
|
||||||
|
var bd = idissued.text
|
||||||
|
if (len === 2 || len === 5) idissued.text = bd + "."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CheckBox
|
||||||
|
{
|
||||||
|
Layout.preferredWidth: bankAccount.longest.width
|
||||||
|
property string name: "worklicense"
|
||||||
|
id: worklicense
|
||||||
|
text: qsTr("Arbeitserlaubnis <font color='red'><b>?</b></font>")
|
||||||
|
visible: nation.currentText === "Deutschland"? false:true
|
||||||
|
}
|
||||||
|
CheckBox
|
||||||
|
{
|
||||||
|
property string name: "residencetype"
|
||||||
|
id: residencetype
|
||||||
|
text: qsTr("Aufenthaltstitel")
|
||||||
|
visible: nation.currentText === "Deutschland"? false:true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Aufenthaltstitel Nr.")
|
||||||
|
visible: residencetype.checked
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "residenceno"
|
||||||
|
id: residenceno
|
||||||
|
visible: residencetype.checked
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ausgestellt von")
|
||||||
|
visible: residencetype.checked
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "residenceauthority"
|
||||||
|
id: residenceauthority
|
||||||
|
visible: residencetype.checked
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ausgestellt am")
|
||||||
|
visible: residencetype.checked
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "residenceissued"
|
||||||
|
id: residenceissued
|
||||||
|
visible: residencetype.checked
|
||||||
|
Layout.fillWidth: true
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
|
||||||
|
}
|
||||||
|
Keys.onPressed: (event)=>
|
||||||
|
{
|
||||||
|
if (event.key !== Qt.Key_Backspace)
|
||||||
|
{
|
||||||
|
var len = residenceissued.length
|
||||||
|
var bd = residenceissued.text
|
||||||
|
if (len === 2 || len === 5) residenceissued.text = bd + "."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Gültig bis")
|
||||||
|
visible: residencetype.checked
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "residenceexpiry"
|
||||||
|
id: residenceexpiry
|
||||||
|
visible: residencetype.checked
|
||||||
|
Layout.fillWidth: true
|
||||||
|
validator: RegularExpressionValidator
|
||||||
|
{
|
||||||
|
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
|
||||||
|
}
|
||||||
|
Keys.onPressed: (event)=>
|
||||||
|
{
|
||||||
|
if (event.key !== Qt.Key_Backspace)
|
||||||
|
{
|
||||||
|
var len = residenceexpiry.length
|
||||||
|
var bd = residenceexpiry.text
|
||||||
|
if (len === 2 || len === 5) residenceexpiry.text = bd + "."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
409
Gui/Employees/EmployeePersonalData.qml
Normal file
409
Gui/Employees/EmployeePersonalData.qml
Normal file
@@ -0,0 +1,409 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import TeroStyle
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: personalData
|
||||||
|
|
||||||
|
function checkPersonalField() {
|
||||||
|
return (firstname.text.trim() && lastname.text.trim() && street.text.trim() && houseno.text.trim() && (postcode.editText.trim() || postcode.currentText.trim()) && (city.editText.trim() || city.currentText.trim()) && birthday.text.trim() && phonenumber.text.trim() && cellphone.text.trim() && email.text.trim() && jobdescription.text.trim() && contractstart.text.trim() && contractend.text.trim() && briefAnrede.text.trim());
|
||||||
|
}
|
||||||
|
function requiredField() {
|
||||||
|
const pf = "Pflichtfeld";
|
||||||
|
street.placeholderText = pf;
|
||||||
|
phonenumber.placeholderText = pf;
|
||||||
|
cellphone.placeholderText = pf;
|
||||||
|
email.placeholderText = pf;
|
||||||
|
jobdescription.placeholderText = pf;
|
||||||
|
contractstart.placeholderText = pf;
|
||||||
|
contractend.placeholderText = pf;
|
||||||
|
briefAnrede.placeholderText = pf;
|
||||||
|
houseno.placeholderText = pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
columns: 4
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Anrede")
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
id: title
|
||||||
|
|
||||||
|
property string name: "title"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: [qsTr("Keine Angabe"), qsTr("Herr"), qsTr("Frau")]
|
||||||
|
|
||||||
|
onCurrentTextChanged: {
|
||||||
|
switch (title.currentIndex) {
|
||||||
|
case 1:
|
||||||
|
briefAnrede.text = "Sehr geehrter Herr ";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
briefAnrede.text = "Sehr geehrte Frau ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
briefAnrede.text = "Guten Tag ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Vorname*")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: firstname
|
||||||
|
|
||||||
|
property string name: "firstname"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Nachname*")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: lastname
|
||||||
|
|
||||||
|
property string name: "lastname"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Straße")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: street
|
||||||
|
|
||||||
|
property string name: "street"
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Nr.")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: houseno
|
||||||
|
|
||||||
|
property string name: "houseno"
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
validator: RegularExpressionValidator {
|
||||||
|
regularExpression: /([0-9a-zA-Z\-]{1,6})/
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("PLZ")
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
id: postcode
|
||||||
|
|
||||||
|
property string name: "postcode"
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
currentIndex: -1
|
||||||
|
editable: true
|
||||||
|
model: address_model
|
||||||
|
popup.height: 300
|
||||||
|
textRole: "display"
|
||||||
|
|
||||||
|
validator: PostcodeValidator {
|
||||||
|
}
|
||||||
|
|
||||||
|
onActivated: currentValue
|
||||||
|
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
|
||||||
|
onCurrentTextChanged: checkFields()
|
||||||
|
onEditTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Ort")
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
id: city
|
||||||
|
|
||||||
|
property string name: "city"
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
currentIndex: -1
|
||||||
|
editable: true
|
||||||
|
model: address_model
|
||||||
|
popup.height: 300
|
||||||
|
textRole: "city"
|
||||||
|
|
||||||
|
onCurrentTextChanged: checkFields()
|
||||||
|
onEditTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Geburtsname")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: birthname
|
||||||
|
|
||||||
|
property string name: "birthname"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Geburtsdatum*")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: birthday
|
||||||
|
|
||||||
|
property string name: "birthday"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
validator: RegularExpressionValidator {
|
||||||
|
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: event => {
|
||||||
|
if (event.key !== Qt.Key_Backspace) {
|
||||||
|
var len = birthday.length;
|
||||||
|
var bd = birthday.text;
|
||||||
|
if (len === 2 || len === 5)
|
||||||
|
birthday.text = bd + ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Geburtsort*")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: placeofbirth
|
||||||
|
|
||||||
|
property string name: "placeofbirth"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Telefonnummer")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: phonenumber
|
||||||
|
|
||||||
|
property string name: "phone"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
validator: RegularExpressionValidator {
|
||||||
|
regularExpression: /([+0-9]{1})([0-9]{1,17})/
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Mobil")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: cellphone
|
||||||
|
|
||||||
|
property string name: "mobile"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
validator: RegularExpressionValidator {
|
||||||
|
regularExpression: /([+0-9]{1})([0-9]{1,17})/
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("E-Mail")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: email
|
||||||
|
|
||||||
|
property string name: "email"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderText: qsTr("beispiel@domain.de")
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
validator: EmailAddressValidator {
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Familienstand")
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
id: maritalstatus
|
||||||
|
|
||||||
|
property string name: "maritalstatus"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: [qsTr("ledig"), qsTr("verheiratet"), qsTr("verwitwet"), qsTr("geschieden")]
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Stundenlohn")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: salary
|
||||||
|
|
||||||
|
property string name: "salary"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Jobbeschreibung")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: jobdescription
|
||||||
|
|
||||||
|
property string name: "jobdesc"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Vertragsbeginn")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: contractstart
|
||||||
|
|
||||||
|
property string name: "contractstart"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
validator: RegularExpressionValidator {
|
||||||
|
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: event => {
|
||||||
|
if (event.key !== Qt.Key_Backspace) {
|
||||||
|
var len = contractstart.length;
|
||||||
|
var bd = contractstart.text;
|
||||||
|
if (len === 2 || len === 5)
|
||||||
|
contractstart.text = bd + ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Vertragsende")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: contractend
|
||||||
|
|
||||||
|
property string name: "contractend"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
validator: RegularExpressionValidator {
|
||||||
|
regularExpression: /((^|)(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]))\.((^|)(0[1-9]{1}|1[0-2]{1}))\.((^|)(196[0-9]{1}|19[7-9]{1}[0-9]{1}|20[0-9]{2}))/
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: event => {
|
||||||
|
if (event.key !== Qt.Key_Backspace) {
|
||||||
|
var len = contractend.length;
|
||||||
|
var bd = contractend.text;
|
||||||
|
if (len === 2 || len === 5)
|
||||||
|
contractend.text = bd + ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Arbeitszeiten Tage")
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
id: workdays
|
||||||
|
|
||||||
|
property string name: "workdays"
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
model: ["1", "2", "3", "4", "5", "6", "7"]
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Stunden")
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
id: workhours
|
||||||
|
|
||||||
|
property string name: "workhours"
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
model: ["1", "2", "3", "4", "5", "6", "7", "8"]
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Briefanrede")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: briefAnrede
|
||||||
|
|
||||||
|
property string name: "formofaddress"
|
||||||
|
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderTextColor: "red"
|
||||||
|
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.columnSpan: 4
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
63
Gui/Employees/EmployeeVarious.qml
Normal file
63
Gui/Employees/EmployeeVarious.qml
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: applicantVarious
|
||||||
|
columns: 2
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
Layout.preferredWidth: bankAccount.longest.width
|
||||||
|
text: qsTr("Grad der Behinderung")
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "disability"
|
||||||
|
id: disability
|
||||||
|
placeholderText: "0,0"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Disponent")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "disponent"
|
||||||
|
id: disponent
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Kostenstelle")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "office"
|
||||||
|
id: office
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Fremdlohn-Nr.")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "empreference"
|
||||||
|
id: empreference
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
143
Gui/Employees/EmployeesTable.qml
Normal file
143
Gui/Employees/EmployeesTable.qml
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Qt.labs.qmlmodels
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
SearchBar {
|
||||||
|
onSubmitted: (query) => {
|
||||||
|
applicantModel.searchQuery = query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QuickFilter {
|
||||||
|
model: ListModel {
|
||||||
|
ListElement {
|
||||||
|
name: "Alle"
|
||||||
|
selected: true
|
||||||
|
text: qsTr("Alle")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Bewerber"
|
||||||
|
selected: false
|
||||||
|
text: qsTr("Bewerber")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Mitarbeiter"
|
||||||
|
selected: false
|
||||||
|
text: qsTr("Kunde")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Erledigt"
|
||||||
|
selected: false
|
||||||
|
text: qsTr("Erledigt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectedChanged: name => {
|
||||||
|
employee_model.viewCriterion(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
flat: true
|
||||||
|
icon.source: "qrc:/images/PlusCircle.svg"
|
||||||
|
text: qsTr("Bewerber Hinzufügen")
|
||||||
|
|
||||||
|
onClicked: contentStack.push("AddApplicant.qml")
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
flat: true
|
||||||
|
icon.source: "qrc:/images/PlusCircle.svg"
|
||||||
|
text: qsTr("Mitarbeiter Hinzufügen")
|
||||||
|
|
||||||
|
onClicked: contentStack.push("AddEmployee.qml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
HorizontalHeaderView {
|
||||||
|
movableColumns: true
|
||||||
|
syncView: employeesTable
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: Colors.primary
|
||||||
|
implicitHeight: 33
|
||||||
|
implicitWidth: 1
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: Colors.primaryContrast
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font: Typography.smallBold
|
||||||
|
height: parent.height
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
padding: Dimensions.s
|
||||||
|
text: model.display
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TableView {
|
||||||
|
id: employeesTable
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
columnSpacing: 2
|
||||||
|
model: applicantModel
|
||||||
|
resizableColumns: true
|
||||||
|
rowSpacing: 2
|
||||||
|
selectionBehavior: TableView.SelectRows
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
ScrollBar.vertical: ScrollBar {
|
||||||
|
policy: ScrollBar.AsNeeded
|
||||||
|
}
|
||||||
|
delegate: Rectangle {
|
||||||
|
required property bool selected
|
||||||
|
|
||||||
|
color: selected ? Colors.primaryHighlight : Colors.transparent
|
||||||
|
implicitHeight: 33
|
||||||
|
implicitWidth: employeesTable.width / employeesTable.columns
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: Colors.foreground
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font: Typography.small
|
||||||
|
height: parent.height
|
||||||
|
padding: Dimensions.s
|
||||||
|
text: (model.display === null || model.display === undefined) ? "" : model.display
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
contentStack.push("EmployeeDetails.qml", { row });
|
||||||
|
}
|
||||||
|
onEntered: {
|
||||||
|
employeesTable.selectionModel.select(employeesTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectionModel: ItemSelectionModel {
|
||||||
|
model: employeesTable.model
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
1
Gui/Employees/qmldir
Normal file
1
Gui/Employees/qmldir
Normal file
@@ -0,0 +1 @@
|
|||||||
|
module Employees
|
||||||
45
Gui/EncryptionKey.qml
Normal file
45
Gui/EncryptionKey.qml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: passEncryptKeyGrid
|
||||||
|
columns: 2
|
||||||
|
columnSpacing: 5
|
||||||
|
rowSpacing: 9
|
||||||
|
// anchors.fill: parent
|
||||||
|
|
||||||
|
property string name: "pyqcrm"
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Encryption Key eingeben")
|
||||||
|
font.pixelSize: 40
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
padding: 15
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Encryption Key:")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: passEncryptKey
|
||||||
|
placeholderText: qsTr("Hier Encryption Key eingeben")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 3
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
property string name: "ENCRYPT_KEY"
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
196
Gui/Firststart.qml
Normal file
196
Gui/Firststart.qml
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import QtCore
|
||||||
|
|
||||||
|
import "../js/qmldict.js" as Qmldict
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
property string recpass: ""
|
||||||
|
property bool adminAvailable: true
|
||||||
|
|
||||||
|
|
||||||
|
id: firstStartItem
|
||||||
|
anchors.fill: parent
|
||||||
|
StackView
|
||||||
|
{
|
||||||
|
id: firstStart
|
||||||
|
anchors.fill: parent
|
||||||
|
initialItem: "DbConfiguration.qml"
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.margins: 9
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: cancelBtn
|
||||||
|
text: qsTr("Abbrechen")
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: submitBtn
|
||||||
|
text: qsTr("Speichern")
|
||||||
|
property var grids: firstStart.currentItem
|
||||||
|
property var pyqcrm_conf: ({})
|
||||||
|
property var admin: Boolean
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
if (firstStart.currentItem.name === "database")
|
||||||
|
{
|
||||||
|
pyqcrm_conf = Qmldict.firstConf(submitBtn.grids)
|
||||||
|
if (pyqcrm_conf)
|
||||||
|
{
|
||||||
|
config.setConfig(pyqcrm_conf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pyqcrm_conf = Qmldict.firstConf(submitBtn.grids)
|
||||||
|
if (pyqcrm_conf) config.addAdminUser(pyqcrm_conf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageDialog
|
||||||
|
{
|
||||||
|
id: recoveryDialog
|
||||||
|
text: qsTr("Diesen Wiederherstellungscode musst du sicher aufbewahren!\nMöchtest du das jetzt machen?")
|
||||||
|
title: qsTr("Wiederherstellen")
|
||||||
|
buttons: MessageDialog.Yes | MessageDialog.No
|
||||||
|
onAccepted: recoveryPaswordDialog.open()
|
||||||
|
onRejected: contentStack.replace("LoginSreen.qml")
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageDialog
|
||||||
|
{
|
||||||
|
id: conErrDialog
|
||||||
|
text: qsTr("Datenbankverbindung fehlgeschlagen")
|
||||||
|
title: qsTr("Datenbank Verbindung")
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog
|
||||||
|
{
|
||||||
|
|
||||||
|
id: recoveryPaswordDialog
|
||||||
|
modal: true
|
||||||
|
title: qsTr("Wiederherstellung")
|
||||||
|
anchors.centerIn: parent
|
||||||
|
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||||
|
onAccepted:
|
||||||
|
{
|
||||||
|
recpass = recoveryPaswordInput.text
|
||||||
|
saveRecoveryDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Wiederherstellungspasswort eingeben: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: recoveryPaswordInput
|
||||||
|
text: ""
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
implicitWidth: 300
|
||||||
|
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Wiederherstellungspasswort eingeben: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: repeatRecoveryPaswordInput
|
||||||
|
text: ""
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
implicitWidth: 300
|
||||||
|
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDialog
|
||||||
|
{
|
||||||
|
id: saveRecoveryDialog
|
||||||
|
title: qsTr("Wiederherstellungsdatei")
|
||||||
|
fileMode: adminAvailable? FileDialog.OpenFile: FileDialog.SaveFile
|
||||||
|
nameFilters: ["PYQCRM Recovery files (*.pyqrec)"]
|
||||||
|
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
|
||||||
|
onAccepted:
|
||||||
|
{
|
||||||
|
if (!adminAvailable) config.saveRecoveryKey(saveRecoveryDialog.currentFile, recpass)
|
||||||
|
else config.getRecoveryKey(saveRecoveryDialog.currentFile, recpass)
|
||||||
|
|
||||||
|
contentStack.replace("LoginSreen.qml")
|
||||||
|
}
|
||||||
|
|
||||||
|
onRejected:
|
||||||
|
{
|
||||||
|
if (adminAvailable) quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader
|
||||||
|
{
|
||||||
|
id: utilityDialogs
|
||||||
|
source: "UtilityDialogs.qml"
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
config.dbConnectionError.connect(onDbConnectionError)
|
||||||
|
config.adminUserError.connect(onAdminUserError)
|
||||||
|
config.backupEncryptionKey.connect(onBackupEncryptionKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBackupEncryptionKey()
|
||||||
|
{
|
||||||
|
|
||||||
|
utilityDialogs.item.recoveryDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDbConnectionError(msg, success)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
conErrDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAdminUserError(msg, success)
|
||||||
|
{
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
recoveryPaswordDialog.open()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
adminAvailable = false
|
||||||
|
firstStart.push("AdminUserConfig.qml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
137
Gui/LoginScreen.qml
Normal file
137
Gui/LoginScreen.qml
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
import QtCore
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property string recpass: ""
|
||||||
|
|
||||||
|
function dbConnectionFailed(msg) {
|
||||||
|
notifications.notificationDialog.informativeText = msg;
|
||||||
|
notifications.notificationDialog.text = "Verbindung zum Datenbankserver verloren";
|
||||||
|
notifications.notificationDialog.open();
|
||||||
|
}
|
||||||
|
function getEncryptionKey() {
|
||||||
|
recoveryPaswordDialog.open();
|
||||||
|
}
|
||||||
|
function loggedin() {
|
||||||
|
contentStack.replace("Dashboard.qml");
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: Dimensions.l
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
loggedin_user.loginOkay.connect(loggedin);
|
||||||
|
config.invalidEncryptionKey.connect(getEncryptionKey);
|
||||||
|
config.checkEncryptionKey();
|
||||||
|
loggedin_user.noDbConnection.connect(dbConnectionFailed);
|
||||||
|
benutzerName.forceActiveFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Dimensions.m
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.bottomMargin: Dimensions.l
|
||||||
|
font: Typography.h1
|
||||||
|
text: qsTr("Login")
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("Benutzername")
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: benutzerName
|
||||||
|
|
||||||
|
focus: true
|
||||||
|
implicitWidth: 300
|
||||||
|
placeholderText: qsTr("Benutzernamen eingeben")
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (benutzerName.text.trim() && passwort.text.trim())
|
||||||
|
loggedin_user.login(benutzerName.text.trim(), passwort.text);
|
||||||
|
else if (benutzerName.text.trim())
|
||||||
|
passwort.forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Field {
|
||||||
|
label: qsTr("Passwort")
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: passwort
|
||||||
|
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
implicitWidth: 300
|
||||||
|
placeholderText: qsTr("Passwort eingeben")
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (benutzerName.text.trim() && passwort.text.trim())
|
||||||
|
loggedin_user.login(benutzerName.text.trim(), passwort.text);
|
||||||
|
else if (passwort.text.trim())
|
||||||
|
benutzerName.forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.topMargin: Dimensions.m
|
||||||
|
icon.source: "qrc:/images/ArrowRightEndOnRectangle.svg"
|
||||||
|
implicitWidth: parent.width
|
||||||
|
text: qsTr("Login")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (benutzerName.text.trim() && passwort.text.trim())
|
||||||
|
loggedin_user.login(benutzerName.text.trim(), passwort.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
Dialog {
|
||||||
|
id: recoveryPaswordDialog
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
modal: true
|
||||||
|
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||||
|
title: qsTr("Wiederherstellung")
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
recpass = recoveryPaswordInput.text;
|
||||||
|
getRecoveryDialog.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
RowLayout {
|
||||||
|
Label {
|
||||||
|
text: qsTr("Wiederherstellungspasswort eingeben: ")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: recoveryPaswordInput
|
||||||
|
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
implicitWidth: 300
|
||||||
|
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FileDialog {
|
||||||
|
id: getRecoveryDialog
|
||||||
|
|
||||||
|
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
|
||||||
|
fileMode: FileDialog.OpenFile
|
||||||
|
nameFilters: ["PYQCRM Recovery files (*.pyqrec)"]
|
||||||
|
title: qsTr("Wiederherstellungsdatei")
|
||||||
|
|
||||||
|
onAccepted: config.getRecoveryKey(getRecoveryDialog.currentFile, recpass)
|
||||||
|
onRejected: quit()
|
||||||
|
}
|
||||||
|
Notifications {
|
||||||
|
id: notifications
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Gui/MiscConf.qml
Executable file
22
Gui/MiscConf.qml
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
property alias sysTray: sysTray
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: 35
|
||||||
|
|
||||||
|
Switch
|
||||||
|
{
|
||||||
|
id: sysTray
|
||||||
|
text: qsTr("Beim minimieren, in der Taskleiste anzeigen")
|
||||||
|
checked: config.systray()
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
120
Gui/Navigation.qml
Normal file
120
Gui/Navigation.qml
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
property bool onSubPage: false
|
||||||
|
|
||||||
|
height: parent.height
|
||||||
|
spacing: 0
|
||||||
|
z: 3
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
onSubPage = Qt.binding(() => contentStack.depth > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
ButtonGroup {
|
||||||
|
id: mainNav
|
||||||
|
|
||||||
|
}
|
||||||
|
BarButton {
|
||||||
|
ButtonGroup.group: mainNav
|
||||||
|
icon.source: "qrc:/images/Square3Stack3D-Outline.svg"
|
||||||
|
target: "/Gui/Dashboard.qml"
|
||||||
|
text: qsTr("Dashboard")
|
||||||
|
visible: !onSubPage
|
||||||
|
}
|
||||||
|
BarButton {
|
||||||
|
ButtonGroup.group: mainNav
|
||||||
|
icon.source: "qrc:/images/UserGroup-Outline.svg"
|
||||||
|
target: "/Gui/CustomersTable.qml"
|
||||||
|
text: qsTr("Kunden")
|
||||||
|
visible: !onSubPage
|
||||||
|
}
|
||||||
|
BarButton {
|
||||||
|
ButtonGroup.group: mainNav
|
||||||
|
icon.source: "qrc:/images/BuildingOffice2-Outline.svg"
|
||||||
|
target: "/Gui/ObjectsTable.qml"
|
||||||
|
text: qsTr("Objekt")
|
||||||
|
visible: !onSubPage
|
||||||
|
}
|
||||||
|
BarButton {
|
||||||
|
ButtonGroup.group: mainNav
|
||||||
|
icon.source: "qrc:/images/Identification-Outline.svg"
|
||||||
|
target: "/Gui/Employees/EmployeesTable.qml"
|
||||||
|
text: qsTr("Mitarbeiter")
|
||||||
|
visible: !onSubPage
|
||||||
|
}
|
||||||
|
BarButton {
|
||||||
|
ButtonGroup.group: mainNav
|
||||||
|
icon.source: "qrc:/images/RectangleStack-Outline.svg"
|
||||||
|
target: "/Gui/OffersTable.qml"
|
||||||
|
text: qsTr("Angebote")
|
||||||
|
visible: !onSubPage
|
||||||
|
}
|
||||||
|
BarButton {
|
||||||
|
ButtonGroup.group: mainNav
|
||||||
|
icon.source: "qrc:/images/Wallet-Outline.svg"
|
||||||
|
text: qsTr("Abrechnung")
|
||||||
|
visible: !onSubPage
|
||||||
|
}
|
||||||
|
BarButton {
|
||||||
|
icon.source: "qrc:/images/ArrowLeftCircle-Outline.svg"
|
||||||
|
text: qsTr("Zurück")
|
||||||
|
visible: onSubPage
|
||||||
|
checkable: false
|
||||||
|
|
||||||
|
onClicked: contentStack.pop();
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
BarButton {
|
||||||
|
checkable: false
|
||||||
|
icon.source: "qrc:/images/Bars3.svg"
|
||||||
|
|
||||||
|
onClicked: mainMenu.open()
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
id: mainMenu
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Einstellungen")
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
// TODO: Check if logged-in user is admin first!!
|
||||||
|
|
||||||
|
contentStack.push("PyqcrmConf.qml");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuSeparator {
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Als PDF exportieren")
|
||||||
|
}
|
||||||
|
MenuSeparator {
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Drucken")
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Erweiterter Druck")
|
||||||
|
|
||||||
|
onTriggered: printerDialog.show()
|
||||||
|
}
|
||||||
|
MenuSeparator {
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Über PYQCRM")
|
||||||
|
|
||||||
|
onTriggered: readMeWin.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
33
Gui/NoCustomerContact.qml
Normal file
33
Gui/NoCustomerContact.qml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 25
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "darksalmon"
|
||||||
|
font.bold: true
|
||||||
|
text: qsTr("Kein Ansprechpartner gefunden")
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
color: "goldenrod"
|
||||||
|
text: qsTr("Was willst du tun?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid row
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
27
Gui/NoDbConnection.qml
Normal file
27
Gui/NoDbConnection.qml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Dimensions.s
|
||||||
|
height: implicitHeight
|
||||||
|
|
||||||
|
H1 {
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
text: qsTr("Keine Verbindung zur Datenbank!")
|
||||||
|
color: Colors.foreground
|
||||||
|
}
|
||||||
|
H2 {
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
text: qsTr("Programm kann nicht starten…")
|
||||||
|
color: Colors.foreground
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.topMargin: Dimensions.l
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
text: qsTr("Beenden")
|
||||||
|
|
||||||
|
onClicked: Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Gui/Notifications.qml
Normal file
12
Gui/Notifications.qml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
MessageDialog
|
||||||
|
{
|
||||||
|
id: notificationDialog
|
||||||
|
buttons: MessageDialog.Ok
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
317
Gui/ObjectAddOnContactPerson.qml
Normal file
317
Gui/ObjectAddOnContactPerson.qml
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
property var contacts: null
|
||||||
|
columns: 2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Position")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignTop
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
//property string name: "contacttype"
|
||||||
|
id: posizion
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
model: [qsTr("Beirat"), qsTr("Hausmeister"), qsTr("Hausbewohner"), qsTr("Sonstiges")]
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Anrede")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
id: title
|
||||||
|
model: [qsTr("Herr"), qsTr("Frau"), qsTr("Keine Angabe")]
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Vorname*")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: firstname
|
||||||
|
Layout.fillWidth: true
|
||||||
|
// onTextChanged: checkContactFields()
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Nachname*")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: lastname
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: mobile.text ? qsTr("Telefonnummer") : qsTr("Telefonnummer*")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: phonenumber
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: phonenumber.text ? qsTr("Mobil") : qsTr("Mobil*")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: mobile
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: removeContact
|
||||||
|
text: qsTr("Entfernen")
|
||||||
|
enabled: false
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
|
||||||
|
if (contactView.highlightFollowsCurrentItem)
|
||||||
|
{
|
||||||
|
delete contacts[contactView.currentIndex]
|
||||||
|
contacts = contacts.filter(elm => elm)
|
||||||
|
contactModel.remove(contactView.currentIndex)
|
||||||
|
contactView.highlightFollowsCurrentItem = false
|
||||||
|
contactView.currentIndex = -1
|
||||||
|
if (Object.keys(contacts).length === 0)
|
||||||
|
{
|
||||||
|
enabled = false
|
||||||
|
console.log(contacts)
|
||||||
|
}
|
||||||
|
checkFields()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: addContact
|
||||||
|
text: qsTr("Hinzufügen")
|
||||||
|
enabled: firstname.text.trim() && lastname.text.trim() && (phonenumber.text.trim() || mobile.text.trim()) && (contacts === null || Object.keys(contacts).length < 3)
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
var num_contacts = 0
|
||||||
|
if (contacts !== null && contacts !== undefined) num_contacts = Object.keys(contacts).length
|
||||||
|
else contacts = []
|
||||||
|
if (num_contacts < 3 && firstname.text.trim() !== "" && lastname.text.trim() !== "" && (phonenumber.text.trim() !== "" || mobile.text.trim() !== ""))
|
||||||
|
{
|
||||||
|
contacts[num_contacts] = {}
|
||||||
|
contacts[num_contacts]["title"] = title.currentText
|
||||||
|
contacts[num_contacts]["position"] = posizion.currentText
|
||||||
|
contacts[num_contacts]["fname"] = firstname.text.trim()
|
||||||
|
contacts[num_contacts]["lname"] = lastname.text.trim()
|
||||||
|
contacts[num_contacts]["phone"] = phonenumber.text.trim()
|
||||||
|
contacts[num_contacts]["mobile"] = mobile.text.trim()
|
||||||
|
contactModel.append({name: title.currentText + " " + firstname.text.trim() + " " + lastname.text.trim(), phone: phonenumber.text.trim(), mobile: mobile.text.trim(), posizion: posizion.currentText})
|
||||||
|
if (checkFields())
|
||||||
|
{
|
||||||
|
saveBtn.enabled = true
|
||||||
|
}
|
||||||
|
firstname.text = ""
|
||||||
|
lastname.text = ""
|
||||||
|
phonenumber.text = ""
|
||||||
|
mobile.text = ""
|
||||||
|
posizion.currentIndex = 0
|
||||||
|
title.currentIndex = 0
|
||||||
|
|
||||||
|
removeContact.enabled = true
|
||||||
|
checkFields()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ansprechpartner")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignTop
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel
|
||||||
|
{
|
||||||
|
id: contactModel
|
||||||
|
}
|
||||||
|
|
||||||
|
// Component
|
||||||
|
// {
|
||||||
|
// id: headline
|
||||||
|
// Row
|
||||||
|
// {
|
||||||
|
// spacing: 9
|
||||||
|
// Text
|
||||||
|
// {
|
||||||
|
// id: cpname
|
||||||
|
// text: qsTr("Name")
|
||||||
|
// font.bold: true
|
||||||
|
// horizontalAlignment: Text.AlignLeft
|
||||||
|
// color: "white"
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Text
|
||||||
|
// {
|
||||||
|
// id: cpphone
|
||||||
|
// text: qsTr("Telefon")
|
||||||
|
// font.bold: true
|
||||||
|
// horizontalAlignment: Text.AlignLeft
|
||||||
|
// color: "white"
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Text
|
||||||
|
// {
|
||||||
|
// id: cpmobile
|
||||||
|
// text: qsTr("Mobil")
|
||||||
|
// font.bold: true
|
||||||
|
// horizontalAlignment: Text.AlignLeft
|
||||||
|
// color: "white"
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Text
|
||||||
|
// {
|
||||||
|
// id: cppos
|
||||||
|
// text: qsTr("Position")
|
||||||
|
// font.bold: true
|
||||||
|
// horizontalAlignment: Text.AlignLeft
|
||||||
|
// color: "white"
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Text
|
||||||
|
// {
|
||||||
|
// id: cttype
|
||||||
|
// text: qsTr("Typ")
|
||||||
|
// font.bold: true
|
||||||
|
// horizontalAlignment: Text.AlignLeft
|
||||||
|
// color: "white"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
Component
|
||||||
|
{
|
||||||
|
id: highlight
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
color: "lightsteelblue"; radius: 5
|
||||||
|
y: contactView.currentItem.y
|
||||||
|
Behavior on y
|
||||||
|
{
|
||||||
|
SpringAnimation
|
||||||
|
{
|
||||||
|
spring: 3
|
||||||
|
damping: 0.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: mainRect
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: 100
|
||||||
|
color: firstname.palette.base
|
||||||
|
border.color: firstname.activeFocus? firstname.palette.highlight: firstname.palette.base
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ScrollView
|
||||||
|
{
|
||||||
|
id: objContactView
|
||||||
|
// Layout.fillWidth: true
|
||||||
|
// Layout.preferredHeight: 100
|
||||||
|
//Layout.columnSpan: 3
|
||||||
|
anchors.fill: mainRect
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||||
|
|
||||||
|
|
||||||
|
ListView
|
||||||
|
{
|
||||||
|
id: contactView
|
||||||
|
anchors.fill: objContactView
|
||||||
|
// implicitHeight: objContactView.height
|
||||||
|
// implicitWidth: objContactView.width
|
||||||
|
model: contactModel
|
||||||
|
// header: headline
|
||||||
|
highlight: Rectangle { color: "slategray"; radius: 3}
|
||||||
|
highlightFollowsCurrentItem: false
|
||||||
|
//focus: true test
|
||||||
|
onActiveFocusChanged: if(!focus) currentIndex = -1
|
||||||
|
delegate: Item
|
||||||
|
{
|
||||||
|
width: contactView.width
|
||||||
|
height: 77
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
contactView.currentIndex = index
|
||||||
|
contactView.highlightFollowsCurrentItem = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Column
|
||||||
|
{
|
||||||
|
anchors.margins: 5
|
||||||
|
|
||||||
|
//spacing: 3
|
||||||
|
Text
|
||||||
|
{
|
||||||
|
text: '<b>' + qsTr('Name: ') + '</b>' + model.name
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
Text
|
||||||
|
{
|
||||||
|
text: '<b>' + qsTr('Telefon: ') + '</b>' + model.phone
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
Text
|
||||||
|
{
|
||||||
|
text: '<b>' + qsTr('Handy: ') + '</b>' + model.mobile
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
Text
|
||||||
|
{
|
||||||
|
text: '<b>' + qsTr('Position: ') + '</b>' + model.posizion
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Column
|
||||||
|
} // delegate
|
||||||
|
} // Listview
|
||||||
|
} // Scrollview
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
125
Gui/ObjectAddOnEmployee.qml
Normal file
125
Gui/ObjectAddOnEmployee.qml
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
// property var employeeForm: null
|
||||||
|
// property var employees: null
|
||||||
|
// id: oaoemployee
|
||||||
|
// columns: 2
|
||||||
|
// rows: 4
|
||||||
|
// Label
|
||||||
|
// {
|
||||||
|
// text: qsTr("Mitarbeiter")
|
||||||
|
// Layout.alignment: Qt.AlignRight | Qt.AlignTop
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ListModel
|
||||||
|
// {
|
||||||
|
// id: employeeModel
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Component
|
||||||
|
// {
|
||||||
|
// id: employeesHeader
|
||||||
|
// Row
|
||||||
|
// {
|
||||||
|
// Text
|
||||||
|
// {
|
||||||
|
// id: empName
|
||||||
|
// text: qsTr("Mitarbeiter")
|
||||||
|
// width: 175
|
||||||
|
// font.bold: true
|
||||||
|
// horizontalAlignment: Text.AlignLeft
|
||||||
|
// color: "black"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Rectangle
|
||||||
|
// {
|
||||||
|
// Layout.fillWidth: true
|
||||||
|
// implicitHeight: 75
|
||||||
|
// Layout.rowSpan: 2
|
||||||
|
// color: mitarbeiterhin.palette.base
|
||||||
|
// border.color: mitarbeiterhin.activeFocus? mitarbeiterhin.palette.highlight: mitarbeiterhin.palette.base
|
||||||
|
// ListView
|
||||||
|
// {
|
||||||
|
// id: employeesList
|
||||||
|
// //anchors.fill: parent
|
||||||
|
// implicitHeight: parent.height
|
||||||
|
|
||||||
|
// model: employeeModel
|
||||||
|
|
||||||
|
// header: employeesHeader
|
||||||
|
|
||||||
|
// delegate: Row
|
||||||
|
// {
|
||||||
|
// width: 200
|
||||||
|
// height: 15
|
||||||
|
// //padding: 7
|
||||||
|
// Text
|
||||||
|
// {
|
||||||
|
// text: model.namens
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// RowLayout
|
||||||
|
// {
|
||||||
|
// Layout.columnSpan: 2
|
||||||
|
// Layout.fillWidth: true
|
||||||
|
// Item
|
||||||
|
// {
|
||||||
|
// Layout.fillWidth: true
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Button
|
||||||
|
// {
|
||||||
|
// id: mitarbeiterraus
|
||||||
|
// text: qsTr("Mitarbeiter entfernen")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Button
|
||||||
|
// {
|
||||||
|
// id: mitarbeiterhin
|
||||||
|
// text: qsTr("Mitarbeiter hinzufügen")
|
||||||
|
// onClicked:
|
||||||
|
// {
|
||||||
|
// var nm = Qt.createComponent("AddObjectEmployee.qml")
|
||||||
|
// if (nm.status === Component.Ready)
|
||||||
|
// {
|
||||||
|
// employeeForm = nm.createObject (appWindow, {width: 600, height: 400})
|
||||||
|
// employeeForm.addNewEmployee.connect(onAddEmployee)
|
||||||
|
// employeeForm.show()
|
||||||
|
// }
|
||||||
|
// else console.log(nm.errorString())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// function onAddEmployee(new_employee)
|
||||||
|
// {
|
||||||
|
// var num_employees = 0
|
||||||
|
|
||||||
|
// if (employees === null || employees === undefined) employees = {}
|
||||||
|
// else num_employees = Object.keys(employees).length;
|
||||||
|
|
||||||
|
// employees[num_employees] = {}
|
||||||
|
// employees[num_employees]["assignee"] = new_employee["assignee"];
|
||||||
|
// employees[num_employees]["duration"] = new_employee["duration"];
|
||||||
|
// employees[num_employees]["wage"] = new_employee["wage"];
|
||||||
|
// employees[num_employees]["cleandays"] = new_employee["cleandays"];
|
||||||
|
// employees[num_employees]["tasks"] = new_employee["tasks"];
|
||||||
|
// employees[num_employees]["output"] = new_employee["output"];
|
||||||
|
|
||||||
|
// employeeModel.append({namens: new_employee["assignee"]});
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
28
Gui/ObjectAddOns.qml
Normal file
28
Gui/ObjectAddOns.qml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import "../js/qmldict.js" as JsLib
|
||||||
|
|
||||||
|
Frame
|
||||||
|
{
|
||||||
|
property alias contactPerson: oaocontactperson
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
id: addObjectLayout
|
||||||
|
width: parent.width
|
||||||
|
ObjectAddOnContactPerson
|
||||||
|
{
|
||||||
|
id: oaocontactperson
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getForm()
|
||||||
|
{
|
||||||
|
return oaocontactperson.contacts
|
||||||
|
}
|
||||||
|
}
|
||||||
27
Gui/ObjectDetails.qml
Normal file
27
Gui/ObjectDetails.qml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
property int selectedObject: -1
|
||||||
|
id: obDet
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ausgewählter Objekt " + selectedObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Zurück zu den Objekten")
|
||||||
|
onClicked: contentStack.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
object_model.onRowClicked(selectedObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
238
Gui/ObjectView.qml
Normal file
238
Gui/ObjectView.qml
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: objectView
|
||||||
|
|
||||||
|
columns: 4
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
rowSpacing: 9
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Firma")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "business"
|
||||||
|
id: business
|
||||||
|
editable: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Straße*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "street"
|
||||||
|
id: street
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Nr.*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "houseno"
|
||||||
|
id: houseno
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("PLZ*")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "postcode"
|
||||||
|
id: postcode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onTextChanged: checkFields()
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Ort")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "city"
|
||||||
|
id: city
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: true
|
||||||
|
onEditTextChanged: checkFields()
|
||||||
|
onCurrentTextChanged: checkFields()
|
||||||
|
model: address_model
|
||||||
|
textRole: "city"
|
||||||
|
popup.height: 300
|
||||||
|
currentIndex: -1
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Lohnanteil inkl. Fahrtkosten")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: lohnanteil
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Materialanteil")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: materialanteil
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Zusatz 1")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: zusatz1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Zusatz 2")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: zusatz2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Gesamt Netto")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{id: gesamtnetto
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("MwSt")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: mwst
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Gesamt(Netto+MwSt)")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: gesamt
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Zahlungsziel")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
}
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
property string name: "zahlungsziel"
|
||||||
|
id: zahlungsziel
|
||||||
|
Layout.fillWidth: true
|
||||||
|
editable: false
|
||||||
|
textRole: "display"
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Info")
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignTop
|
||||||
|
}
|
||||||
|
ScrollView
|
||||||
|
{
|
||||||
|
id: infoview
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 110
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
ScrollBar.horizontal: ScrollBar
|
||||||
|
{
|
||||||
|
policy: ScrollBar.AlwaysOn
|
||||||
|
}
|
||||||
|
|
||||||
|
TextArea
|
||||||
|
{
|
||||||
|
id: objectInfo
|
||||||
|
property string name: "objectinfo"
|
||||||
|
implicitWidth: parent.width
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
color: objectInfo.palette.base
|
||||||
|
border.color: objectInfo.activeFocus? objectInfo.palette.highlight: objectInfo.palette.base
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
191
Gui/ObjectsTable.qml
Normal file
191
Gui/ObjectsTable.qml
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Qt.labs.qmlmodels
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
property var availableFilters: [""]
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
function viewCriterion(criterion)
|
||||||
|
{
|
||||||
|
business_model.viewCriterion(criterion.text);
|
||||||
|
}
|
||||||
|
function onObjectContactAdded(added)
|
||||||
|
{
|
||||||
|
console.log(added)
|
||||||
|
if (added) object_model.viewCriterion("")
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
contact_model.objectContactAdded.connect(onObjectContactAdded)
|
||||||
|
contentStack.pop()
|
||||||
|
}
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Dimensions.l
|
||||||
|
SearchBar
|
||||||
|
{
|
||||||
|
}
|
||||||
|
QuickFilter {
|
||||||
|
onSelectedChanged: (name) => {
|
||||||
|
business_model.viewCriterion(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
model: ListModel {
|
||||||
|
ListElement {
|
||||||
|
|
||||||
|
name: "Alle"
|
||||||
|
text: qsTr("Alle")
|
||||||
|
selected: true
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Interessent"
|
||||||
|
text: qsTr("Interessent")
|
||||||
|
selected: false
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Kunde"
|
||||||
|
text: qsTr("Kunde")
|
||||||
|
selected: false
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Lieferant"
|
||||||
|
text: qsTr("Lieferant")
|
||||||
|
selected: false
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Erledigt"
|
||||||
|
text: qsTr("Erledigt")
|
||||||
|
selected: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: addObjectBtn
|
||||||
|
icon.source: "qrc:/images/PlusCircle.svg"
|
||||||
|
text: qsTr("Objekt Hinzufügen")
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
onClicked: contentStack.push("AddObject.qml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
id: tableColumn
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.verticalStretchFactor: 1
|
||||||
|
clip: true
|
||||||
|
// anchors
|
||||||
|
// {
|
||||||
|
// top: searchBar.bottom
|
||||||
|
// bottom: parent.bottom
|
||||||
|
// left: parent.left
|
||||||
|
// right: parent.right
|
||||||
|
// topMargin: 15
|
||||||
|
// }
|
||||||
|
HorizontalHeaderView
|
||||||
|
{
|
||||||
|
id: horizontalHeaderview
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: 40
|
||||||
|
movableColumns: true //@disable-check M16
|
||||||
|
syncView: objectTable
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
color: addObjectBtn.palette.alternateBase
|
||||||
|
border.color: addObjectBtn.palette.base
|
||||||
|
implicitHeight: 40
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitWidth: 1
|
||||||
|
Text
|
||||||
|
{
|
||||||
|
text: model.display
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: addObjectBtn.palette.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TableView
|
||||||
|
{
|
||||||
|
property real newWidth: 0
|
||||||
|
id: objectTable
|
||||||
|
z: 1
|
||||||
|
// height: tableColumn.height - horizontalHeaderview.height
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
columnSpacing: 1
|
||||||
|
rowSpacing: 2
|
||||||
|
model: object_model
|
||||||
|
alternatingRows: true
|
||||||
|
resizableColumns: true // @disable-check M16
|
||||||
|
selectionBehavior: TableView.SelectRows
|
||||||
|
ScrollBar.vertical: ScrollBar
|
||||||
|
{
|
||||||
|
policy: objectTable.contentHeight > objectTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
||||||
|
}
|
||||||
|
selectionModel: ItemSelectionModel
|
||||||
|
{
|
||||||
|
id: obmodel
|
||||||
|
model: objectTable.model
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate:Rectangle
|
||||||
|
{
|
||||||
|
required property bool selected
|
||||||
|
required property bool current
|
||||||
|
implicitWidth: objectTable.width / objectTable.columns
|
||||||
|
implicitHeight: 25
|
||||||
|
color: selected
|
||||||
|
? addObjectBtn.palette.highlight //palette.highlight
|
||||||
|
: (objectTable.alternatingRows && row % 2 !== 0
|
||||||
|
? addObjectBtn.palette.base // palette.base
|
||||||
|
: addObjectBtn.palette.alternateBase) //palette.alternateBase)
|
||||||
|
|
||||||
|
Text
|
||||||
|
{
|
||||||
|
text: (model.display === null || model.display === undefined)? "": model.display
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
leftPadding: 9 //@d isable-check M16
|
||||||
|
color: addObjectBtn.palette.text
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
property bool hovered: false
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onDoubleClicked:
|
||||||
|
{
|
||||||
|
contentStack.push("ObjectDetails.qml", {selectedObject: row});
|
||||||
|
}
|
||||||
|
onEntered:
|
||||||
|
{
|
||||||
|
objectTable.selectionModel.select(objectTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
66
Gui/OffersTable.qml
Normal file
66
Gui/OffersTable.qml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Qt.labs.qmlmodels
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
function viewOffers(criterion) {
|
||||||
|
//offer_model.viewCriterion(criterion)
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Dimensions.l
|
||||||
|
|
||||||
|
SearchBar {
|
||||||
|
id: searchBar
|
||||||
|
|
||||||
|
}
|
||||||
|
QuickFilter {
|
||||||
|
model: ListModel {
|
||||||
|
ListElement {
|
||||||
|
name: "Alle"
|
||||||
|
selected: true
|
||||||
|
text: qsTr("Alle")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Offen"
|
||||||
|
selected: false
|
||||||
|
text: qsTr("Offen")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Abgeschlossen"
|
||||||
|
selected: false
|
||||||
|
text: qsTr("Abgeschlossen")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Erledigt"
|
||||||
|
selected: false
|
||||||
|
text: qsTr("Erledigt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectedChanged: name => {
|
||||||
|
business_model.viewCriterion(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: addOfferBtn
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
flat: true
|
||||||
|
icon.source: "qrc:/images/PlusCircle.svg"
|
||||||
|
text: qsTr("Angebote Hinzufügen")
|
||||||
|
|
||||||
|
onClicked: contentStack.push("AddOffer.qml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: spacer
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
143
Gui/PrinterDialog.qml
Normal file
143
Gui/PrinterDialog.qml
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Window
|
||||||
|
{
|
||||||
|
property alias printerDialog: printDialog
|
||||||
|
property var printers: null
|
||||||
|
|
||||||
|
id: printDialog
|
||||||
|
title: qsTr("PYQCRM - Drucker")
|
||||||
|
color: palette.base
|
||||||
|
minimumWidth: 300
|
||||||
|
maximumWidth: 600
|
||||||
|
minimumHeight: 150
|
||||||
|
maximumHeight: 150
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
spacing: 9
|
||||||
|
y: 15
|
||||||
|
implicitWidth: parent.width
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 5
|
||||||
|
Layout.rightMargin: 5
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: printersLabel
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Drucker")
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox
|
||||||
|
{
|
||||||
|
id: allPrinters
|
||||||
|
model: printers
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.leftMargin: 5
|
||||||
|
Layout.rightMargin: 5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
Layout.minimumWidth: printersLabel.width
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("Kopie")
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinBox
|
||||||
|
{
|
||||||
|
id: copiesSpinBox
|
||||||
|
from: 1
|
||||||
|
to: 10
|
||||||
|
value: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.leftMargin: 5
|
||||||
|
Layout.rightMargin: 5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
CheckBox
|
||||||
|
{
|
||||||
|
id: colorPrint
|
||||||
|
text: qsTr("Farbe")
|
||||||
|
Layout.minimumWidth: printersLabel.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
Layout.leftMargin: 5
|
||||||
|
Layout.rightMargin: 5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: printButton
|
||||||
|
text: qsTr("Drucken")
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
var copies = copiesSpinBox.value > 1? copiesSpinBox.value + " copies": "one copy"
|
||||||
|
console.log("Printing ", copies, " using ", allPrinters.currentText);
|
||||||
|
printDialog.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Ablehnen")
|
||||||
|
onClicked: printDialog.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged:
|
||||||
|
{
|
||||||
|
copiesSpinBox.value = 1
|
||||||
|
colorPrint.checked = true
|
||||||
|
if (!sys_printers)
|
||||||
|
{
|
||||||
|
printers = sys_printers.getPrinters()
|
||||||
|
if (sys_printers.getDefaultPrinter())
|
||||||
|
allPrinters.currentIndex = allPrinters.indexOfValue(sys_printers.getDefaultPrinter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
if (sys_printers)
|
||||||
|
{
|
||||||
|
printers = sys_printers.getPrinters()
|
||||||
|
if (sys_printers.getDefaultPrinter())
|
||||||
|
allPrinters.currentIndex = allPrinters.indexOfValue(sys_printers.getDefaultPrinter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
171
Gui/PyqcrmConf.qml
Normal file
171
Gui/PyqcrmConf.qml
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
property alias companyConf: companyConf
|
||||||
|
property alias miscConf: miscConf
|
||||||
|
anchors.fill: parent
|
||||||
|
TabBar
|
||||||
|
{
|
||||||
|
id: bar
|
||||||
|
width: parent.width
|
||||||
|
TabButton
|
||||||
|
{
|
||||||
|
text: qsTr("Benutzer")
|
||||||
|
}
|
||||||
|
TabButton
|
||||||
|
{
|
||||||
|
text: qsTr("Datenbank")
|
||||||
|
}
|
||||||
|
TabButton
|
||||||
|
{
|
||||||
|
text: qsTr("Das Unternehmen")
|
||||||
|
}
|
||||||
|
|
||||||
|
TabButton
|
||||||
|
{
|
||||||
|
text: qsTr("Sicherung")
|
||||||
|
}
|
||||||
|
|
||||||
|
TabButton
|
||||||
|
{
|
||||||
|
text: qsTr("Sonstiges")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StackLayout
|
||||||
|
{
|
||||||
|
id: confContainer
|
||||||
|
anchors.fill: parent
|
||||||
|
currentIndex: bar.currentIndex
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: userTab
|
||||||
|
UsersPage
|
||||||
|
{
|
||||||
|
id: usersPage
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: dbTab
|
||||||
|
DbConfiguration
|
||||||
|
{
|
||||||
|
id: dbConf
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: companyTab
|
||||||
|
CompanyConf
|
||||||
|
{
|
||||||
|
id: companyConf
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: backup
|
||||||
|
BackupSettings
|
||||||
|
{
|
||||||
|
id: backupSettings
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: miscelanea
|
||||||
|
MiscConf
|
||||||
|
{
|
||||||
|
id: miscConf
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Ablehnen")
|
||||||
|
onClicked: contentStack.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: qsTr("Speichern")
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
switch (confContainer.currentIndex)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
updateDbConf()
|
||||||
|
break
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
updateCompanyInfo()
|
||||||
|
break
|
||||||
|
case 4:
|
||||||
|
updateMiscConf()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
console.log("Need to handle users")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDbConf()
|
||||||
|
{
|
||||||
|
var db = {}
|
||||||
|
db['database'] = {}
|
||||||
|
db['database']['DB_HOST'] = dbConf.dbHost.text.trim()
|
||||||
|
db['database']['DB_PORT'] = dbConf.dbPort.text.trim()
|
||||||
|
db['database']['DB_NAME'] = dbConf.dbName.text.trim()
|
||||||
|
db['database']['DB_USER'] = dbConf.dbUserName.text.trim()
|
||||||
|
db['database']['DB_PASS'] = dbConf.dbPassword.text.trim()
|
||||||
|
|
||||||
|
|
||||||
|
if (db['database']['DB_HOST'] === '' || db['database']['DB_PORT'] === '' ||
|
||||||
|
db['database']['DB_NAME'] === '' || db['database']['DB_USER'] === '' ||
|
||||||
|
db['database']['DB_PASS'] === '');
|
||||||
|
else config.saveDbConf(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCompanyInfo()
|
||||||
|
{
|
||||||
|
var company = {}
|
||||||
|
company['company'] = {}
|
||||||
|
company['company']['NAME'] = companyConf.name.text.trim()
|
||||||
|
company['company']['STREET'] = companyConf.street.text.trim()
|
||||||
|
company['company']['HOUSE'] = companyConf.house.text.trim()
|
||||||
|
company['company']['ZIPCODE'] = companyConf.zipcode.editText? companyConf.zipcode.editText.trim(): companyConf.zipcode.currentText
|
||||||
|
company['company']['CITY'] = companyConf.city.editText? companyConf.city.editText.trim(): companyConf.city.currentText
|
||||||
|
|
||||||
|
if (company['company']['NAME'] === '' || company['company']['STREET'] === '' ||
|
||||||
|
company['company']['HOUSE'] === '' || company['company']['ZIPCODE'] === '' ||
|
||||||
|
company['company']['CITY'] === '');
|
||||||
|
else config.saveCompanyInfo(company)
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMiscConf()
|
||||||
|
{
|
||||||
|
var misc = {}
|
||||||
|
misc['misc'] = {}
|
||||||
|
misc['misc']['SYSTRAY'] = miscConf.sysTray.checked
|
||||||
|
config.saveMiscConf(misc)
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Gui/ReadMe.qml
Normal file
47
Gui/ReadMe.qml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Window
|
||||||
|
{
|
||||||
|
property alias readMeWin: readMeWin
|
||||||
|
id: readMeWin
|
||||||
|
width: 400
|
||||||
|
height: 300
|
||||||
|
title: "PYQCRM - README"
|
||||||
|
color: palette.base
|
||||||
|
|
||||||
|
ScrollView
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
TextArea
|
||||||
|
{
|
||||||
|
id: readMe
|
||||||
|
anchors.fill: parent
|
||||||
|
readOnly: true
|
||||||
|
wrapMode: TextArea.Wrap
|
||||||
|
color: "darksalmon"
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
var filePath = "qrc:/README";
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", filePath, true);
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (xhr.readyState === XMLHttpRequest.DONE)
|
||||||
|
{
|
||||||
|
if (xhr.status === 200)
|
||||||
|
{
|
||||||
|
readMe.text = xhr.responseText;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
readMe.text = qsTr("Datei nicht gefunden!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
Gui/UsersPage.qml
Normal file
17
Gui/UsersPage.qml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
property string name: "users"
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Benutzer-Verwaltung")
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pixelSize: 57
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
}
|
||||||
208
Gui/UtilityDialogs.qml
Normal file
208
Gui/UtilityDialogs.qml
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import QtCore
|
||||||
|
import "../js/qmldict.js" as JsLib
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: utilityDialogs
|
||||||
|
property alias backup_config: backupConfig
|
||||||
|
property alias backup_encrypt_pw: recoveryPasswordDialog
|
||||||
|
|
||||||
|
property var recpass
|
||||||
|
property var configpass
|
||||||
|
Dialog
|
||||||
|
{
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
id: backupConfig
|
||||||
|
title: "Backup Config"
|
||||||
|
standardButtons: Dialog.Apply | Dialog.Cancel
|
||||||
|
|
||||||
|
onApplied:
|
||||||
|
{
|
||||||
|
|
||||||
|
if (configPwd.text === repeatConfigPwd.text)
|
||||||
|
{
|
||||||
|
configpass = repeatConfigPwd.text
|
||||||
|
saveConfigFile.open()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
configPwd.text = ""
|
||||||
|
configPwd.placeholderText = qsTr("Passwort stimmt nicht überein")
|
||||||
|
configPwd.placeholderTextColor = "red"
|
||||||
|
repeatConfigPwd.placeholderText = qsTr("")
|
||||||
|
repeatConfigPwd.text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onRejected: resetRecoveryConfigDialog()
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
id: gridPw
|
||||||
|
columns: 2
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Passwort eingeben")
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
|
||||||
|
id: configPwd
|
||||||
|
placeholderText: qsTr("Sicherungspasswort festlegen")
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
implicitWidth: 300
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Passwort wiederholen")
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
property string name: "password"
|
||||||
|
id: repeatConfigPwd
|
||||||
|
placeholderText: qsTr("Sicherungspasswort wiederholen")
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
implicitWidth: 300
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDialog
|
||||||
|
{
|
||||||
|
id: saveConfigFile
|
||||||
|
fileMode: FileDialog.SaveFile
|
||||||
|
nameFilters: ["PYQCRM Recovery files (*.pyqrec)"]
|
||||||
|
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
|
||||||
|
onAccepted:
|
||||||
|
{
|
||||||
|
config.backupConfig(saveConfigFile.currentFile, configpass)
|
||||||
|
}
|
||||||
|
onRejected:
|
||||||
|
{
|
||||||
|
backupConfig.close()
|
||||||
|
resetRecoveryConfigDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageDialog
|
||||||
|
{
|
||||||
|
id: recoveryDialog
|
||||||
|
|
||||||
|
text: qsTr("Diesen Wiederherstellungscode musst du sicher aufbewahren!\nMöchtest du das jetzt machen?")
|
||||||
|
title: qsTr("Wiederherstellen")
|
||||||
|
buttons: MessageDialog.Yes | MessageDialog.No
|
||||||
|
onAccepted: recoveryPasswordDialog.open()
|
||||||
|
onRejected: contentStack.replace("LoginSreen.qml")
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageDialog
|
||||||
|
{
|
||||||
|
id: conErrDialog
|
||||||
|
text: qsTr("Datenbankverbindung fehlgeschlagen")
|
||||||
|
title: qsTr("Datenbank Verbindung")
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog
|
||||||
|
{
|
||||||
|
|
||||||
|
id: recoveryPasswordDialog
|
||||||
|
modal: true
|
||||||
|
title: qsTr("Wiederherstellung")
|
||||||
|
anchors.centerIn: parent
|
||||||
|
standardButtons: Dialog.Apply | Dialog.Cancel
|
||||||
|
onApplied:
|
||||||
|
{
|
||||||
|
if (recoveryPasswordInput.text === repeatRecoveryPasswordInput.text)
|
||||||
|
{
|
||||||
|
recpass = recoveryPasswordInput.text
|
||||||
|
saveRecoveryDialog.open()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
recoveryPasswordInput.text = ""
|
||||||
|
recoveryPasswordInput.placeholderText = qsTr("Passwort stimmt nicht überein")
|
||||||
|
recoveryPasswordInput.placeholderTextColor = "red"
|
||||||
|
repeatRecoveryPasswordInput.placeholderText = qsTr("")
|
||||||
|
repeatRecoveryPasswordInput.text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: resetRecoveryPwDialog()
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
GridLayout
|
||||||
|
{
|
||||||
|
columns: 2
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Wiederherstellungspasswort festlegen: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: recoveryPasswordInput
|
||||||
|
text: ""
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
implicitWidth: 300
|
||||||
|
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: qsTr("Wiederherstellungspasswort wiederholen: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: repeatRecoveryPasswordInput
|
||||||
|
text: ""
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
implicitWidth: 300
|
||||||
|
placeholderText: qsTr("Hier Wiederherstellungspasswort wiederholen")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDialog
|
||||||
|
{
|
||||||
|
id: saveRecoveryDialog
|
||||||
|
title: qsTr("Wiederherstellungsdatei")
|
||||||
|
fileMode: FileDialog.SaveFile
|
||||||
|
nameFilters: ["PYQCRM Recovery files (*.pyqrec)"]
|
||||||
|
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
|
||||||
|
onAccepted:
|
||||||
|
{
|
||||||
|
config.backupEncryptkey(saveRecoveryDialog.currentFile, recpass)
|
||||||
|
}
|
||||||
|
|
||||||
|
onRejected:
|
||||||
|
{
|
||||||
|
recoveryPasswordDialog.close()
|
||||||
|
resetRecoveryPwDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetRecoveryPwDialog()
|
||||||
|
{
|
||||||
|
recoveryPasswordInput.text = ""
|
||||||
|
recoveryPasswordInput.placeholderText = qsTr("Hier Wiederherstellungspasswort eingeben")
|
||||||
|
recoveryPasswordInput.placeholderTextColor = repeatRecoveryPasswordInput.placeholderTextColor
|
||||||
|
repeatRecoveryPasswordInput.text = ""
|
||||||
|
repeatRecoveryPasswordInput.placeholderText = qsTr("Hier Wiederherstellungspasswort wiederholen")
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetRecoveryConfigDialog()
|
||||||
|
{
|
||||||
|
configPwd.text = ""
|
||||||
|
configPwd.placeholderText = qsTr("Hier Wiederherstellungspasswort eingeben")
|
||||||
|
configPwd.placeholderTextColor = repeatConfigPwd.placeholderTextColor
|
||||||
|
repeatConfigPwd.text = ""
|
||||||
|
repeatConfigPwd.placeholderText = qsTr("Hier Wiederherstellungspasswort wiederholen")
|
||||||
|
}
|
||||||
|
}
|
||||||
145
Gui/main.qml
Normal file
145
Gui/main.qml
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import QtCore
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
id: appWindow
|
||||||
|
|
||||||
|
property string confile: ""
|
||||||
|
property alias settingsFileDialog: settingsFiledialog
|
||||||
|
|
||||||
|
function showWindow(why) {
|
||||||
|
if (why === 3) {
|
||||||
|
systray.setVisible(false);
|
||||||
|
appWindow.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
font: Typography.body
|
||||||
|
height: Screen.height * .85
|
||||||
|
palette.window: Colors.mantle
|
||||||
|
palette.placeholderText: Colors.interactive
|
||||||
|
palette.text: Colors.foreground
|
||||||
|
title: "TERO Personal"
|
||||||
|
visible: true
|
||||||
|
width: Screen.width * .75
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
systray.activated.connect(showWindow);
|
||||||
|
|
||||||
|
if (bad_config) {
|
||||||
|
importDialog.open();
|
||||||
|
} else {
|
||||||
|
if (db_con)
|
||||||
|
contentStack.replace("LoginScreen.qml")
|
||||||
|
else
|
||||||
|
contentStack.replace("NoDbConnection.qml");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClosing: close => {
|
||||||
|
if (false) {
|
||||||
|
console.log("Main window closed!! Was soll ich tun? kann ich mich beenden?!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onVisibilityChanged: {
|
||||||
|
if (appWindow.visibility === Window.Minimized && config.systray()) {
|
||||||
|
systray.setVisible(true);
|
||||||
|
appWindow.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onWindowStateChanged: windowState => {
|
||||||
|
if (windowState !== Qt.WindowMinimized) {
|
||||||
|
systray.setVisible(false);
|
||||||
|
appWindow.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigation {
|
||||||
|
id: navigation
|
||||||
|
|
||||||
|
visible: !(bad_config || !db_con)
|
||||||
|
}
|
||||||
|
PrinterDialog {
|
||||||
|
id: printerDialog
|
||||||
|
|
||||||
|
}
|
||||||
|
ReadMe {
|
||||||
|
id: readMeWin
|
||||||
|
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: mainView
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: contentBackground
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: navigation.visible ? navigation.right : parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
color: Colors.background
|
||||||
|
}
|
||||||
|
|
||||||
|
StackView {
|
||||||
|
id: contentStack
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
fill: contentBackground
|
||||||
|
margins: Dimensions.l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: importDialog
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
modal: true
|
||||||
|
standardButtons: Dialog.Yes | Dialog.No
|
||||||
|
title: qsTr("Einstellungen importieren")
|
||||||
|
|
||||||
|
onAccepted: settingsFiledialog.open()
|
||||||
|
onRejected: contentStack.replace("Firststart.qml")
|
||||||
|
}
|
||||||
|
FileDialog {
|
||||||
|
id: settingsFiledialog
|
||||||
|
|
||||||
|
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
|
||||||
|
modality: "ApplicationModal"
|
||||||
|
nameFilters: [qsTr("PYQCRM Einstellungen (*.pyqrec)")]
|
||||||
|
title: qsTr("PYQCRM Einstellungen")
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
exportFilePassword.open();
|
||||||
|
confile = selectedFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Dialog {
|
||||||
|
id: exportFilePassword
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
modal: true
|
||||||
|
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||||
|
title: qsTr("PYQCRM Einstellungen")
|
||||||
|
|
||||||
|
onAccepted: config.importConfig(confile, exportPasswordInput.text)
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
RowLayout {
|
||||||
|
Label {
|
||||||
|
text: qsTr("Passwort eingeben:")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: exportPasswordInput
|
||||||
|
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
implicitWidth: 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Gui/qmldir
Normal file
2
Gui/qmldir
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
module gui
|
||||||
|
Navigation 1.0 Navigation.qml
|
||||||
138
Gui/test.qml
Normal file
138
Gui/test.qml
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Qt.labs.qmlmodels
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TableView
|
||||||
|
{
|
||||||
|
id: testTable
|
||||||
|
anchors.fill: parent
|
||||||
|
columnSpacing: 10
|
||||||
|
rowSpacing: 2
|
||||||
|
//boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
model: TableModel
|
||||||
|
{
|
||||||
|
TableModelColumn { display: "checked" }
|
||||||
|
TableModelColumn { display: "amount" }
|
||||||
|
TableModelColumn { display: "fruitType" }
|
||||||
|
TableModelColumn { display: "fruitName" }
|
||||||
|
TableModelColumn { display: "fruitPrice" }
|
||||||
|
|
||||||
|
|
||||||
|
rows:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
checked: "checked",
|
||||||
|
amount: "amount",
|
||||||
|
fruitType: "Fruittype",
|
||||||
|
fruitName: "fruitName",
|
||||||
|
fruitPrice: "Price"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
checked: true,
|
||||||
|
amount: 2,
|
||||||
|
fruitType: "Fruittype",
|
||||||
|
fruitName: "blabla",
|
||||||
|
fruitPrice: 1.50
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
checked: true,
|
||||||
|
amount: 1,
|
||||||
|
fruitType: "Apple",
|
||||||
|
fruitName: "Granny Smith",
|
||||||
|
fruitPrice: 1.50
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
checked: "true",
|
||||||
|
amount: 4,
|
||||||
|
fruitType: "Orange",
|
||||||
|
fruitName: "Navel",
|
||||||
|
fruitPrice: 2.50
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
checked: "false",
|
||||||
|
amount: 1,
|
||||||
|
fruitType: "Banana",
|
||||||
|
fruitName: "Cavendish",
|
||||||
|
fruitPrice: 3.50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: DelegateChooser
|
||||||
|
{
|
||||||
|
DelegateChoice
|
||||||
|
{
|
||||||
|
column: 0
|
||||||
|
delegate: Text
|
||||||
|
{
|
||||||
|
|
||||||
|
text: model.display
|
||||||
|
//selectByMouse: true
|
||||||
|
//implicitWidth: 140
|
||||||
|
//onVisibleChanged: model.display = "checked"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DelegateChoice
|
||||||
|
{
|
||||||
|
column: 1
|
||||||
|
delegate: Text
|
||||||
|
{
|
||||||
|
|
||||||
|
text: model.display
|
||||||
|
//selectByMouse: true
|
||||||
|
//implicitWidth: 140
|
||||||
|
//onVisibleChanged: model.display = "amount"
|
||||||
|
//onLinkHovered: model.display = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DelegateChoice
|
||||||
|
{
|
||||||
|
column: 2
|
||||||
|
delegate: Text
|
||||||
|
{
|
||||||
|
|
||||||
|
text: model.display
|
||||||
|
//selectByMouse: true
|
||||||
|
//implicitWidth: 140
|
||||||
|
//model.display : "fruitType"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DelegateChoice
|
||||||
|
{
|
||||||
|
column: 3
|
||||||
|
delegate: Text
|
||||||
|
{
|
||||||
|
|
||||||
|
text: model.display
|
||||||
|
//selectByMouse: true
|
||||||
|
//implicitWidth: 140
|
||||||
|
//onVisibleChanged: model.display = "fruitName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DelegateChoice
|
||||||
|
{
|
||||||
|
column: 4
|
||||||
|
delegate: Text
|
||||||
|
{
|
||||||
|
text: model.display
|
||||||
|
//selectByMouse: true
|
||||||
|
//implicitWidth: 140
|
||||||
|
//onVisibleChanged: model.display = "fruitPrice"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
54
README
Normal file
54
README
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
PYQCRM - Python QtQuick CRM System
|
||||||
|
|
||||||
|
Einleitung:
|
||||||
|
----------------
|
||||||
|
|
||||||
|
PYQCRM entstand als Teil einer Abschlusspraxis und dem Bedarf der TERO GmbH an einem Managementprogramm für den internen Gebrauch.
|
||||||
|
|
||||||
|
|
||||||
|
Erstellung:
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Das Program wurde mit den folgenen Techologien entwickelt:
|
||||||
|
|
||||||
|
- IDE: Qt-Creator 6.8.x
|
||||||
|
- Framework: QtQuick - QML 6.8.x
|
||||||
|
- Sprache: Python 3.13.x
|
||||||
|
- Datenbank: MariaDB 10.11.x
|
||||||
|
- Sonstiges: JavaScript
|
||||||
|
|
||||||
|
|
||||||
|
Installation:
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Möglicherweise ist für deine Plattform ein Installationspaket verfügbar. Prüfe es also zuerst.
|
||||||
|
|
||||||
|
Es gibt zwei möglichkeiten das Program zu verwenden:
|
||||||
|
|
||||||
|
Möglichkeit I:
|
||||||
|
|
||||||
|
1. Datenbank einrichten (MaraiDB SQL-Schema verfügbar)
|
||||||
|
2. Python installiert und eingerichtet
|
||||||
|
3. Das Program in einen bevorzugten Pfad kopieren.
|
||||||
|
4. Erstelle einen Link zum main.py-Skript und stelle ihn so ein, dass er mit deinem Python-Interpreter ausgeführt wird
|
||||||
|
|
||||||
|
Möglichkeit II:
|
||||||
|
|
||||||
|
1. Datenbank einrichten (MaraiDB SQL-Schema verfügbar)
|
||||||
|
2. Die ausführbare Version des Programs in einen bevorzugten Pfad kopieren
|
||||||
|
3. Erstelle einen Link zur ausführbaren Datei, die für dein System erstellt wurde (pyqcrm/pyqcrm.exe)
|
||||||
|
|
||||||
|
|
||||||
|
Kudos:
|
||||||
|
----------
|
||||||
|
|
||||||
|
Wenn dir dieses Kunstwerk gefällt, kannst du uns deine Wertschätzung einfach dadurch zeigen, dass du jedem von uns einen Bungalow, einen 760IL BMW, lebenslange Flugtickets inklusive Begleitung kaufst und als Geschenk ein paar Millionen Euro auf ein Schweizer Bankkonto überweist.
|
||||||
|
|
||||||
|
|
||||||
|
Team:
|
||||||
|
---------
|
||||||
|
|
||||||
|
Marcopolo
|
||||||
|
Schnacke
|
||||||
|
Renegade
|
||||||
|
|
||||||
61
TeroStyle/BarButton.qml
Normal file
61
TeroStyle/BarButton.qml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls.impl
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Templates as T
|
||||||
|
|
||||||
|
T.ToolButton {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
property string target
|
||||||
|
|
||||||
|
checkable: true
|
||||||
|
icon.color: Colors.foreground
|
||||||
|
icon.height: 36
|
||||||
|
icon.width: 36
|
||||||
|
implicitHeight: 90
|
||||||
|
implicitWidth: 100
|
||||||
|
topPadding: 20
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
readonly property color color: control.checked ? Colors.primaryShade : control.hovered ? Colors.primary : Colors.foreground
|
||||||
|
|
||||||
|
IconLabel {
|
||||||
|
color: parent.color
|
||||||
|
icon.color: parent.color
|
||||||
|
icon.height: control.icon.height
|
||||||
|
icon.source: control.icon.source
|
||||||
|
icon.width: control.icon.width
|
||||||
|
x: parent.width * .5 - width * .5
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
color: parent.color
|
||||||
|
font: Typography.smaller
|
||||||
|
text: control.text
|
||||||
|
x: parent.width * .5 - width * .5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
color: control.checked ? Colors.primaryShade : Colors.primary
|
||||||
|
implicitWidth: 6
|
||||||
|
visible: control.checked || control.hovered
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
|
onPressed: mouse => mouse.accepted = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if(!target) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
contentStack.replace(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
69
TeroStyle/Button.qml
Normal file
69
TeroStyle/Button.qml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls.impl as I
|
||||||
|
import QtQuick.Templates as T
|
||||||
|
|
||||||
|
T.Button {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set true when the button is supposed to be displayed in e.g. a TextField.
|
||||||
|
* You want to do this when this button is directly related to the TextField
|
||||||
|
* and the primary and only action for the TextField.
|
||||||
|
* Usually, you'd only want to display an icon in this button.
|
||||||
|
* If true, automatically sets height, width and position.
|
||||||
|
*
|
||||||
|
* ```qml
|
||||||
|
* TextField {
|
||||||
|
* placeholderText: "Search..."
|
||||||
|
* Button {
|
||||||
|
* icon.source: "qrc:/images/MagnifyingGlass.svg"
|
||||||
|
* isFieldButton: true
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
property bool isFieldButton: false
|
||||||
|
|
||||||
|
|
||||||
|
height: isFieldButton ? parent.height : null
|
||||||
|
icon.color: Colors.primaryContrast
|
||||||
|
icon.height: 21
|
||||||
|
icon.width: 21
|
||||||
|
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding)
|
||||||
|
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding)
|
||||||
|
/**
|
||||||
|
* Icon is slightly larger than Text, so we need to reduce the padding a
|
||||||
|
* tiny bit to make sure all Buttons are still the same height.
|
||||||
|
*/
|
||||||
|
padding: Dimensions.m - (icon.source.toString() === "" ? 0 : 1)
|
||||||
|
x: isFieldButton ? parent.x + parent.width - width : null
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
border.color: Colors.interactive
|
||||||
|
border.width: isFieldButton ? 1 : 0
|
||||||
|
bottomLeftRadius: topLeftRadius
|
||||||
|
color: !control.enabled ? Colors.disabled : !control.hovered ? Colors.primary : Colors.primaryLighter
|
||||||
|
radius: Dimensions.radius
|
||||||
|
topLeftRadius: isFieldButton ? 0 : radius
|
||||||
|
}
|
||||||
|
contentItem: I.IconLabel {
|
||||||
|
color: !control.enabled ? Colors.disabledForeground : Colors.primaryContrast
|
||||||
|
display: control.display
|
||||||
|
font: control.font
|
||||||
|
icon: control.icon
|
||||||
|
mirrored: control.mirrored
|
||||||
|
spacing: Dimensions.s
|
||||||
|
text: control.text
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
|
onPressed: mouse => mouse.accepted = false
|
||||||
|
}
|
||||||
|
}
|
||||||
26
TeroStyle/Colors.qml
Normal file
26
TeroStyle/Colors.qml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
readonly property int dark: 0
|
||||||
|
readonly property int light: 1
|
||||||
|
|
||||||
|
property int theme: Application.styleHints.colorScheme === Qt.ColorScheme.Light ? light : dark
|
||||||
|
|
||||||
|
readonly property color primary: "#b81a34"
|
||||||
|
readonly property color primaryContrast: "#fdfdfd"
|
||||||
|
readonly property color primaryLighter: Qt.lighter(primary, 1.5)
|
||||||
|
readonly property color primaryShade: theme === dark ? primaryLighter : Qt.darker(primary, 1.5)
|
||||||
|
readonly property color primaryHighlight: theme === dark ? Qt.darker(primary, 2- Colors.highlightOpacity) : Qt.lighter(primary, 2- Colors.highlightOpacity)
|
||||||
|
readonly property color foreground: theme === dark ? "#fdfdfd" : "#110b0c"
|
||||||
|
readonly property color background: theme === dark ? "#303136" : "#eff1f5"
|
||||||
|
readonly property color mantle: theme === dark ? "#1E1E23" : "#e7e9ef"
|
||||||
|
readonly property color interactive: theme === dark ? "#878b97" : "#d9d9da"
|
||||||
|
readonly property color error: theme === dark ? "#ff2264" : "#ff004b"
|
||||||
|
readonly property color disabled: theme === dark ? Qt.darker(interactive, 1.9) : Qt.darker(interactive, 1.3)
|
||||||
|
readonly property color disabledForeground: theme === dark ? Qt.darker(foreground, 1.4) : Qt.lighter(foreground, 1.9)
|
||||||
|
readonly property color transparent: "transparent"
|
||||||
|
|
||||||
|
readonly property double highlightOpacity: .3
|
||||||
|
}
|
||||||
108
TeroStyle/ComboBox.qml
Normal file
108
TeroStyle/ComboBox.qml
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Templates as T
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Controls.impl
|
||||||
|
|
||||||
|
T.ComboBox {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
font: Typography.body
|
||||||
|
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||||
|
implicitContentHeight + topPadding + bottomPadding,
|
||||||
|
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||||
|
|
||||||
|
|
||||||
|
contentItem: T.TextField {
|
||||||
|
id: test
|
||||||
|
autoScroll: control.editable
|
||||||
|
color: Colors.foreground
|
||||||
|
enabled: control.editable
|
||||||
|
|
||||||
|
font: Typography.body
|
||||||
|
implicitHeight: Typography.body.pixelSize + topPadding + bottomPadding
|
||||||
|
inputMethodHints: control.inputMethodHints
|
||||||
|
padding: Dimensions.m
|
||||||
|
readOnly: control.down
|
||||||
|
selectByMouse: control.selectTextByMouse
|
||||||
|
text: control.editable ? control.editText : control.displayText
|
||||||
|
validator: control.validator
|
||||||
|
width: control.width - indicator.width
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
background: Rectangle {
|
||||||
|
border.color: Colors.interactive
|
||||||
|
border.width: 1
|
||||||
|
color: Colors.mantle
|
||||||
|
radius: Dimensions.radius
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
required property var model
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
width: ListView.view.width
|
||||||
|
text: model[control.textRole]
|
||||||
|
highlighted: control.highlightedIndex === index
|
||||||
|
hoverEnabled: control.hoverEnabled
|
||||||
|
}
|
||||||
|
indicator: Rectangle {
|
||||||
|
id: indicator
|
||||||
|
|
||||||
|
border.color: Colors.interactive
|
||||||
|
bottomRightRadius: Dimensions.radius
|
||||||
|
color: Colors.primary
|
||||||
|
height: control.height
|
||||||
|
topRightRadius: Dimensions.radius
|
||||||
|
width: 20 + Dimensions.s * 2
|
||||||
|
x: control.width - width
|
||||||
|
y: 0
|
||||||
|
z: 2
|
||||||
|
|
||||||
|
IconLabel {
|
||||||
|
anchors.fill: parent
|
||||||
|
bottomPadding: Dimensions.s
|
||||||
|
icon.color: Colors.foreground
|
||||||
|
icon.source: "qrc:/images/ChevronDown.svg"
|
||||||
|
leftPadding: Dimensions.s
|
||||||
|
rightPadding: Dimensions.s
|
||||||
|
topPadding: Dimensions.s
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
|
onPressed: () => {
|
||||||
|
control.popup.visible = true;
|
||||||
|
control.popup.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
popup: T.Popup {
|
||||||
|
bottomMargin: 6
|
||||||
|
height: Math.min(contentItem.implicitHeight + 2, control.Window.height - topMargin - bottomMargin)
|
||||||
|
padding: 1
|
||||||
|
topMargin: 6
|
||||||
|
width: control.width
|
||||||
|
y: control.height
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
border.color: Colors.interactive
|
||||||
|
color: Colors.mantle
|
||||||
|
radius: Dimensions.radius
|
||||||
|
}
|
||||||
|
contentItem: ListView {
|
||||||
|
clip: true
|
||||||
|
currentIndex: control.highlightedIndex
|
||||||
|
implicitHeight: contentHeight
|
||||||
|
model: control.popup.visible ? control.delegateModel : null
|
||||||
|
|
||||||
|
T.ScrollBar.vertical: ScrollBar {
|
||||||
|
}
|
||||||
|
highlight: Rectangle {
|
||||||
|
color: Colors.primary
|
||||||
|
opacity: Colors.highlightOpacity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
TeroStyle/Dimensions.qml
Normal file
26
TeroStyle/Dimensions.qml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
QtObject
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Distance for objects that are tied to each other,
|
||||||
|
* e.g. a field and its label.
|
||||||
|
*/
|
||||||
|
readonly property int s: 9
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Distance for objects that are grouped together, e.g. radio buttons of the
|
||||||
|
* same radio group.
|
||||||
|
*/
|
||||||
|
readonly property int m: 15
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Distance for objects that are not related to each other, or to objects
|
||||||
|
* and their container.
|
||||||
|
*/
|
||||||
|
readonly property int l: 30
|
||||||
|
|
||||||
|
readonly property int radius: 4
|
||||||
|
}
|
||||||
5
TeroStyle/EmailAddressValidator.qml
Normal file
5
TeroStyle/EmailAddressValidator.qml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
RegularExpressionValidator {
|
||||||
|
regularExpression: /([\+!#$%&‘\*\–\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
|
||||||
|
}
|
||||||
20
TeroStyle/Field.qml
Normal file
20
TeroStyle/Field.qml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
required property string label
|
||||||
|
/**
|
||||||
|
* Adds an asterisk after the label, informing the user that this field
|
||||||
|
* is mandatory.
|
||||||
|
*/
|
||||||
|
property bool mandatory: false
|
||||||
|
spacing: Dimensions.s
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
text: label + (mandatory ? "*" : "")
|
||||||
|
font: Typography.body
|
||||||
|
}
|
||||||
|
}
|
||||||
5
TeroStyle/H1.qml
Normal file
5
TeroStyle/H1.qml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Text {
|
||||||
|
font: Typography.h1
|
||||||
|
}
|
||||||
5
TeroStyle/H2.qml
Normal file
5
TeroStyle/H2.qml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Text {
|
||||||
|
font: Typography.h2
|
||||||
|
}
|
||||||
5
TeroStyle/Label.qml
Normal file
5
TeroStyle/Label.qml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
Label {
|
||||||
|
color: Colors.foreground
|
||||||
|
}
|
||||||
5
TeroStyle/NotEmptyValidator.qml
Normal file
5
TeroStyle/NotEmptyValidator.qml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
RegularExpressionValidator {
|
||||||
|
regularExpression: /^\S+.*\S+$/
|
||||||
|
}
|
||||||
5
TeroStyle/OptionalEmailAddressValidator.qml
Normal file
5
TeroStyle/OptionalEmailAddressValidator.qml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
RegularExpressionValidator {
|
||||||
|
regularExpression: /^$|([\+!#$%&‘\*\–\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
|
||||||
|
}
|
||||||
5
TeroStyle/OptionalPhoneNumberValidator.qml
Normal file
5
TeroStyle/OptionalPhoneNumberValidator.qml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
RegularExpressionValidator {
|
||||||
|
regularExpression: /^$|([+0-9])([0-9\s]{1,17})/
|
||||||
|
}
|
||||||
5
TeroStyle/PhoneNumberValidator.qml
Normal file
5
TeroStyle/PhoneNumberValidator.qml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
RegularExpressionValidator {
|
||||||
|
regularExpression: /([+0-9])([0-9\s]{1,17})/
|
||||||
|
}
|
||||||
5
TeroStyle/PostcodeValidator.qml
Normal file
5
TeroStyle/PostcodeValidator.qml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
RegularExpressionValidator {
|
||||||
|
regularExpression: /([^$][0-9]{1,4})/
|
||||||
|
}
|
||||||
64
TeroStyle/QuickFilter.qml
Normal file
64
TeroStyle/QuickFilter.qml
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtCore
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property ListModel model
|
||||||
|
|
||||||
|
signal selectedChanged(string name)
|
||||||
|
|
||||||
|
spacing: Dimensions.m
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.model
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: item
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
required property var modelData
|
||||||
|
property bool hovered: false
|
||||||
|
property real padding: Dimensions.m
|
||||||
|
|
||||||
|
height: text.height + padding * 2
|
||||||
|
width: text.width + padding * 2
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
border.color: modelData.selected ? Colors.transparent : Colors.foreground
|
||||||
|
border.width: 2
|
||||||
|
color: modelData.selected || mouseArea.containsMouse ? Colors.primary : Colors.transparent
|
||||||
|
radius: parent.height
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
id: text
|
||||||
|
|
||||||
|
color: Colors.foreground
|
||||||
|
font: Typography.body
|
||||||
|
text: modelData.text
|
||||||
|
x: parent.padding
|
||||||
|
y: parent.padding
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
if (item.modelData.selected)
|
||||||
|
return;
|
||||||
|
const model = root.model;
|
||||||
|
for (let i = 0; i < model.count; i++) {
|
||||||
|
model.setProperty(i, "selected", false);
|
||||||
|
}
|
||||||
|
model.setProperty(item.index, "selected", true);
|
||||||
|
selectedChanged(item.modelData.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
TeroStyle/SearchBar.qml
Normal file
26
TeroStyle/SearchBar.qml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: field
|
||||||
|
|
||||||
|
signal submitted(query: string)
|
||||||
|
|
||||||
|
Layout.preferredWidth: 300
|
||||||
|
placeholderText: qsTr("Suche")
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
field.submitted(field.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
icon.source: "qrc:/images/MagnifyingGlass.svg"
|
||||||
|
isFieldButton: true
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
field.submitted(field.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
TeroStyle/TextField.qml
Normal file
47
TeroStyle/TextField.qml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Templates as T
|
||||||
|
|
||||||
|
T.TextField
|
||||||
|
{
|
||||||
|
id: control
|
||||||
|
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
id: background
|
||||||
|
color: Colors.mantle
|
||||||
|
radius: Dimensions.radius
|
||||||
|
border.width: !control.focus ? 1 : 2
|
||||||
|
border.color: Colors.interactive
|
||||||
|
height: control.implicitHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
color: Colors.foreground
|
||||||
|
implicitHeight: Typography.body.pixelSize + topPadding + bottomPadding
|
||||||
|
placeholderTextColor: Colors.interactive
|
||||||
|
font: Typography.body
|
||||||
|
padding: Dimensions.m
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Placeholder
|
||||||
|
*/
|
||||||
|
Text {
|
||||||
|
x: control.leftPadding
|
||||||
|
y: control.topPadding
|
||||||
|
width: control.width - (control.leftPadding + control.rightPadding)
|
||||||
|
height: control.height - (control.topPadding + control.bottomPadding)
|
||||||
|
|
||||||
|
font: control.font
|
||||||
|
text: control.placeholderText
|
||||||
|
color: control.placeholderTextColor
|
||||||
|
verticalAlignment: control.verticalAlignment
|
||||||
|
visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter)
|
||||||
|
elide: Text.ElideRight
|
||||||
|
renderType: control.renderType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
56
TeroStyle/Typography.qml
Normal file
56
TeroStyle/Typography.qml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtCore
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
readonly property font body: ({
|
||||||
|
family: robotoCondensed.font,
|
||||||
|
pointSize: 16,
|
||||||
|
weight: Font.Medium,
|
||||||
|
letterSpacing: 0,
|
||||||
|
kerning: true
|
||||||
|
})
|
||||||
|
|
||||||
|
readonly property font small: ({
|
||||||
|
family: body.family,
|
||||||
|
pointSize: 14,
|
||||||
|
weight: Font.Medium,
|
||||||
|
letterSpacing: body.letterSpacing,
|
||||||
|
kerning: body.kerning
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
readonly property font smallBold: ({
|
||||||
|
family: small.family,
|
||||||
|
pointSize: small.pointSize,
|
||||||
|
weight: Font.Bold,
|
||||||
|
letterSpacing: small.letterSpacing,
|
||||||
|
kerning: small.kerning
|
||||||
|
})
|
||||||
|
|
||||||
|
readonly property font smaller: ({
|
||||||
|
family: body.family,
|
||||||
|
pointSize: 11,
|
||||||
|
weight: Font.DemiBold,
|
||||||
|
letterSpacing: body.letterSpacing,
|
||||||
|
kerning: body.kerning
|
||||||
|
})
|
||||||
|
readonly property font h1: ({
|
||||||
|
family: body.family,
|
||||||
|
pointSize: 38,
|
||||||
|
weight: body.weight,
|
||||||
|
letterSpacing: body.letterSpacing,
|
||||||
|
kerning: body.kerning
|
||||||
|
})
|
||||||
|
readonly property font h2: ({
|
||||||
|
family: body.family,
|
||||||
|
pointSize: 28,
|
||||||
|
weight: body.weight,
|
||||||
|
letterSpacing: body.letterSpacing,
|
||||||
|
kerning: body.kerning,
|
||||||
|
})
|
||||||
|
readonly property FontLoader robotoCondensed: FontLoader {
|
||||||
|
source: "qrc:/fonts/RobotoCondensed.otf"
|
||||||
|
}
|
||||||
|
}
|
||||||
20
TeroStyle/qmldir
Normal file
20
TeroStyle/qmldir
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
module TeroStyle
|
||||||
|
singleton Colors Colors.qml
|
||||||
|
singleton Dimensions Dimensions.qml
|
||||||
|
singleton Typography Typography.qml
|
||||||
|
BarButton BarButton.qml
|
||||||
|
Button Button.qml
|
||||||
|
ComboBox ComboBox.qml
|
||||||
|
EmailAddressValidator EmailAddressValidator.qml
|
||||||
|
Field Field.qml
|
||||||
|
H1 H1.qml
|
||||||
|
H2 H2.qml
|
||||||
|
Label Label.qml
|
||||||
|
NotEmptyValidator NotEmptyValidator.qml
|
||||||
|
OptionalEmailAddressValidator OptionalEmailAddressValidator.qml
|
||||||
|
PhoneNumberValidator PhoneNumberValidator.qml
|
||||||
|
OptionalPhoneNumberValidator OptionalPhoneNumberValidator.qml
|
||||||
|
PostcodeValidator PostcodeValidator.qml
|
||||||
|
QuickFilter QuickFilter.qml
|
||||||
|
SearchBar SearchBar.qml
|
||||||
|
TextField TextField.qml
|
||||||
88
Tero_CRM_Reinigungsunternehmen.txt
Normal file
88
Tero_CRM_Reinigungsunternehmen.txt
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
CRM für Objektbetreuung Reinigungsservice
|
||||||
|
|
||||||
|
|
||||||
|
Minimal Voraussetzung:
|
||||||
|
|
||||||
|
|
||||||
|
Mitarbeiter
|
||||||
|
- Dokumenten Management System (DMS)
|
||||||
|
- Arbeitszeitdokumentation
|
||||||
|
- Urlaubsplaner
|
||||||
|
- Arbeitnehmer anlegen
|
||||||
|
|
||||||
|
Nice To Have:
|
||||||
|
- WhatsApp
|
||||||
|
- Telefon
|
||||||
|
- Social Media Uploader
|
||||||
|
Dokumentenvorlagen
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Kunden
|
||||||
|
- Kunden anlegen (Hausverwaltung Krefeld)
|
||||||
|
- Dokumenten Management System (DMS)
|
||||||
|
- Ansprechpartner anlegen
|
||||||
|
RG auch in CC Funktion
|
||||||
|
|
||||||
|
Nice To Have:
|
||||||
|
Dokumentenvorlagen
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Dashboard
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Abrechnung
|
||||||
|
- Rechnung schreiben (Zugferd Modus)
|
||||||
|
- Fixkostenerfassung
|
||||||
|
Rechnungsarchiv
|
||||||
|
Mahnfunktion
|
||||||
|
|
||||||
|
|
||||||
|
Objekt
|
||||||
|
- Objekt anlegen
|
||||||
|
- Ansprechpartner anlegen
|
||||||
|
- Dokumenten Management System (DMS)
|
||||||
|
Str. (Pflicht)
|
||||||
|
Hausnummer (Pflicht)
|
||||||
|
PLZ
|
||||||
|
Ort (Pflicht)
|
||||||
|
Parteien (Anzahl)
|
||||||
|
Stockwerke (Anzahl)
|
||||||
|
Zwischenetage (ja/nein)
|
||||||
|
Aufzug (ja/nein)
|
||||||
|
Fenster (ja/nein) anschließend Anzahl + ohne Leiter erreichbar (ja/nein)
|
||||||
|
Besonderheiten (Infofeld)
|
||||||
|
Kontaktdaten Hausmeister / Beirat
|
||||||
|
Reinigungsmittel zu finden? ( Wo ist es im Kellerraum, Dachgeschoss, 2 Tür von links?)
|
||||||
|
Foto Upload wäre toll ;-)
|
||||||
|
|
||||||
|
Leistungen
|
||||||
|
Treppenhausreinigung
|
||||||
|
Garten
|
||||||
|
siehe Homepage !!!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Angebot
|
||||||
|
|
||||||
|
|
||||||
|
Auftrag
|
||||||
|
- Arbeitsauftrag anlegen
|
||||||
|
Pflegehinweise zum Objekt
|
||||||
|
BG Sicherheitsdatenblätter
|
||||||
|
Reinigungsmittel erhalten am ?
|
||||||
|
Preis ab Datum
|
||||||
|
Objektkontrolle (Wann wurde das Objekt das letzte Mal kontrolliert?) Ähnlich wie Preis mit Datum
|
||||||
|
Preise
|
||||||
|
Schlüssel
|
||||||
|
|
||||||
|
|
||||||
|
Auswertung
|
||||||
|
Stundenkalender
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1
backup.pyqrec
Normal file
1
backup.pyqrec
Normal file
@@ -0,0 +1 @@
|
|||||||
|
zIgY4d8ORJ0HZpG7y8/XeS84mKHFcvNaMmCxdirT6ebjApHlo5XVXspy3ENIEvrZczSDRugR0sAVVt8StqZ2gGAr42tIwFF9Uwl7YBMi72+iGIkwyIGX/Jw3OiHYubkXEooZLYX1MYPOC91ppVnZG0PA0IYdpDofq5inFfxpPBwMdcJxvtZPLhIX2y7Fn3m1/lsWe+e2EBwDGxnZjUjPMsRFMjswBv20EOHk46OuNFwlDyn+w9ZDoJfhF6HKYqNxnBnN90KEUygTYGWk.nfaytDW7Z0Nn2/5d22/ciQ==
|
||||||
BIN
doc/DB-DAO-Model.moj
Normal file
BIN
doc/DB-DAO-Model.moj
Normal file
Binary file not shown.
BIN
doc/DB-DAO-Model.pdf
Normal file
BIN
doc/DB-DAO-Model.pdf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
doc/GUI-Mockups/GUI-AddCustomer.pdf
Normal file
BIN
doc/GUI-Mockups/GUI-AddCustomer.pdf
Normal file
Binary file not shown.
BIN
doc/GUI-Mockups/GUI-AddCustomer.rnote
Normal file
BIN
doc/GUI-Mockups/GUI-AddCustomer.rnote
Normal file
Binary file not shown.
BIN
doc/GUI-Mockups/GUI-AddEmployee_Applicant.pdf
Normal file
BIN
doc/GUI-Mockups/GUI-AddEmployee_Applicant.pdf
Normal file
Binary file not shown.
BIN
doc/GUI-Mockups/GUI-AddEmployee_Applicant.rnote
Normal file
BIN
doc/GUI-Mockups/GUI-AddEmployee_Applicant.rnote
Normal file
Binary file not shown.
BIN
doc/GUI-Mockups/GUI-AddObject.pdf
Normal file
BIN
doc/GUI-Mockups/GUI-AddObject.pdf
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user