3 Commits

Author SHA256 Message Date
857a8b6fa0 hallo 2024-12-16 08:57:25 +01:00
40d308d965 nochmal 2024-12-16 08:52:57 +01:00
e28c68f643 AddCustomer, AddContact finished 2024-12-15 20:44:44 +01:00
211 changed files with 7156 additions and 90320 deletions

3
.gitignore vendored
View File

@@ -210,7 +210,7 @@ dmypy.json
# pytype static type analyzer # pytype static type analyzer
.pytype/ .pytype/
.qtcreator/ .qtcreator/
*.pyproject.user* *.pyproject.user
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/
@@ -228,4 +228,3 @@ cython_debug/
rc_*.py rc_*.py
.DS_STORE

8
.idea/.gitignore generated vendored
View File

@@ -1,8 +0,0 @@
# 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
View File

@@ -1,17 +0,0 @@
<?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>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

16
.idea/discord.xml generated
View File

@@ -1,16 +0,0 @@
<?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>

View File

@@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View File

@@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated
View File

@@ -1,7 +0,0 @@
<?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
View File

@@ -1,8 +0,0 @@
<?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
View File

@@ -1,10 +0,0 @@
<?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
View File

@@ -1,22 +0,0 @@
<?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>

View File

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

View File

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

View File

@@ -1,31 +0,0 @@
<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/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

Binary file not shown.

View File

@@ -2,21 +2,15 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
Frame
{
id: addContactFrame
property alias contactGrid: addContactLayout
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
GridLayout GridLayout
{ {
id: addContactLayout id: addContactLayout
anchors.fill: parent Layout.fillWidth: true
// Layout.fillWidth: true Layout.fillHeight: true
// Layout.fillHeight: true Layout.alignment: Qt.AlignTop
// Layout.alignment: Qt.AlignTop
columns: 2 columns: 2
rowSpacing: 9 rowSpacing: 9
visible: false
property alias fname: firstname property alias fname: firstname
property alias lname: lastname property alias lname: lastname
@@ -83,7 +77,7 @@ Frame
placeholderText: qsTr("beispiel@domain.de") placeholderText: qsTr("beispiel@domain.de")
validator: RegularExpressionValidator validator: RegularExpressionValidator
{ {
regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/ regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~0-9A-Za-z]{1,185})@([0-9A-Za-z\.]{1,64})\.([a-zA-z]{2,5})/
} }
} }
@@ -105,7 +99,7 @@ Frame
Label Label
{ {
text: qsTr("Mobil") text: qsTr("Handy")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
} }
TextField TextField
@@ -123,7 +117,6 @@ Frame
text: qsTr("Geburtsdatum") text: qsTr("Geburtsdatum")
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
TextField TextField
{ {
property string name: "birthday" property string name: "birthday"
@@ -131,18 +124,15 @@ Frame
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: qsTr("TT.MM.JJJJ") placeholderText: qsTr("TT.MM.JJJJ")
validator: RegularExpressionValidator 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}))/ regularExpression: /((^|)([0-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)=>
{ onTextChanged:
if (event.key !== Qt.Key_Backspace)
{ {
var len = birthday.length var len = birthday.length
var bd = birthday.text var bd = birthday.text
if (len === 2 || len === 5) birthday.text = bd + "." if (len == 2 || len == 5) birthday.text = bd + "."
}
} }
} }
@@ -186,7 +176,6 @@ Frame
editable: false editable: false
model: ["Nein", "Ja"] model: ["Nein", "Ja"]
} }
}
function checkContactField() function checkContactField()
{ {

115
Gui/AddCustomer.qml Normal file
View File

@@ -0,0 +1,115 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Fusion
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:
{
addContactLayout.visible = checked
checkFields()
}
}
RowLayout
{
id: addCustomer
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 45
CustomerView
{
id: customerView
}
AddContact
{
id: addContactLayout
}
}
RowLayout
{
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
Button
{
text: qsTr("Abbrechen")
onClicked: appLoader.source = "CustomerTable.qml"
}
Button
{
id: saveBtn
text: qsTr("Speichern")
enabled: false
onClicked:
{
if (!checkAddContact.checked)
{
new_business = JsLib.addBusiness(customerView)
business_model.addBusiness(new_business, 0)
appLoader.source = "CustomerTable.qml"
}
else
{
new_business = JsLib.addBusiness(customerView)
var new_contact = JsLib.addBusiness(addContactLayout)
contact_model.addContact(new_contact)
}
}
}
}
Item
{
id: spacer3
Layout.fillHeight: true
}
//Component.onCompleted: contact_model.contactIdReady.connect(onContactId)
Connections
{
target: contact_model
onContactIdReady:
{
var con_id = arguments[0]
business_model.addBusiness(new_business, con_id)
appLoader.source = "CustomerTable.qml"
}
}
function checkFields()
{
if(checkAddContact.checked)
{
if(!customerView.checkBusinessField() || !addContactLayout.checkContactField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
else if (!customerView.checkBusinessField())
saveBtn.enabled = false
else
saveBtn.enabled = true
}
}

View File

@@ -1,230 +0,0 @@
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()
}
}

View File

@@ -1,155 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Dialogs
import Js
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)
// For Debugging
console.log(JSON.stringify(new_object))
//
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
}
}

View File

@@ -1,130 +0,0 @@
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)
}

View File

@@ -51,15 +51,6 @@ GridLayout
placeholderText: qsTr("Hier Passwort eingeben") placeholderText: qsTr("Hier Passwort eingeben")
Layout.fillWidth: true Layout.fillWidth: true
property string name: "PYQCRM_USER_PASS" property string name: "PYQCRM_USER_PASS"
color: acceptableInput ? "black" : "red"
ToolTip.visible: hovered && !acceptableInput
ToolTip.text: "Passwort muss mind. 12 Zeichen lang sein und Groß-, Kleinbuchstaben, Zahlen sowie Sonderzeichen (!@#$%^&*()_+-=) enthalten."
validator: RegularExpressionValidator {
regularExpression: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=]).{12,}$/
}
} }
Label Label
{ {

View File

@@ -1,57 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import QtCore
import Js
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"
}
}

View File

@@ -1,122 +0,0 @@
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']
}
}
}

View File

@@ -1,136 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Dialogs
import Js
import Gui
ScrollView
{
id: scroll
width: parent.width
height: parent.height
property var new_business: null
ColumnLayout
{
height: Screen.desktopAvailableHeight
width: scroll.width
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)
console.log(JSON.stringify(new_business))
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
}
}

View File

@@ -1,174 +0,0 @@
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")
}
}

View File

@@ -1,61 +0,0 @@
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
}
}

