diff --git a/Gui/AddCustomer.qml b/Gui/AddCustomer.qml index 50750e5..d06078d 100644 --- a/Gui/AddCustomer.qml +++ b/Gui/AddCustomer.qml @@ -1,120 +1,120 @@ -import QtQuick -import QtQuick.Layouts -import QtQuick.Controls -import QtQuick.Dialogs -import Js +// import QtQuick +// import QtQuick.Layouts +// import QtQuick.Controls +// import QtQuick.Dialogs +// import Js -ColumnLayout -{ - property var new_business: null - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 15 - Label - { - text: qsTr("Kunden anlegen") - horizontalAlignment: Text.AlignHCenter - Layout.fillWidth: true - font.pixelSize: 35 - } - CheckBox - { - id: checkAddContact - text: qsTr("Ansprechpartner hinzufügen") - Layout.alignment: Qt.AlignRight - checked: false - onCheckStateChanged: - { - checkFields() - } - } +// ColumnLayout +// { +// property var new_business: null +// Layout.fillWidth: true +// Layout.fillHeight: true +// spacing: 15 +// Label +// { +// text: qsTr("Kunden anlegen") +// horizontalAlignment: Text.AlignHCenter +// Layout.fillWidth: true +// font.pixelSize: 35 +// } +// CheckBox +// { +// id: checkAddContact +// text: qsTr("Ansprechpartner hinzufügen") +// Layout.alignment: Qt.AlignRight +// checked: false +// onCheckStateChanged: +// { +// checkFields() +// } +// } - RowLayout - { - id: addCustomer - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 45 - Frame - { - Layout.alignment: Qt.AlignTop - Layout.fillWidth: true - CustomerView - { - id: customerView - width: parent.width - } - } +// RowLayout +// { +// id: addCustomer +// Layout.fillWidth: true +// Layout.fillHeight: true +// spacing: 45 +// Frame +// { +// Layout.alignment: Qt.AlignTop +// Layout.fillWidth: true +// CustomerView +// { +// id: customerView +// width: parent.width +// } +// } - AddContact - { - id: addContactFrame - visible: checkAddContact.checked - } - } - RowLayout - { - Layout.fillHeight: true - Layout.alignment: Qt.AlignRight - Button - { - text: qsTr("Abbrechen") - onClicked: contentStack.pop() - } - Button - { - id: saveBtn - text: qsTr("Speichern") - enabled: false - onClicked: - { - if (!checkAddContact.checked) - { - new_business = JsLib.parseForm(customerView) - business_model.addBusiness(new_business, 0) - contentStack.pop() - } - else - { - new_business = JsLib.parseForm(customerView) - var new_contact = JsLib.parseForm(addContactFrame.contactGrid) - contact_model.addContact(new_contact) - } - } - } - } - Item - { - id: spacer3 - Layout.fillHeight: true - } +// AddContact +// { +// id: addContactFrame +// visible: checkAddContact.checked +// } +// } +// RowLayout +// { +// Layout.fillHeight: true +// Layout.alignment: Qt.AlignRight +// Button +// { +// text: qsTr("Abbrechen") +// onClicked: contentStack.pop() +// } +// Button +// { +// id: saveBtn +// text: qsTr("Speichern") +// enabled: false +// onClicked: +// { +// if (!checkAddContact.checked) +// { +// new_business = JsLib.parseForm(customerView) +// business_model.addBusiness(new_business, 0) +// contentStack.pop() +// } +// else +// { +// new_business = JsLib.parseForm(customerView) +// var new_contact = JsLib.parseForm(addContactFrame.contactGrid) +// contact_model.addContact(new_contact) +// } +// } +// } +// } +// Item +// { +// id: spacer3 +// Layout.fillHeight: true +// } - //Component.onCompleted: contact_model.contactIdReady.connect(onContactId) +// //Component.onCompleted: contact_model.contactIdReady.connect(onContactId) - Connections - { - target: contact_model +// Connections +// { +// target: contact_model - function onContactIdReady() - { - var con_id = arguments[0] - business_model.addBusiness(new_business, con_id) - contentStack.pop() - } - } +// 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 - } -} +// 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 +// } +// } diff --git a/Gui/Customer/AddCustomer.qml b/Gui/Customer/AddCustomer.qml new file mode 100644 index 0000000..7549233 --- /dev/null +++ b/Gui/Customer/AddCustomer.qml @@ -0,0 +1,133 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Dialogs +import Js +import Gui +ScrollView +{ + id: scroll + width: parent.width + height: parent.height + + +ColumnLayout +{ + property var new_business: null + 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: true + onClicked: + { + if (!checkAddContact.checked) + { + new_business = JsLib.parseForm(customerView) + business_model.addBusiness(new_business, 0) + contentStack.pop() + } + else + { + new_business = JsLib.parseForm(customerView) + var new_contact = JsLib.parseForm(addContactFrame.contactGrid) + contact_model.addContact(new_contact) + } + } + } + } + Item + { + id: spacer3 + Layout.fillHeight: true + } + + //Component.onCompleted: contact_model.contactIdReady.connect(onContactId) + + Connections + { + target: contact_model + + function onContactIdReady() + { + var con_id = arguments[0] + business_model.addBusiness(new_business, con_id) + contentStack.pop() + } + } + + function checkFields() + { + if(checkAddContact.checked) + { + if(!customerView.checkBusinessField() || !addContactFrame.checkContactField()) + saveBtn.enabled = false + else + saveBtn.enabled = true + } + else if (!customerView.checkBusinessField()) + saveBtn.enabled = false + else + saveBtn.enabled = true + } +} +} diff --git a/Gui/Customer/CustomerContactDetails.qml b/Gui/Customer/CustomerContactDetails.qml new file mode 100644 index 0000000..6c66c9a --- /dev/null +++ b/Gui/Customer/CustomerContactDetails.qml @@ -0,0 +1,174 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +GridLayout +{ + columns: 2 + rowSpacing: 25 + Layout.leftMargin: 7 + + // Grid row + ColumnLayout + { + Layout.columnSpan: 2 + Label + { + id: contactLabel + color: "darksalmon" + font.bold: true + text: qsTr("Ansprechpartner") + } + + Label + { + color: "goldenrod" + text: contact? contact['contact']['salute'] + " " + contact['contact']['fname'] + " " + contact['contact']['lname']: "" + } + } + + // Grid row + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Geburtsdatum") + font.bold: true + } + + Label + { + color: "goldenrod" + text: contact? contact['contact']['birthday']: "" + } + } + + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("E-Mail") + font.bold: true + } + + Label + { + color: "goldenrod" + text: contact? contact['contact']['email']: "" + } + } + + // Grid row + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Position") + font.bold: true + } + + Label + { + color: "goldenrod" + text: contact? contact['contact']['position']: "" + } + } + + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Priorität") + font.bold: true + } + + Label + { + color: "goldenrod" + text: contact? contact['contact']['priority']: "" + } + } + + // Grid row + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Telefon") + font.bold: true + } + + Label + { + color: "goldenrod" + text: contact? contact['contact']['phone']: "" + } + } + + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Handy") + font.bold: true + } + + Label + { + color: "goldenrod" + text: contact? contact['contact']['cell']: "" + } + } + + // Grid row + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Abrechnung") + font.bold: true + } + + Label + { + color: "goldenrod" + text: contact? contact['contact']['invoice']: "" + } + } + + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Mahnung") + font.bold: true + } + + Label + { + color: "goldenrod" + text: contact? contact['contact']['reminder']: "" + } + } + + // Grid row + Item + { + Layout.columnSpan: 2 + Layout.fillHeight: true + } + + Component.onCompleted: + { + if (contact && contact['contact']['salute'] === "Frau") + contactLabel.text = qsTr("Ansprechpartnerin") + } +} diff --git a/Gui/Customer/CustomerDetails.qml b/Gui/Customer/CustomerDetails.qml new file mode 100644 index 0000000..e0c13d3 --- /dev/null +++ b/Gui/Customer/CustomerDetails.qml @@ -0,0 +1,61 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ColumnLayout +{ + property int selectedClient: -1 + property var client: null + property var contact: null + id: clDet + + Button + { + text: qsTr("Zurück") + onClicked: contentStack.pop() + } + + SplitView + { + id: clDetView + Layout.fillHeight: true + Layout.fillWidth: true + leftPadding: 9 + rightPadding: 9 + + CustomerDetailsView + { + id: customerDetails + } + + CustomerContactDetails + { + id: contactDetails + visible: false + } + + NoCustomerContact + { + id: noCustomerContact + visible: false + } + } + + Item + { + //Layout.columnSpan: 2 + Layout.fillHeight: true + } + + Component.onCompleted: + { + //business_model.onRowClicked(selectedClient) + client = business_model.getClientDetails() + if (client['business']['contactid'] > 0) + { + contact = contact_model.getContactDetails(client['business']['contactid']) + contactDetails.visible = true + } + else noCustomerContact.visible = true + } +} diff --git a/Gui/Customer/CustomerDetailsView.qml b/Gui/Customer/CustomerDetailsView.qml new file mode 100644 index 0000000..c69ac2b --- /dev/null +++ b/Gui/Customer/CustomerDetailsView.qml @@ -0,0 +1,225 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +GridLayout +{ + columns: 2 + rowSpacing: 25 + SplitView.preferredWidth: clDetView.width / 3 * 1.8 + + // Grid row + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Steuer-ID") + font.bold: true + } + + Label + { + color: "goldenrod" + text: client['business']['tax']? client['business']['tax']: "" + } + } + + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Anmerkungen") + font.bold: true + } + + Label + { + color: "goldenrod" + text: client['business']['info']? client['business']['info']: "" + } + } + + // Grid row + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Kundenname") + font.bold: true + } + + Label + { + color: "goldenrod" + text: client['business']['company'] + } + } + + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("CEO") + font.bold: true + } + + Label + { + color: "goldenrod" + text: client['business']['ceo'] + } + } + + // Grid row + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Telefon") + font.bold: true + } + + Label + { + color: "goldenrod" + text: client['business']['phone']? client['business']['phone']: "" + } + } + + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Handy") + font.bold: true + } + + Label + { + color: "goldenrod" + text: client['business']['cell']? client['business']['cell']: "" + } + } + + // Grid row + ColumnLayout + { + Label + { + color: "darksalmon" + text: qsTr("Webseite") + font.bold: true + } + + Label + { + id: clientWebsite + color: "goldenrod" + font.underline: false + text: client['business']['website']? '' + client['business']['website'] + '': "" + 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']? '' + client['business']['email'] + '': "" + 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 + // } +} diff --git a/Gui/Customer/CustomerView.qml b/Gui/Customer/CustomerView.qml new file mode 100644 index 0000000..0e6da5b --- /dev/null +++ b/Gui/Customer/CustomerView.qml @@ -0,0 +1,293 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +GridLayout +{ + id: customerView + columns: 4 + Layout.fillWidth: true + Layout.fillHeight: true + rowSpacing: 9 + property alias businesstxt: firmenName + property alias street: streetid + property alias postcodetxt: postcode + property alias citytxt: city + Label + { + id: lblFirmenName + text: qsTr("Firmenname*") + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + + } + TextField + { + property string name: "business" + + id: firmenName + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + onTextChanged: checkFields() + Layout.columnSpan: 3 + } + Label + { + text: qsTr("Land") + 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 + + } + Label + { + text: qsTr("PLZ") + Layout.alignment: Qt.AlignRight + } + + + + + ComboBox + { + property string name: "postcode" + id: postcode + Layout.fillWidth: true + editable: true + onCurrentTextChanged: checkFields() + onEditTextChanged: checkFields() + onActivated: currentValue + model: address_model + textRole: "display" + popup.height: 300 + currentIndex: -1 + onCurrentIndexChanged: city.currentIndex = postcode.currentIndex + Layout.columnSpan: 3 + validator: RegularExpressionValidator + { + regularExpression: /([0-9]{1,5})/ + } + + } + + Label + { + text: qsTr("Ort") + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + } + ComboBox + { + property string name: "city" + id: city + Layout.fillWidth: true + editable: true + onEditTextChanged: checkFields() + onCurrentTextChanged: checkFields() + model: address_model + textRole: "city" + popup.height: 300 + currentIndex: -1 + Layout.columnSpan: 3 + } + Label + { + text: qsTr("Straße*") + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + } + + TextField + { + property string name: "street" + id: streetid + Layout.fillWidth: true + onTextChanged: checkFields() + } + + Label + { + text: qsTr("Nr.*") + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + } + + TextField + { + property string name: "houseno" + id: housenoid + Layout.fillWidth: true + onTextChanged: checkFields() + validator: RegularExpressionValidator + { + regularExpression: /([0-9a-zA-Z\-]{1,6})/ + } + } + + + + + Label + { + text: qsTr("Telefon") + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + } + TextField + { + property string name: "telephone" + id: telephone + Layout.fillWidth: true + Layout.columnSpan: 3 + validator: RegularExpressionValidator + { + regularExpression: /([+0-9]{1})([0-9]{1,17})/ + } + + } + + Label + { + text: qsTr("Mobil") + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + } + TextField + { + property string name: "cellphone" + id: cellphone + Layout.fillWidth: true + Layout.columnSpan: 3 + validator: RegularExpressionValidator + { + regularExpression: /([+0-9]{1})([0-9]{1,17})/ + } + } + + Label + { + text: qsTr("E-Mail") + Layout.alignment: Qt.AlignRight + } + TextField + { + property string name: "email" + id: email + Layout.fillWidth: true + placeholderText: qsTr("beispiel@domain.de") + Layout.columnSpan: 3 + validator: RegularExpressionValidator + { + regularExpression: /([\+!#$%&‘\*\–\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/ + } + } + + Label + { + text: qsTr("Homepage") + Layout.alignment: Qt.AlignRight + } + TextField + { + property string name: "homepage" + id: homepage + Layout.fillWidth: true + Layout.columnSpan: 3 + placeholderText: "www.oschkarischtverhaftetwegensexy.jinx" + } + + Label + { + text: qsTr("Geschäftsführer") + Layout.alignment: Qt.AlignRight + } + TextField + { + property string name: "ceo" + id: ceo + Layout.fillWidth: true + Layout.columnSpan: 3 + } + + Label + { + text: qsTr("USt-IdNr") + Layout.alignment: Qt.AlignRight + } + TextField + { + property string name: "taxno" + id: taxno + Layout.fillWidth: true + Layout.columnSpan: 3 + } + Label + { + text: qsTr("Typ") + Layout.alignment: Qt.AlignRight + } + ComboBox + { + property string name: "typeid" + id: typeid + Layout.fillWidth: true + editable: false + model: business_type + textRole: "display" + Layout.columnSpan: 3 + } + Label + { + text: qsTr("Info") + Layout.alignment: Qt.AlignRight | Qt.AlignTop + } + + ScrollView + { + id: infoView + Layout.fillWidth: true + Layout.preferredHeight: 100 + Layout.columnSpan: 3 + ScrollBar.horizontal: ScrollBar + { + policy: ScrollBar.AlwaysOn + } + + TextArea + { + property string name: "customerinfo" + id: customerInfo + implicitWidth: parent.width + wrapMode: TextEdit.Wrap + background: Rectangle + { + color: customerInfo.palette.base + border.color: customerInfo.activeFocus? customerInfo.palette.highlight: customerInfo.palette.base + } + } + } + function checkBusinessField() + { + if (!firmenName.text.trim() || !streetid.text.trim()) + { + return false + + } + else + { + if (!postcode.editText.trim() || !postcode.currentText || !city.editText.trim() || !city.currentText) + return false + else + return true + } + + } +} diff --git a/Gui/Customer/CustomersTable.qml b/Gui/Customer/CustomersTable.qml new file mode 100644 index 0000000..661ebec --- /dev/null +++ b/Gui/Customer/CustomersTable.qml @@ -0,0 +1,177 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Qt.labs.qmlmodels + +ColumnLayout { + property var availableFilters: ["Name", "Adresse", "PLZ", "Ort"] + + function viewCriterion(criterion) + { + business_model.viewCriterion(criterion.text); + } + + + + anchors.fill: parent + spacing: Dimensions.l + + Component.onCompleted: contentStack.pop() + + RowLayout + { + Layout.fillWidth: true + spacing: Dimensions.l + + + SearchBar + { + } + QuickFilter { + onSelectedChanged: (name) => { + business_model.viewCriterion(name) + } + + model: ListModel { + ListElement { + + name: "Alle" + text: qsTr("Alle") + selected: true + } + ListElement { + name: "Interessent" + text: qsTr("Interessent") + selected: false + } + ListElement { + name: "Kunde" + text: qsTr("Kunde") + selected: false + } + ListElement { + name: "Lieferant" + text: qsTr("Lieferant") + selected: false + } + ListElement { + name: "Erledigt" + text: qsTr("Erledigt") + selected: false + } + } + } + Button + { + id: addCustomer + + Layout.alignment: Qt.AlignRight + icon.source: "qrc:/images/PlusCircle.svg" + text: qsTr("Kunde Hinzufügen") + onClicked: contentStack.push("AddCustomer.qml") + } + } + ColumnLayout + { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.verticalStretchFactor: 1 + clip: true + + HorizontalHeaderView + { + id: horizontalHeader + + Layout.fillWidth: true + implicitHeight: 40 + movableColumns: true //@disable-check M16 + syncView: customerTable + + delegate: Rectangle + { + Layout.fillWidth: true + border.color: addCustomer.palette.base + color: addCustomer.palette.alternateBase + implicitHeight: 40 + implicitWidth: 1 + + Text + { + color: addCustomer.palette.text + elide: Text.ElideRight + height: parent.height + horizontalAlignment: Text.AlignHCenter + text: model.display + verticalAlignment: Text.AlignVCenter + width: parent.width + } + } + } + TableView { + id: customerTable + + property real newWidth: 0 + + Layout.fillHeight: true + Layout.fillWidth: true + alternatingRows: true + columnSpacing: 1 + model: business_model + resizableColumns: true + rowSpacing: 2 + selectionBehavior: TableView.SelectRows + z: 1 + + ScrollBar.vertical: ScrollBar { + policy: customerTable.contentHeight > customerTable.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff + } + delegate: Rectangle { + required property bool current + required property bool selected + + color: selected ? addCustomer.palette.highlight //palette.highlight + : (customerTable.alternatingRows && row % 2 !== 0 ? addCustomer.palette.base // palette.base + : addCustomer.palette.alternateBase) //palette.alternateBase) + implicitHeight: 25 + implicitWidth: customerTable.width / customerTable.columns + + Text { + color: addCustomer.palette.text + elide: Text.ElideRight + height: parent.height + leftPadding: 9 + text: model.display == null ? "" : model.display // @disable-check M126 + verticalAlignment: Text.AlignVCenter + width: parent.width + } + MouseArea { + id: mouseArea + + property bool hovered: false + + anchors.fill: parent + hoverEnabled: true + + onDoubleClicked: { + business_model.onRowClicked(row); + contentStack.push("CustomerDetails.qml", { + selectedClient: row + }); + } + onEntered: { + customerTable.selectionModel.select(customerTable.model.index(row, 0), ItemSelectionModel.SelectCurrent | ItemSelectionModel.Rows); + } + } + } + selectionModel: ItemSelectionModel { + id: selModel + + model: customerTable.model + } + } + + } + Item { + Layout.fillHeight: true + } +} diff --git a/Gui/Customer/qmldir b/Gui/Customer/qmldir new file mode 100644 index 0000000..5df1e15 --- /dev/null +++ b/Gui/Customer/qmldir @@ -0,0 +1 @@ +module Customer diff --git a/Gui/CustomerView.qml b/Gui/CustomerView.qml index 09a8622..b22491a 100644 --- a/Gui/CustomerView.qml +++ b/Gui/CustomerView.qml @@ -1,271 +1,271 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts +// import QtQuick +// import QtQuick.Controls +// import QtQuick.Layouts -GridLayout -{ - id: customerView - columns: 4 - Layout.fillWidth: true - Layout.fillHeight: true - rowSpacing: 9 - property alias businesstxt: firmenName - property alias street: streetid - property alias postcodetxt: postcode - property alias citytxt: city - Label - { - id: lblFirmenName - text: qsTr("Firmenname*") - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter +// GridLayout +// { +// id: customerView +// columns: 4 +// Layout.fillWidth: true +// Layout.fillHeight: true +// rowSpacing: 9 +// property alias businesstxt: firmenName +// property alias street: streetid +// property alias postcodetxt: postcode +// property alias citytxt: city +// Label +// { +// id: lblFirmenName +// text: qsTr("Firmenname*") +// Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - } - TextField - { - property string name: "business" +// } +// TextField +// { +// property string name: "business" - id: firmenName - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter - onTextChanged: checkFields() - Layout.columnSpan: 3 - } +// id: firmenName +// Layout.fillWidth: true +// Layout.alignment: Qt.AlignVCenter +// onTextChanged: checkFields() +// Layout.columnSpan: 3 +// } - Label - { - text: qsTr("Straße*") - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - } +// Label +// { +// text: qsTr("Straße*") +// Layout.alignment: Qt.AlignRight | Qt.AlignVCenter +// } - TextField - { - property string name: "street" - id: streetid - Layout.fillWidth: true - onTextChanged: checkFields() - } +// TextField +// { +// property string name: "street" +// id: streetid +// Layout.fillWidth: true +// onTextChanged: checkFields() +// } - Label - { - text: qsTr("Nr.*") - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - } +// 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})/ - } - } +// TextField +// { +// property string name: "houseno" +// id: housenoid +// Layout.fillWidth: true +// onTextChanged: checkFields() +// validator: RegularExpressionValidator +// { +// regularExpression: /([0-9a-zA-Z\-]{1,6})/ +// } +// } - Label - { - text: qsTr("PLZ") - Layout.alignment: Qt.AlignRight - } +// Label +// { +// text: qsTr("PLZ") +// Layout.alignment: Qt.AlignRight +// } - ComboBox - { - property string name: "postcode" - id: postcode - Layout.fillWidth: true - editable: true - onCurrentTextChanged: checkFields() - onEditTextChanged: checkFields() - onActivated: currentValue - model: address_model - textRole: "display" - popup.height: 300 - currentIndex: -1 - onCurrentIndexChanged: city.currentIndex = postcode.currentIndex - Layout.columnSpan: 3 - validator: RegularExpressionValidator - { - regularExpression: /([0-9]{1,5})/ - } +// ComboBox +// { +// property string name: "postcode" +// id: postcode +// Layout.fillWidth: true +// editable: true +// onCurrentTextChanged: checkFields() +// onEditTextChanged: checkFields() +// onActivated: currentValue +// model: address_model +// textRole: "display" +// popup.height: 300 +// currentIndex: -1 +// onCurrentIndexChanged: city.currentIndex = postcode.currentIndex +// Layout.columnSpan: 3 +// validator: RegularExpressionValidator +// { +// regularExpression: /([0-9]{1,5})/ +// } - } +// } - Label - { - text: qsTr("Ort") - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - } - ComboBox - { - property string name: "city" - id: city - Layout.fillWidth: true - editable: true - onEditTextChanged: checkFields() - onCurrentTextChanged: checkFields() - model: address_model - textRole: "city" - popup.height: 300 - currentIndex: -1 - Layout.columnSpan: 3 - } +// Label +// { +// text: qsTr("Ort") +// Layout.alignment: Qt.AlignRight | Qt.AlignVCenter +// } +// ComboBox +// { +// property string name: "city" +// id: city +// Layout.fillWidth: true +// editable: true +// onEditTextChanged: checkFields() +// onCurrentTextChanged: checkFields() +// model: address_model +// textRole: "city" +// popup.height: 300 +// currentIndex: -1 +// Layout.columnSpan: 3 +// } - Label - { - text: qsTr("Telefon") - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - } - TextField - { - property string name: "telephone" - id: telephone - Layout.fillWidth: true - Layout.columnSpan: 3 - validator: RegularExpressionValidator - { - regularExpression: /([+0-9]{1})([0-9]{1,17})/ - } +// Label +// { +// text: qsTr("Telefon") +// Layout.alignment: Qt.AlignRight | Qt.AlignVCenter +// } +// TextField +// { +// property string name: "telephone" +// id: telephone +// Layout.fillWidth: true +// Layout.columnSpan: 3 +// validator: RegularExpressionValidator +// { +// regularExpression: /([+0-9]{1})([0-9]{1,17})/ +// } - } +// } - Label - { - text: qsTr("Mobil") - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - } - TextField - { - property string name: "cellphone" - id: cellphone - Layout.fillWidth: true - Layout.columnSpan: 3 - validator: RegularExpressionValidator - { - regularExpression: /([+0-9]{1})([0-9]{1,17})/ - } - } +// Label +// { +// text: qsTr("Mobil") +// Layout.alignment: Qt.AlignRight | Qt.AlignVCenter +// } +// TextField +// { +// property string name: "cellphone" +// id: cellphone +// Layout.fillWidth: true +// Layout.columnSpan: 3 +// validator: RegularExpressionValidator +// { +// regularExpression: /([+0-9]{1})([0-9]{1,17})/ +// } +// } - Label - { - text: qsTr("E-Mail") - Layout.alignment: Qt.AlignRight - } - TextField - { - property string name: "email" - id: email - Layout.fillWidth: true - placeholderText: qsTr("beispiel@domain.de") - Layout.columnSpan: 3 - validator: RegularExpressionValidator - { - regularExpression: /([\+!#$%&‘\*\–\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/ - } - } +// Label +// { +// text: qsTr("E-Mail") +// Layout.alignment: Qt.AlignRight +// } +// TextField +// { +// property string name: "email" +// id: email +// Layout.fillWidth: true +// placeholderText: qsTr("beispiel@domain.de") +// Layout.columnSpan: 3 +// validator: RegularExpressionValidator +// { +// regularExpression: /([\+!#$%&‘\*\–\/\=?\^_`\.{|}\~\-\_0-9A-Za-z]{1,185})@([0-9A-Za-z\.\-\_]{1,64})\.([a-zA-z]{2,5})/ +// } +// } - Label - { - text: qsTr("Homepage") - Layout.alignment: Qt.AlignRight - } - TextField - { - property string name: "homepage" - id: homepage - Layout.fillWidth: true - Layout.columnSpan: 3 - placeholderText: "www.oschkarischtverhaftetwegensexy.jinx" - } +// Label +// { +// text: qsTr("Homepage") +// Layout.alignment: Qt.AlignRight +// } +// TextField +// { +// property string name: "homepage" +// id: homepage +// Layout.fillWidth: true +// Layout.columnSpan: 3 +// placeholderText: "www.oschkarischtverhaftetwegensexy.jinx" +// } - Label - { - text: qsTr("Geschäftsführer") - Layout.alignment: Qt.AlignRight - } - TextField - { - property string name: "ceo" - id: ceo - Layout.fillWidth: true - Layout.columnSpan: 3 - } +// Label +// { +// text: qsTr("Geschäftsführer") +// Layout.alignment: Qt.AlignRight +// } +// TextField +// { +// property string name: "ceo" +// id: ceo +// Layout.fillWidth: true +// Layout.columnSpan: 3 +// } - Label - { - text: qsTr("USt-IdNr") - Layout.alignment: Qt.AlignRight - } - TextField - { - property string name: "taxno" - id: taxno - Layout.fillWidth: true - Layout.columnSpan: 3 - } - Label - { - text: qsTr("Typ") - Layout.alignment: Qt.AlignRight - } - ComboBox - { - property string name: "typeid" - id: typeid - Layout.fillWidth: true - editable: false - model: business_type - textRole: "display" - Layout.columnSpan: 3 - } - Label - { - text: qsTr("Info") - Layout.alignment: Qt.AlignRight | Qt.AlignTop - } +// Label +// { +// text: qsTr("USt-IdNr") +// Layout.alignment: Qt.AlignRight +// } +// TextField +// { +// property string name: "taxno" +// id: taxno +// Layout.fillWidth: true +// Layout.columnSpan: 3 +// } +// Label +// { +// text: qsTr("Typ") +// Layout.alignment: Qt.AlignRight +// } +// ComboBox +// { +// property string name: "typeid" +// id: typeid +// Layout.fillWidth: true +// editable: false +// model: business_type +// textRole: "display" +// Layout.columnSpan: 3 +// } +// Label +// { +// text: qsTr("Info") +// Layout.alignment: Qt.AlignRight | Qt.AlignTop +// } - ScrollView - { - id: infoView - Layout.fillWidth: true - Layout.preferredHeight: 100 - Layout.columnSpan: 3 - ScrollBar.horizontal: ScrollBar - { - policy: ScrollBar.AlwaysOn - } +// ScrollView +// { +// id: infoView +// Layout.fillWidth: true +// Layout.preferredHeight: 100 +// Layout.columnSpan: 3 +// ScrollBar.horizontal: ScrollBar +// { +// policy: ScrollBar.AlwaysOn +// } - TextArea - { - property string name: "customerinfo" - id: customerInfo - implicitWidth: parent.width - wrapMode: TextEdit.Wrap - background: Rectangle - { - color: customerInfo.palette.base - border.color: customerInfo.activeFocus? customerInfo.palette.highlight: customerInfo.palette.base - } - } - } - function checkBusinessField() - { - if (!firmenName.text.trim() || !streetid.text.trim()) - { - return false +// TextArea +// { +// property string name: "customerinfo" +// id: customerInfo +// implicitWidth: parent.width +// wrapMode: TextEdit.Wrap +// background: Rectangle +// { +// color: customerInfo.palette.base +// border.color: customerInfo.activeFocus? customerInfo.palette.highlight: customerInfo.palette.base +// } +// } +// } +// function checkBusinessField() +// { +// if (!firmenName.text.trim() || !streetid.text.trim()) +// { +// return false - } - else - { - if (!postcode.editText.trim() || !postcode.currentText || !city.editText.trim() || !city.currentText) - return false - else - return true - } +// } +// else +// { +// if (!postcode.editText.trim() || !postcode.currentText || !city.editText.trim() || !city.currentText) +// return false +// else +// return true +// } - } -} +// } +// } diff --git a/Gui/Navigation.qml b/Gui/Navigation.qml index 5dbba06..5838039 100644 --- a/Gui/Navigation.qml +++ b/Gui/Navigation.qml @@ -31,7 +31,7 @@ ColumnLayout { BarButton { ButtonGroup.group: mainNav icon.source: "qrc:/images/UserGroup-Outline.svg" - target: "/Gui/CustomersTable.qml" + target: "/Gui/Customer/CustomersTable.qml" text: qsTr("Kunden") visible: !onSubPage } diff --git a/Gui/main.qml b/Gui/main.qml index 41dac0e..1d57b7d 100644 --- a/Gui/main.qml +++ b/Gui/main.qml @@ -18,13 +18,13 @@ ApplicationWindow { } font: Typography.body - height: Screen.height * .85 + height: Screen.desktopAvailableHeight palette.window: Colors.mantle palette.placeholderText: Colors.interactive palette.text: Colors.foreground title: "TERO Personal" visible: true - width: Screen.width * .75 + width: Screen.desktopAvailableWidth Component.onCompleted: { systray.activated.connect(showWindow); diff --git a/Gui/qmldir b/Gui/qmldir index 2302c4f..bf61494 100644 --- a/Gui/qmldir +++ b/Gui/qmldir @@ -1,2 +1,3 @@ module gui Navigation 1.0 Navigation.qml +AddContact 1.0 AddContact.qml diff --git a/lib/DB/AddressModel.py b/lib/DB/AddressModel.py index ed90ed1..5492c47 100644 --- a/lib/DB/AddressModel.py +++ b/lib/DB/AddressModel.py @@ -19,12 +19,16 @@ class AddressModel(QAbstractListModel): elif role == PyqcrmDataRoles.CITY_ROLE: data = self.__address_data[row][4] return data + elif role == PyqcrmDataRoles.COUNTRY_ROLE: + data = self.__address_data[row][3] + return data return None def roleNames(self): return { Qt.DisplayRole: b"display", PyqcrmDataRoles.CITY_ROLE: b"city", + PyqcrmDataRoles.COUNTRY_ROLE: b"country" } def setData(self): diff --git a/lib/PyqcrmDataRoles.py b/lib/PyqcrmDataRoles.py index 12c8a28..8947eec 100644 --- a/lib/PyqcrmDataRoles.py +++ b/lib/PyqcrmDataRoles.py @@ -6,5 +6,6 @@ from enum import IntEnum class PyqcrmDataRoles(IntEnum): CITY_ROLE = Qt.UserRole + 100 STREET_IN_POSTCODE = CITY_ROLE + 1 + COUNTRY_ROLE = CITY_ROLE + 100 diff --git a/main.py b/main.py index 07ff0b3..cf10541 100644 --- a/main.py +++ b/main.py @@ -22,6 +22,7 @@ from lib.Printers import Printers os.environ['QML_XHR_ALLOW_FILE_READ'] = '1' + # [pyqcrm] # program-name="" # version= diff --git a/pyqcrm.pyproject.user.6c31db7 b/pyqcrm.pyproject.user.6c31db7 new file mode 100644 index 0000000..9de842d --- /dev/null +++ b/pyqcrm.pyproject.user.6c31db7 @@ -0,0 +1,180 @@ + + + + + + EnvironmentId + {6c31db7b-2c94-4111-b0dc-25005cece3f8} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 0 + 80 + true + true + 1 + 0 + false + true + false + 2 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + false + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 4 + true + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Python 3.13.1 + Python 3.13.1 + {bd928902-6673-464d-b976-4a1ba0e13d34} + 0 + 0 + 0 + + /home/dstoppek/anaconda3/envs/pyqcrm + + + true + Python.PysideBuildStep + /home/dstoppek/anaconda3/envs/pyqcrm/bin/pyside6-project + /home/dstoppek/anaconda3/envs/pyqcrm/bin/pyside6-uic + + 1 + Erstellen + Erstellen + ProjectExplorer.BuildSteps.Build + + + 0 + Bereinigen + Bereinigen + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Python 3.13.1 virtuelle Umgebung + Python.PySideBuildConfiguration + /home/dstoppek/anaconda3/envs/pyqcrm/bin/python + /home/dstoppek/anaconda3/envs/pyqcrm + + 1 + + + 0 + Deployment + Deployment + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + 0 + true + + 2 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + main.py + PythonEditor.RunConfiguration. + /home/dstoppek/Coden/Projekte/pyqcrm/main.py + false + /home/dstoppek/Coden/Projekte/pyqcrm/main.py + true + true + /home/dstoppek/Coden/Projekte/pyqcrm + :0 + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/qml.qrc b/qml.qrc index 4679f9a..6010001 100644 --- a/qml.qrc +++ b/qml.qrc @@ -74,7 +74,13 @@ Js/qmldir Js/JsLib.js Js/qmldict.js - TeroStyle/pushtest.qml + Gui/Customer/AddCustomer.qml + Gui/Customer/CustomerContactDetails.qml + Gui/Customer/CustomerDetails.qml + Gui/Customer/CustomerDetailsView.qml + Gui/Customer/CustomersTable.qml + Gui/Customer/CustomerView.qml + Gui/Customer/qmldir diff --git a/requirements.txt b/requirements.txt index 7d26b55..8897cdb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,5 @@ mariadb soundfile sounddevice reportlab +tomlkit +bcrypt