View File

@@ -1,225 +0,0 @@
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
// }
}

View File

@@ -1,177 +0,0 @@
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);
}
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
}
}

View File

@@ -1,33 +0,0 @@
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
}
}

View File

@@ -1 +0,0 @@
module Customer

217
Gui/CustomerTable.qml Normal file
View File

@@ -0,0 +1,217 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
import QtQuick.Controls.Fusion
Item {
anchors.fill: parent
property var availableFilters: ["Name", "Adresse", "PLZ", "Ort"]
id: test
SearchBar
{
id:searchBar
anchors.margins: 9
}
Button
{
id: addBusinessBtn
icon.source: "qrc:/images/addbusiness.svg"
icon.color: "olive"
anchors.right: parent.right
flat: true
onClicked: appLoader.source = "AddCustomer.qml"
}
ColumnLayout
{
id: tableColumn
anchors
{
top: searchBar.bottom
bottom: parent.bottom
left: parent.left
right: parent.right
}
RowLayout
{
RadioButton
{
id: showAll
checked: true
text: qsTr("Alle")
onClicked: viewCriterion(showAll)
}
RadioButton
{
id: showInterested
text: qsTr("Interessent")
onClicked: viewCriterion(showInterested)
}
RadioButton
{
id: showClientele
text: qsTr("Kunden")
onClicked: viewCriterion(showClientele)
}
RadioButton
{
id: showProvider
text: qsTr("Lieferant")
onClicked: viewCriterion(showProvider)
}
RadioButton
{
id: showFinished
text: qsTr("Erledigt")
onClicked: viewCriterion(showFinished)
}
}
HorizontalHeaderView
{
id: horizontalHeader
Layout.fillWidth: true
implicitHeight: 40
movableColumns: true //@disable-check M16
syncView: customerTable
delegate: Rectangle {
color: addBusinessBtn.palette.alternateBase
border.color: addBusinessBtn.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: addBusinessBtn.palette.text
}
}
}
TableView
{
//property var customWidths: [0.2, 0.5, 0.3, 05, 0.2, 0.2]
property real newWidth: 0
id: customerTable
Layout.fillHeight: true
Layout.fillWidth: true
ScrollBar.vertical: ScrollBar
{
policy: customerTable.contentHeight > customerTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
}
columnSpacing: 1
rowSpacing: 2
model: business_model
alternatingRows: true
resizableColumns: true // @disable-check M16
selectionBehavior: TableView.SelectRows
selectionModel: ItemSelectionModel
{
id: selModel
model: customerTable.model
}
// columnWidthProvider: function(column)
// {
// switch (column)
// {
// case 0: return width * 0.2;
// case 1: return width * 0.5;
// case 2: return width * 0.3;
// default: return width / model.columnCount();
// }
//return customWidths[column] * width;
//return tableColumn.content.implicitWidth // model.columnCount()
// newWidth = columnWidth(column)
// return newWidth
// }
Timer
{
id: redrawTable
running: true
interval: 1
repeat: false
onTriggered:
{
customerTable.forceLayout();
}
}
delegate:Rectangle
{
required property bool selected
required property bool current
implicitWidth: customerTable.width / customerTable.columns
implicitHeight: 25
color: selected
? addBusinessBtn.palette.highlight //palette.highlight
: (customerTable.alternatingRows && row % 2 !== 0
? addBusinessBtn.palette.base // palette.base
: addBusinessBtn.palette.alternateBase) //palette.alternateBase)
Text
{
text: model.display == null? "": model.display
elide: Text.ElideRight
width: parent.width
height: parent.height
verticalAlignment: Text.AlignVCenter
leftPadding: 9 //@d isable-check M16
color: addBusinessBtn.palette.text
}
MouseArea
{
property bool hovered: false
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked:
{
business_model.onRowClicked(row)
}
onEntered:
{
customerTable.selectionModel.select(customerTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows)
}
}
}
onContentWidthChanged:
{
//console.log("Model changed!!")
redrawTable.start()
}
}
Item
{
//Layout.fillHeight: true
Layout.fillWidth: true
}
}
function viewCriterion(criterion)
{
business_model.viewCriterion(criterion.text)
}
}

View File

@@ -5,7 +5,7 @@ import QtQuick.Layouts
GridLayout GridLayout
{ {
id: customerView id: customerView
columns: 4 columns: 2
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
rowSpacing: 9 rowSpacing: 9
@@ -16,10 +16,10 @@ GridLayout
Label Label
{ {
id: lblFirmenName id: lblFirmenName
text: qsTr("Firmenname*") text: qsTr("Firmenname")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
} }
TextField TextField
{ {
property string name: "business" property string name: "business"
@@ -28,29 +28,26 @@ GridLayout
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
onTextChanged: checkFields() onTextChanged: checkFields()
Layout.columnSpan: 3 placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
} }
Label Label
{ {
text: qsTr("Land") text: qsTr("Straße")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
visible: false
} }
ComboBox
{
property string name: "country"
id: country
Layout.fillWidth: true
editable: true
// onEditTextChanged: checkFields()
// onCurrentTextChanged: checkFields()
model: address_model
textRole: "country"
popup.height: 300
currentIndex: 37
Layout.columnSpan: 3
visible: false
TextField
{
property string name: "street"
id: streetid
Layout.fillWidth: true
onTextChanged: checkFields()
placeholderText: "Pflichtfeld"
placeholderTextColor: "red"
} }
Label Label
{ {
@@ -58,9 +55,6 @@ GridLayout
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
} }
ComboBox ComboBox
{ {
property string name: "postcode" property string name: "postcode"
@@ -73,9 +67,9 @@ GridLayout
model: address_model model: address_model
textRole: "display" textRole: "display"
popup.height: 300 popup.height: 300
popup.y: postcode.y + 5 - (postcode.height * 2)
currentIndex: -1 currentIndex: -1
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
Layout.columnSpan: 3
validator: RegularExpressionValidator validator: RegularExpressionValidator
{ {
regularExpression: /([0-9]{1,5})/ regularExpression: /([0-9]{1,5})/
@@ -99,43 +93,10 @@ GridLayout
model: address_model model: address_model
textRole: "city" textRole: "city"
popup.height: 300 popup.height: 300
popup.y: postcode.y + 5 - (postcode.height * 2)
currentIndex: -1 currentIndex: -1
Layout.columnSpan: 3 // onCurrentIndexChanged: postcode.currentIndex = city.currentIndex
} }
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 Label
{ {
@@ -147,7 +108,6 @@ GridLayout
property string name: "telephone" property string name: "telephone"
id: telephone id: telephone
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 3
validator: RegularExpressionValidator validator: RegularExpressionValidator
{ {
regularExpression: /([+0-9]{1})([0-9]{1,17})/ regularExpression: /([+0-9]{1})([0-9]{1,17})/
@@ -157,7 +117,7 @@ GridLayout
Label Label
{ {
text: qsTr("Mobil") text: qsTr("Handy")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
} }
TextField TextField
@@ -165,7 +125,6 @@ GridLayout
property string name: "cellphone" property string name: "cellphone"
id: cellphone id: cellphone
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 3
validator: RegularExpressionValidator validator: RegularExpressionValidator
{ {
regularExpression: /([+0-9]{1})([0-9]{1,17})/ regularExpression: /([+0-9]{1})([0-9]{1,17})/
@@ -183,10 +142,9 @@ GridLayout
id: email id: email
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: qsTr("beispiel@domain.de") placeholderText: qsTr("beispiel@domain.de")
Layout.columnSpan: 3
validator: RegularExpressionValidator validator: RegularExpressionValidator
{ {
regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/ regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~0-9A-Za-z]{1,185})@([0-9A-Za-z\.]{1,64})\.([a-zA-z]{2,5})/
} }
} }
@@ -200,7 +158,6 @@ GridLayout
property string name: "homepage" property string name: "homepage"
id: homepage id: homepage
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 3
placeholderText: "www.oschkarischtverhaftetwegensexy.jinx" placeholderText: "www.oschkarischtverhaftetwegensexy.jinx"
} }
@@ -214,7 +171,6 @@ GridLayout
property string name: "ceo" property string name: "ceo"
id: ceo id: ceo
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 3
} }
Label Label
@@ -227,7 +183,6 @@ GridLayout
property string name: "taxno" property string name: "taxno"
id: taxno id: taxno
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 3
} }
Label Label
{ {
@@ -242,7 +197,6 @@ GridLayout
editable: false editable: false
model: business_type model: business_type
textRole: "display" textRole: "display"
Layout.columnSpan: 3
} }
Label Label
{ {
@@ -255,7 +209,6 @@ GridLayout
id: infoView id: infoView
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 100 Layout.preferredHeight: 100
Layout.columnSpan: 3
ScrollBar.horizontal: ScrollBar ScrollBar.horizontal: ScrollBar
{ {
policy: ScrollBar.AlwaysOn policy: ScrollBar.AlwaysOn
@@ -276,7 +229,7 @@ GridLayout
} }
function checkBusinessField() function checkBusinessField()
{ {
if (!firmenName.text.trim() || !streetid.text.trim() || !housenoid.text.trim()) if (!firmenName.text.trim() || !streetid.text.trim())
{ {
return false return false

View File

@@ -2,109 +2,15 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
ColumnLayout { ColumnLayout
anchors.top: Navigation.bottom {
anchors.top: TopBar.bottom
Rectangle { Rectangle
Layout.bottomMargin: 3 {
color: "blue"
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
color: "dimgrey" Layout.bottomMargin: 9
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";
}
}
}
}
} }
} }

View File

@@ -5,11 +5,7 @@ import QtQuick.Layouts
GridLayout GridLayout
{ {
property alias dbHost: dbHost // property alias firstStart: firstStartGrid
property alias dbPort: dbPort
property alias dbName: dbName
property alias dbUserName: dbUserName
property alias dbPassword: dbPassword
id: dbGrid id: dbGrid
columns: 2 columns: 2
columnSpacing: 5 columnSpacing: 5
@@ -106,17 +102,4 @@ GridLayout
{ {
Layout.fillHeight: true 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']
}
}
} }

126
Gui/EmployeeTable.qml Normal file
View File

@@ -0,0 +1,126 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
Item {
property var availableFilters: ["Name", "Adresse", "PLZ", "Ort", "Status"]
SearchBar
{
id:searchBar
anchors.margins: 9
}
ColumnLayout
{
anchors
{
top: searchBar.bottom
bottom: parent.bottom
left: parent.left
right: parent.right
}
RowLayout
{
RadioButton
{
checked: true
text: qsTr("Alle")
}
RadioButton
{
text: qsTr("Bewerber")
}
RadioButton
{
text: qsTr("Mitarbeiter")
}
RadioButton
{
text: qsTr("Erledigt")
}
RadioButton
{
text: qsTr("Ausgeschieden")
}
}
HorizontalHeaderView
{
id: horizontalHeader
Layout.fillWidth: true
syncView: testTable
}
TableView
{
id: testTable
Layout.fillHeight: true
Layout.fillWidth: true
columnSpacing: 1
rowSpacing: 2
model: business_model
selectionBehavior: TableView.SelectRows
selectionModel: ItemSelectionModel
{
id: selModel
model: testTable.model
}
delegate:Rectangle
{
required property bool selected
required property bool current
implicitWidth: 200
implicitHeight: 25
color: selected? "lightblue": palette.base
Text
{
Layout.fillWidth: true
text: model.display
}
MouseArea
{
id: mouseArea
property bool hovered:false
anchors.fill: parent
hoverEnabled: true
onClicked:
{
business_model.onRowClicked(row)
testTable.selectionModel.select(testTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows)
}
}
}
}
}
}

View File

@@ -1,52 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import TeroStyle
import Js
ScrollView
{
ColumnLayout {
spacing: Dimensions.l
Component.onCompleted: {
employee_model.addedNewEmployee.connect(successful => {
if (successful)
contentStack.pop();
});
}
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:
{
employee_model.addApplicant(applicantForm.value);
}
}
}
}
}

View File

@@ -1,109 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Js
ScrollView
{
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');
}
}
ColumnLayout {
id: colPar
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);
}
}
}
}
}

View File

@@ -1,264 +0,0 @@
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: city.acceptableInput && email.acceptableInput && firstname.acceptableInput && lastname.acceptableInput && mobile.acceptableInput && phone.acceptableInput && postcode.acceptableInput && formofaddress.acceptableInput && title.acceptableInput
readonly property var value: QtObject
{
readonly property string city: (city.editText ? city.editText : city.currentText) ?? ""
readonly property string email: email.text
readonly property string firstname: firstname.text
readonly property string formofaddress: formofaddress.text
readonly property string houseno: houseno.text
readonly property string lastname: lastname.text
readonly property string mobile: mobile.text
readonly property string phone: phone.text
readonly property string postcode: (postcode.editText ? postcode.editText : postcode.currentText) ?? ""
readonly property string street: street.text
readonly property string title: title.currentText
readonly property string country: (country.editText ? country.editText : country.currentText) ?? ""
}
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 {
// property string name: "title"
id: title
implicitWidth: fieldM
model: [qsTr("Keine Angabe"), qsTr("Herr"), qsTr("Frau")]
onCurrentTextChanged: {
switch (title.currentIndex) {
case 1:
formofaddress.text = "Sehr geehrter Herr ";
break;
case 2:
formofaddress.text = "Sehr geehrte Frau ";
break;
default:
formofaddress.text = "Guten Tag ";
}
}
}
}
Field
{
label: qsTr("Vorname")
mandatory: true
TextField
{
// property string name: "firstname"
id: firstname
implicitWidth: fieldM
placeholderText: qsTr("Max")
validator: NotEmptyValidator {
}
}
}
Field {
label: qsTr("Nachname")
mandatory: true
TextField {
// property string name: "lastname"
id: lastname
implicitWidth: fieldM
placeholderText: qsTr("Mustermann")
validator: NotEmptyValidator {
}
}
}
}
RowLayout {
spacing: Dimensions.m
Field
{
label: qsTr("Straße")
mandatory: true
TextField
{
// property string name: "street"
id: street
implicitWidth: fieldM
placeholderText: qsTr("Musterstraße")
validator: NotEmptyValidator {
}
}
}
Field
{
mandatory: true
label: qsTr("Hausnummer")
TextField
{
// property string name: "houseno"
id: houseno
implicitWidth: fieldS
placeholderText: qsTr("1a")
validator: NotEmptyValidator {
}
}
}
Field
{
label: qsTr("PLZ")
mandatory: true
ComboBox
{
// property string name: "postcode"
id: postcode
currentIndex: -1
editable: true
implicitWidth: fieldS
model: address_model
textRole: "display"
onActivated: currentValue
onCurrentIndexChanged: city.currentIndex = postcode.currentIndex
validator: NotEmptyValidator {}
}
}
Field
{
label: qsTr("Ort")
mandatory: true
ComboBox
{
// property string name: "city"
id: city
currentIndex: -1
editable: true
implicitWidth: fieldM
model: address_model
textRole: "city"
validator: NotEmptyValidator {
}
}
}
Field
{
label: qsTr("Land")
mandatory: true
ComboBox
{
// property string name: "country"
id: country
currentIndex: 37
editable: true
implicitWidth: fieldM
model: address_model
textRole: "country"
}
}
}
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 {
// property string name: "phone"
id: phone
implicitWidth: fieldM
placeholderText: "+49 1234 567890"
validator: OptionalPhoneNumberValidator {
}
}
}
Field
{
label: qsTr("Mobil")
TextField
{
// property string name: "mobile"
id: mobile
implicitWidth: fieldM
placeholderText: "+49 123 4567891011"
validator: OptionalPhoneNumberValidator {
}
}
}
Field
{
label: qsTr("E-Mail Adresse")
TextField
{
// property string name: "email"
id: email
implicitWidth: fieldM
placeholderText: "tero@example.org"
validator: OptionalEmailAddressValidator {
}
}
}
Field
{
label: qsTr("Briefanrede")
TextField
{
// property string name: "formofaddress"
id: formofaddress
implicitWidth: fieldM
}
}
}
}

View File

@@ -1,51 +0,0 @@
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
}
}

View File

@@ -1,27 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Item
{
property int selectedEmployee: -1
id: emDet
ColumnLayout
{
Label
{
text: qsTr("Ausgewählter Mitarbeiter " + selectedEmployee)
}
Button
{
text: qsTr("Mitarbeiter zeigen")
onClicked: contentStack.pop()
}
}
Component.onCompleted:
{
employee_model.onRowClicked(selectedEmployee)
}
}

View File

@@ -1,263 +0,0 @@
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 + "."
}
}
}
}

View File

@@ -1,409 +0,0 @@
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
}
}

View File

@@ -1,63 +0,0 @@
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
}
}

View File

@@ -1,141 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout {
spacing: Dimensions.l
RowLayout {
Layout.fillWidth: true
spacing: Dimensions.l
SearchBar {
}
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: employee_model
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", {
selectedEmployee: row
});
}
onEntered: {
employeesTable.selectionModel.select(employeesTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows);
}
}
}
selectionModel: ItemSelectionModel {
model: employeesTable.model
}
}
}
}

View File

@@ -1 +0,0 @@
module Employees

View File

@@ -4,134 +4,199 @@ import QtQuick.Controls
import QtQuick.Dialogs import QtQuick.Dialogs
import QtQuick.Layouts import QtQuick.Layouts
Item {
Item
{
property string recpass: "" property string recpass: ""
anchors.fill: parent
function dbConnectionFailed(msg) { ColumnLayout
notifications.notificationDialog.informativeText = msg; {
notifications.notificationDialog.text = "Verbindung zum Datenbankserver verloren";
notifications.notificationDialog.open(); anchors.fill: parent
}
function getEncryptionKey() { FontLoader
recoveryPaswordDialog.open(); {
} id: helloStranger
function loggedin() { source: "qrc:/fonts/HelloStranger.otf"
contentStack.replace("Dashboard.qml");
} }
// anchors.fill: parent FontLoader
// anchors.topMargin: Dimensions.l {
id: damarWulan
Component.onCompleted: { source: "qrc:/fonts/Damarwulan.ttf"
loggedin_user.loginOkay.connect(loggedin);
config.invalidEncryptionKey.connect(getEncryptionKey);
config.checkEncryptionKey();
loggedin_user.noDbConnection.connect(dbConnectionFailed);
benutzerName.forceActiveFocus();
} }
ColumnLayout { FontLoader
anchors.centerIn: parent {
spacing: Dimensions.m id: hussarPrint
source: "qrc:/fonts/HussarPrintA.otf"
}
Label { FontLoader
{
id: reginaldScript
source: "qrc:/fonts/ReginaldScript.ttf"
}
Item
{
height: 65
}
Label
{
text: qsTr ("Login*****")
font.family: helloStranger.font.family
font.weight: helloStranger.font.weight
font.styleName: helloStranger.font.styleName
font.pixelSize: 89
font.bold: true
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: Dimensions.l
font: Typography.h1
text: qsTr("Login")
} }
Field {
label: qsTr("Benutzername")
TextField { Item
{
height: 25
}
RowLayout
{
Layout.alignment: Qt.AlignHCenter
spacing: 15
Label
{
text: qsTr ("Benutzername")
minimumPixelSize: 20
Layout.preferredWidth: 150
horizontalAlignment: Text.AlignRight
font.family: damarWulan.font.family
font.weight: damarWulan.font.weight
font.styleName: damarWulan.font.styleName
font.pixelSize: 21
}
TextField
{
id: benutzerName id: benutzerName
focus: true
implicitWidth: 300
placeholderText: qsTr ("Benutzernamen eingeben") 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 implicitWidth: 300
font: hussarPrint.font
}
}
RowLayout
{
Layout.alignment: Qt.AlignHCenter
spacing: 15
Label
{
minimumPixelSize: 20
Layout.preferredWidth: 150
text: qsTr ("Passwort")
font.family: damarWulan.font.family
font.weight: damarWulan.font.weight
font.styleName: damarWulan.font.styleName
font.pixelSize: 21
horizontalAlignment: Text.AlignRight
}
TextField
{
id: passwort
placeholderText: qsTr ("Passwort eingeben") placeholderText: qsTr ("Passwort eingeben")
implicitWidth: 300
font: hussarPrint.font
echoMode: TextInput.Password
}
}
onAccepted: { RowLayout
if (benutzerName.text.trim() && passwort.text.trim()) {
loggedin_user.login(benutzerName.text.trim(), passwort.text); Layout.preferredWidth: 465
else if (passwort.text.trim()) Layout.alignment: Qt.AlignHCenter
benutzerName.forceActiveFocus();
}
}
}
Button {
Layout.topMargin: Dimensions.m
icon.source: "qrc:/images/ArrowRightEndOnRectangle.svg"
implicitWidth: parent.width
text: qsTr("Login")
onClicked: { Button
{
text: qsTr ("Feierabend für heute!")
Layout.alignment: Qt.AlignRight
font: reginaldScript.font
onClicked:
{
if (benutzerName.text.trim() && passwort.text.trim()) if (benutzerName.text.trim() && passwort.text.trim())
loggedin_user.login(benutzerName.text.trim(), passwort.text); loggedin_user.login(benutzerName.text.trim(), passwort.text)
} }
} }
Item { }
Item
{
Layout.fillHeight: true Layout.fillHeight: true
} }
Dialog {
Dialog
{
id: recoveryPaswordDialog id: recoveryPaswordDialog
anchors.centerIn: parent
modal: true modal: true
standardButtons: Dialog.Ok | Dialog.Cancel
title: qsTr("Wiederherstellung") title: qsTr("Wiederherstellung")
anchors.centerIn: parent
onAccepted: { standardButtons: Dialog.Ok | Dialog.Cancel
recpass = recoveryPaswordInput.text; onAccepted:
getRecoveryDialog.open(); {
recpass = recoveryPaswordInput.text
getRecoveryDialog.open()
} }
ColumnLayout { ColumnLayout
RowLayout { {
Label { RowLayout
{
Label
{
text: qsTr("Wiederherstellungspasswort eingeben: ") text: qsTr("Wiederherstellungspasswort eingeben: ")
} }
TextField {
id: recoveryPaswordInput
TextField
{
id: recoveryPaswordInput
text: ""
echoMode: TextInput.Password echoMode: TextInput.Password
implicitWidth: 300 implicitWidth: 300
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben") placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
text: ""
} }
} }
} }
} }
FileDialog {
id: getRecoveryDialog
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0] FileDialog
{
id: getRecoveryDialog
title: qsTr("Wiederherstellungsdatei")
fileMode: FileDialog.OpenFile fileMode: FileDialog.OpenFile
nameFilters: ["PYQCRM Recovery files (*.pyqrec)"] nameFilters: ["PYQCRM Recovery files (*.pyqrec)"]
title: qsTr("Wiederherstellungsdatei") currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
onAccepted: config.getRecoveryKey(getRecoveryDialog.currentFile, recpass) onAccepted: config.getRecoveryKey(getRecoveryDialog.currentFile, recpass)
onRejected: quit() onRejected: quit()
} }
Notifications { }
id: notifications
} Component.onCompleted:
{
loggedin_user.loginOkay.connect(loggedin)
config.invalidEncryptionKey.connect(getEncryptionKey)
config.checkEncryptionKey()
}
function loggedin()
{
appLoader.source = "Dashboard.qml"
}
function getEncryptionKey()
{
recoveryPaswordDialog.open()
} }
} }

View File

@@ -1,22 +0,0 @@
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
}
}

View File

@@ -1,120 +0,0 @@
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/Customer/CustomersTable.qml"
text: qsTr("Kunden")
visible: !onSubPage
}
BarButton {
ButtonGroup.group: mainNav
icon.source: "qrc:/images/BuildingOffice2-Outline.svg"
target: "/Gui/Objects/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/Offers/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()
}
}
}
}

View File

@@ -1,27 +1,74 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts
ColumnLayout { Rectangle
{
anchors.fill: parent
color: "slateblue"
Rectangle
{
id: info
anchors.horizontalCenter: parent.horizontalCenter
color: "slateblue"
implicitHeight: 55
implicitWidth: parent.width / 4
y: parent.height / 4
Text
{
anchors.centerIn: parent anchors.centerIn: parent
spacing: Dimensions.s
height: implicitHeight
H1 {
Layout.alignment: Qt.AlignCenter
text: qsTr("Keine Verbindung zur Datenbank!") text: qsTr("Keine Verbindung zur Datenbank!")
color: Colors.foreground color: "moccasin"
font.bold: true
font.pixelSize: 45
} }
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")
Rectangle
{
id: nostart
anchors.top: info.bottom
color: "slateblue"
anchors.horizontalCenter: parent.horizontalCenter
implicitHeight: 55
implicitWidth: parent.width / 4
Text
{
text: qsTr("Programm kann nicht starten..")
color: "moccasin"
anchors.centerIn: parent
font.bold: true
font.pixelSize: 45
}
}
Rectangle
{
anchors.top: nostart.bottom
anchors.topMargin: 25
anchors.horizontalCenter: parent.horizontalCenter
color: "slateblue"
implicitHeight: 55
implicitWidth: parent.width / 4
Button
{
width: parent.width
height: 75
Text
{
text: qsTr("Beenden")
color: "moccasin"
anchors.centerIn: parent
font.bold: true
font.pixelSize: 45
}
anchors.centerIn: parent
background: Rectangle
{
color: "dodgerblue"
radius: 50
}
onClicked: Qt.quit() onClicked: Qt.quit()
} }
} }
}

View File

@@ -1,12 +0,0 @@
import QtQuick
import QtQuick.Dialogs
Item
{
MessageDialog
{
id: notificationDialog
buttons: MessageDialog.Ok
}
}

View File

@@ -1,317 +0,0 @@
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
}
}

View File

@@ -1,125 +0,0 @@
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"]});
// }
}

View File

@@ -1,28 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Js
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
}
}

View File

@@ -1,27 +0,0 @@
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)
}
}

View File

@@ -1,238 +0,0 @@
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
}
}

View File

@@ -1,255 +0,0 @@
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("Land")
Layout.alignment: Qt.AlignRight
visible: false
}
ComboBox
{
property string name: "country"
id: country
Layout.fillWidth: true
editable: true
// onEditTextChanged: checkFields()
// onCurrentTextChanged: checkFields()
model: address_model
textRole: "country"
popup.height: 300
currentIndex: 37
visible: false
}
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
}
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
// 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()
}
}

View File

@@ -1,163 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Dialogs
import Js
ScrollView
{
id: scroll
width: parent.width
height: parent.height
ColumnLayout
{
height: Screen.desktopAvailableHeight
width: scroll.width
property var new_object: null
//property alias checkAddContact: checkAddContact
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)
// For Debugging
console.log(JSON.stringify(new_object))
//
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
}
}

View File

@@ -1,130 +0,0 @@
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)
}

View File

@@ -1,317 +0,0 @@
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
}
}

View File

@@ -1,125 +0,0 @@
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"]});
// }
}

View File

@@ -1,28 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Js
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
}
}

View File

@@ -1,27 +0,0 @@
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)
}
}

View File

@@ -1,238 +0,0 @@
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
}
}

View File

@@ -1,186 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout
{
property var availableFilters: [""]
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: "Aktiv"
text: qsTr("Aktiv")
selected: false
}
ListElement {
name: "Ehemalig"
text: qsTr("Ehemalig")
selected: false
}
ListElement {
name: "Angebote"
text: qsTr("Angebote")
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
}
}

View File

@@ -1 +0,0 @@
module Objects

View File

@@ -1,186 +0,0 @@
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: "Aktiv"
text: qsTr("Aktiv")
selected: false
}
ListElement {
name: "Ehemalig"
text: qsTr("Ehemalig")
selected: false
}
ListElement {
name: "Angebote"
text: qsTr("Angebote")
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
}
}

View File

@@ -1,236 +0,0 @@
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("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
}
Label
{
text: qsTr("Straße")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "street"
id: street
model: object_model
textRole: "StreetInPostcode"
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
// onTextChanged: checkFields()
}
Label
{
text: qsTr("Nr.*")
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
}
ComboBox
{
property string name: "houseno"
id: houseno
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
// onTextChanged: checkFields()
}
// New grid row
//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.columnSpan: 2
}
//New Grid
Label
{
text: qsTr("Leistungen:")
Layout.alignment: Qt.AlignRight
font: Typography.h2
}
Item
{
Layout.columnSpan: 3
}
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()
// }
}

View File

@@ -1,111 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Dialogs
import Js
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
AddNewOffer
{
id: newOffer
width: parent.width
}
}
RowLayout
{
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
Button
{
text: qsTr("Abbrechen")
onClicked: contentStack.pop()
}
Button
{
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
// }
}

View File

@@ -1,66 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
ColumnLayout
{
spacing: Dimensions.l
function viewOffers(criterion)
{
//offer_model.viewCriterion(criterion)
}
RowLayout
{
Layout.fillWidth: true
spacing: Dimensions.l
SearchBar
{
id: searchBar
}
QuickFilter {
model: ListModel {
ListElement {
name: "Alle"
text: qsTr("Alle")
selected: true
}
ListElement
{
name: "Offen"
text: qsTr("Offen")
selected: false
}
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
text: qsTr("Angebote Hinzufügen")
icon.source: "qrc:/images/PlusCircle.svg"
Layout.alignment: Qt.AlignRight
flat: true
onClicked: contentStack.push("AddOffer.qml")
}
}
Item {
id: spacer
Layout.fillHeight: true
}
}

View File

@@ -1 +0,0 @@
module Offers

View File

@@ -1,143 +0,0 @@
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())
}
}
}

View File

@@ -1,171 +0,0 @@
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)
}
}

View File

@@ -1,47 +0,0 @@
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();
}
}
}
}

82
Gui/SearchBar.qml Normal file
View File

@@ -0,0 +1,82 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
RowLayout
{
id: searchBar
TextField
{
id: searchField
placeholderText: qsTr("Suche")
leftPadding: 3
rightPadding: 3
Layout.preferredWidth: 300
Button
{
icon.source: "qrc:/images/search.svg"
icon.color: "olive"
x: parent.x + parent.width - width
height: parent.height
flat: true
}
Button
{
id: filterBtn
icon.source: "qrc:/images/filter.svg"
icon.color: "olive"
x: parent.x + parent.width
height: searchField.height
flat: true
onClicked: filterPopup.open()
}
}
Popup
{
id: filterPopup
x: filterBtn.x + filterBtn.width
y: filterBtn.y
width: 100
height: 150
modal: true
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
contentItem: Item
{
ColumnLayout
{
anchors.fill: parent
//id: filterContent
Repeater
{
model: availableFilters
CheckBox
{
text: model.modelData
onClicked:
{
setFilter(text, checkState)
}
}
}
}
}
}
function setFilter(filter,activated)
{
console.log(filter)
console.log(activated)
}
}

92
Gui/TopBar.qml Normal file
View File

@@ -0,0 +1,92 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
RowLayout
{
id: topBar
spacing: 0
height: 35
width: parent.width
anchors
{
top: parent.top
left: parent.left
}
Button
{
id: dashBoard
flat: true
text: qsTr("Dashboard")
implicitWidth: dashBoard.implicitContentWidth + 10
onClicked:
{
appLoader.source = "Dashboard.qml"
}
}
Button
{
id: kunden
flat: true
text: qsTr("Kunden")
implicitWidth: kunden.implicitContentWidth + 10
onClicked:
{
// TODO: here we should call the model
appLoader.source = "CustomerTable.qml"
}
}
Button
{
id: objekt
flat: true
text: qsTr("Objekt")
implicitWidth: objekt.implicitContentWidth + 10
}
Button
{
id: mitarbeiter
flat: true
text: qsTr("Mitarbeiter")
implicitWidth: mitarbeiter.implicitContentWidth + 10
onClicked:
{
appLoader.source = "EmployeeTable.qml"
}
}
Button
{
id: abrechnung
flat: true
text: qsTr("Abrechnung")
implicitWidth: abrechnung.implicitContentWidth + 10
}
Item
{
id: hspacer
Layout.fillWidth: true
}
Button
{
id: atajos
icon.source: "qrc:/images/menu.svg"
icon.color: "red"
flat: true
Layout.rightMargin: 9
}
}

View File

@@ -1,17 +0,0 @@
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
}
}

View File

@@ -1,208 +0,0 @@
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")
}
}

View File

@@ -7,14 +7,11 @@ import QtCore
import "../js/qmldict.js" as Qmldict import "../js/qmldict.js" as Qmldict
Item Item
{ {
property string recpass: "" property string recpass: ""
property bool adminAvailable: true property bool adminAvailable: true
id: firstStartItem
anchors.fill: parent anchors.fill: parent
StackView StackView
{ {
@@ -73,11 +70,12 @@ Item
MessageDialog MessageDialog
{ {
id: recoveryDialog id: recoveryDialog
text: qsTr("Diesen Wiederherstellungscode musst du sicher aufbewahren!\nMöchtest du das jetzt machen?") text: qsTr("Diesen Wiederherstellungscode musst du sicher aufbewahren!\nMöchtest du das jetzt machen?")
title: qsTr("Wiederherstellen") title: qsTr("Wiederherstellen")
buttons: MessageDialog.Yes | MessageDialog.No buttons: MessageDialog.Yes | MessageDialog.No
onAccepted: recoveryPaswordDialog.open() onAccepted: recoveryPaswordDialog.open()
onRejected: contentStack.replace("LoginSreen.qml") onRejected: gotoLogin()
} }
MessageDialog MessageDialog
@@ -89,7 +87,6 @@ Item
Dialog Dialog
{ {
id: recoveryPaswordDialog id: recoveryPaswordDialog
modal: true modal: true
title: qsTr("Wiederherstellung") title: qsTr("Wiederherstellung")
@@ -118,19 +115,6 @@ Item
implicitWidth: 300 implicitWidth: 300
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben") placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
} }
Label
{
text: qsTr("Wiederherstellungspasswort eingeben: ")
}
TextField
{
id: repeatRecoveryPaswordInput
text: ""
echoMode: TextInput.Password
implicitWidth: 300
placeholderText: qsTr("Hier Wiederherstellungspasswort eingeben")
}
} }
} }
} }
@@ -147,7 +131,7 @@ Item
if (!adminAvailable) config.saveRecoveryKey(saveRecoveryDialog.currentFile, recpass) if (!adminAvailable) config.saveRecoveryKey(saveRecoveryDialog.currentFile, recpass)
else config.getRecoveryKey(saveRecoveryDialog.currentFile, recpass) else config.getRecoveryKey(saveRecoveryDialog.currentFile, recpass)
contentStack.replace("LoginSreen.qml") gotoLogin()
} }
onRejected: onRejected:
@@ -156,12 +140,6 @@ Item
} }
} }
Loader
{
id: utilityDialogs
source: "UtilityDialogs.qml"
}
Component.onCompleted: Component.onCompleted:
{ {
config.dbConnectionError.connect(onDbConnectionError) config.dbConnectionError.connect(onDbConnectionError)
@@ -169,10 +147,15 @@ Item
config.backupEncryptionKey.connect(onBackupEncryptionKey) config.backupEncryptionKey.connect(onBackupEncryptionKey)
} }
function gotoLogin()
{
appLoader.source= "LoginScreen.qml"
topBar.visible = true
}
function onBackupEncryptionKey() function onBackupEncryptionKey()
{ {
recoveryDialog.open()
utilityDialogs.item.recoveryDialog.open()
} }
function onDbConnectionError(msg, success) function onDbConnectionError(msg, success)
@@ -193,4 +176,5 @@ Item
firstStart.push("AdminUserConfig.qml") firstStart.push("AdminUserConfig.qml")
} }
} }
} }

View File

@@ -4,138 +4,108 @@ import QtQuick.Controls
import QtQuick.Dialogs import QtQuick.Dialogs
import QtCore import QtCore
ApplicationWindow { ApplicationWindow
{
id: appWindow id: appWindow
width: Screen.width * .6
property string confile: "" height: Screen.height * .75
property alias settingsFileDialog: settingsFiledialog
function showWindow(why) {
if (why === 3) {
systray.setVisible(false);
appWindow.show();
}
}
font: Typography.body
height: Screen.desktopAvailableHeight
palette.window: Colors.mantle
palette.placeholderText: Colors.interactive
palette.text: Colors.foreground
title: "TERO Personal"
visible: true visible: true
width: Screen.desktopAvailableWidth title: "PYQCRM"
property string confile: ""
Component.onCompleted: { TopBar
systray.activated.connect(showWindow); {
if (bad_config) { id:topBar
importDialog.open(); anchors
} else { {
if (db_con) rightMargin: 9
contentStack.replace("LoginScreen.qml") leftMargin: 9
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 { visible: bad_config || !db_con ? false: true
id: navigation
visible: !(bad_config || !db_con)
} }
PrinterDialog {
id: printerDialog
} Item
ReadMe { {
id: readMeWin
}
Item {
id: mainView id: mainView
} }
Rectangle { Loader
id: contentBackground {
anchors { id: appLoader
bottom: parent.bottom anchors
left: navigation.visible ? navigation.right : parent.left {
left: parent.left
right: parent.right right: parent.right
top: parent.top top: topBar.bottom
} bottom: parent.bottom
color: Colors.background topMargin: 0
rightMargin: 9
leftMargin: 9
} }
StackView { property alias window: appWindow
id: contentStack }
anchors { Component.onCompleted:
fill: contentBackground {
margins: Dimensions.l if(bad_config)
{
importDialog.open()
}
else
{
if (db_con) appLoader.source= "LoginScreen.qml"
else appLoader.source= "NoDbConnection.qml"
} }
} }
Dialog { Dialog
{
id: importDialog id: importDialog
anchors.centerIn: parent
modal: true modal: true
anchors.centerIn: parent
standardButtons: Dialog.Yes | Dialog.No standardButtons: Dialog.Yes | Dialog.No
title: qsTr("Einstellungen importieren")
onAccepted: settingsFiledialog.open() onAccepted: settingsFiledialog.open()
onRejected: contentStack.replace("Firststart.qml") onRejected: appLoader.source= "firststart.qml"
title: qsTr("Einstellungen importieren")
} }
FileDialog {
id: settingsFiledialog
FileDialog
{
id: settingsFiledialog
title: qsTr("PYQCRM Einstellungen")
currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0] currentFolder: StandardPaths.standardLocations(StandardPaths.DocumentsLocation)[0]
modality: "ApplicationModal" modality: "ApplicationModal"
nameFilters: [qsTr("PYQCRM Einstellungen (*.pyqrec)")] nameFilters: [qsTr("PYQCRM Einstellungen (*.pyqcrm)")]
title: qsTr("PYQCRM Einstellungen") onAccepted:
{
exportFilePassword.open()
confile = selectedFile
}
}
onAccepted: { Dialog
exportFilePassword.open(); {
confile = selectedFile;
}
}
Dialog {
id: exportFilePassword id: exportFilePassword
anchors.centerIn: parent
modal: true modal: true
standardButtons: Dialog.Ok | Dialog.Cancel
title: qsTr("PYQCRM Einstellungen") title: qsTr("PYQCRM Einstellungen")
anchors.centerIn: parent
standardButtons: Dialog.Ok | Dialog.Cancel
onAccepted: config.importConfig(confile, exportPasswordInput.text) onAccepted: config.importConfig(confile, exportPasswordInput.text)
ColumnLayout
ColumnLayout { {
RowLayout { RowLayout
Label { {
Label
{
text: qsTr("Passwort eingeben:") text: qsTr("Passwort eingeben:")
} }
TextField {
id: exportPasswordInput
TextField
{
id: exportPasswordInput
echoMode: TextInput.Password echoMode: TextInput.Password
implicitWidth: 300 implicitWidth: 300
} }

View File

@@ -1,3 +1,2 @@
module gui module gui
Navigation 1.0 Navigation.qml TopBar 1.0 TopBar.qml
AddContact 1.0 AddContact.qml

View File

@@ -1,73 +0,0 @@
.pragma library
function firstConf(tabs)
{
let pyqcrm_conf = {};
pyqcrm_conf[tabs.name] = {}
for (var i = 0; i < tabs.children.length; i++)
{
if (tabs.children[i].name)
{
if (!tabs.children[i].text.trim())
return false
if (pyqcrm_conf[tabs.name][tabs.children[i].name] !== "DB_PASS")
pyqcrm_conf[tabs.name] [tabs.children[i].name] = tabs.children[i].text.trim()
else
pyqcrm_conf[tabs.name] [tabs.children[i].name] = tabs.children[i].text
}
}
return pyqcrm_conf
}
function parseForm(...form)
{
let data_form = {};
for (var i = 0; i < form.length; i++)
{
for (var j = 0; j < form[i].children.length; j++)
{
console.log(form[i].children[j])
if (form[i].children[j].toString().startsWith("Combo"))
{
if(form[i].children[j].editText)
{
data_form[form[i].children[j].name] = form[i].children[j].editText
}
else
{
data_form[form[i].children[j].name] = form[i].children[j].currentText
}
}
else if (form[i].children[j].toString().startsWith("TextField"))
{
data_form[form[i].children[j].name] = form[i].children[j].text.trim()
}
else if (form[i].children[j].toString().startsWith("Scroll"))
{
data_form[form[i].children[j].contentChildren[0].name] = form[i].children[j].contentChildren[0].text.trim()
}
else if (form[i].children[j].toString().startsWith("CheckBox"))
{
data_form[form[i].children[j].name] = form[i].children[j].checked
}
else if (form[i].children[j].toString().startsWith("SpinBox"))
{
data_form[form[i].children[j].name] = form[i].children[j].value
}
// else if (form[i].children[j].toString().startsWith("QQuickContentItem"))
// {
// console.log(form[i].children[j].children.children)
// for (var k = 0; k < form[i].children[j].length; k++)
// {
// console.log(form[i].children[j].name)
// }
// }
}
}
return data_form
}

View File

@@ -1,70 +0,0 @@
.pragma library
function firstConf(tabs)
{
let pyqcrm_conf = {};
pyqcrm_conf[tabs.name] = {}
for (var i = 0; i < tabs.children.length; i++)
{
if (tabs.children[i].name)
{
if (!tabs.children[i].text.trim())
return false
if (pyqcrm_conf[tabs.name][tabs.children[i].name] !== "DB_PASS")
pyqcrm_conf[tabs.name] [tabs.children[i].name] = tabs.children[i].text.trim()
else
pyqcrm_conf[tabs.name] [tabs.children[i].name] = tabs.children[i].text
}
}
return pyqcrm_conf
}
function parseForm(...form)
{
let data_form = {};
for (var i = 0; i < form.length; i++)
{
for (var j = 0; j < form[i].children.length; j++)
{
if (form[i].children[j].toString().startsWith("Combo"))
{
if(form[i].children[j].editText)
{
data_form[form[i].children[j].name] = form[i].children[j].editText
}
else
{
data_form[form[i].children[j].name] = form[i].children[j].currentText
}
}
else if (form[i].children[j].toString().startsWith("TextField"))
{
data_form[form[i].children[j].name] = form[i].children[j].text.trim()
}
else if (form[i].children[j].toString().startsWith("Scroll"))
{
data_form[form[i].children[j].contentChildren[0].name] = form[i].children[j].contentChildren[0].text.trim()
}
else if (form[i].children[j].toString().startsWith("CheckBox"))
{
data_form[form[i].children[j].name] = form[i].children[j].checked
}
else if (form[i].children[j].toString().startsWith("SpinBox"))
{
data_form[form[i].children[j].name] = form[i].children[j].value
}
// else if (form[i].children[j].toString().startsWith("QQuickContentItem"))
// {
// console.log(form[i].children[j].children.children)
// for (var k = 0; k < form[i].children[j].length; k++)
// {
// console.log(form[i].children[j].name)
// }
// }
}
}
return data_form
}

View File

@@ -1,2 +0,0 @@
module Js
JsLib 1.0 JsLib.js

View File

@@ -1 +0,0 @@
Nicht zu verwenden ohne Zahlung!

54
README
View File

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

View File

@@ -1,61 +0,0 @@
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)
}
}

View File

@@ -1,69 +0,0 @@
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
}
}

View File

@@ -1,26 +0,0 @@
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
}

View File

@@ -1,108 +0,0 @@
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
}
}
}
}

View File

@@ -1,26 +0,0 @@
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
}

View File

@@ -1,5 +0,0 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /([\+!#$%&\*\\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
}

View File

@@ -1,20 +0,0 @@
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
}
}

View File

@@ -1,5 +0,0 @@
import QtQuick
Text {
font: Typography.h1
}

View File

@@ -1,5 +0,0 @@
import QtQuick
Text {
font: Typography.h2
}

View File

@@ -1,5 +0,0 @@
import QtQuick.Controls
Label {
color: Colors.foreground
}

View File

@@ -1,5 +0,0 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /^\S+.*\S+$/
}

View File

@@ -1,5 +0,0 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /^$|([\+!#$%&\*\\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/
}

View File

@@ -1,5 +0,0 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /^$|([+0-9])([0-9\s]{1,17})/
}

View File

@@ -1,5 +0,0 @@
import QtQuick
RegularExpressionValidator {
regularExpression: /([+0-9])([0-9\s]{1,17})/
}

Some files were not shown because too many files have changed in this diff Show More