diff --git a/AA-Forms/FormAuftragDetail.Designer.cs b/AA-Forms/FormAuftragDetail.Designer.cs index 68cb570..ec884d1 100644 --- a/AA-Forms/FormAuftragDetail.Designer.cs +++ b/AA-Forms/FormAuftragDetail.Designer.cs @@ -92,10 +92,10 @@ this.buttonFertig.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.buttonFertig.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.buttonFertig.ForeColor = System.Drawing.Color.Black; - this.buttonFertig.Location = new System.Drawing.Point(557, 615); + this.buttonFertig.Location = new System.Drawing.Point(489, 615); this.buttonFertig.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.buttonFertig.Name = "buttonFertig"; - this.buttonFertig.Size = new System.Drawing.Size(267, 50); + this.buttonFertig.Size = new System.Drawing.Size(300, 50); this.buttonFertig.TabIndex = 14; this.buttonFertig.Text = "Speichern/Abschließen"; this.buttonFertig.UseVisualStyleBackColor = false; @@ -109,10 +109,10 @@ this.buttonAbbrechen.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.buttonAbbrechen.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.buttonAbbrechen.ForeColor = System.Drawing.Color.Black; - this.buttonAbbrechen.Location = new System.Drawing.Point(830, 615); + this.buttonAbbrechen.Location = new System.Drawing.Point(795, 615); this.buttonAbbrechen.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.buttonAbbrechen.Name = "buttonAbbrechen"; - this.buttonAbbrechen.Size = new System.Drawing.Size(267, 50); + this.buttonAbbrechen.Size = new System.Drawing.Size(300, 50); this.buttonAbbrechen.TabIndex = 0; this.buttonAbbrechen.Text = "Abbrechen"; this.buttonAbbrechen.UseVisualStyleBackColor = false; @@ -364,7 +364,7 @@ this.oLVArtikel.View = System.Windows.Forms.View.Details; this.oLVArtikel.CellEditFinished += new BrightIdeasSoftware.CellEditEventHandler(this.oLVArtikel_CellEditFinished); this.oLVArtikel.CellEditStarting += new BrightIdeasSoftware.CellEditEventHandler(this.oLVArtikel_CellEditStarting); - this.oLVArtikel.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.oLVArtikel_ItemCheck); + this.oLVArtikel.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.OLVArtikel_ItemCheck); this.oLVArtikel.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.oLVArtikel_ItemChecked); this.oLVArtikel.SizeChanged += new System.EventHandler(this.oLVArtikel_SizeChanged); // diff --git a/AA-Forms/FormAuftragDetail.cs b/AA-Forms/FormAuftragDetail.cs index fdf3277..c7fa9f2 100644 --- a/AA-Forms/FormAuftragDetail.cs +++ b/AA-Forms/FormAuftragDetail.cs @@ -21,7 +21,8 @@ namespace Deckungsbeitrag { public partial class FormAuftragDetail : Form { - private Dictionary dictionary = new Dictionary(); + private Dictionary dictionary = new Dictionary(); + private Dictionary auftragDictionary = new Dictionary(); public Auftrag auftrag; public Benutzer benutzer; public List artikelList; @@ -197,16 +198,36 @@ namespace Deckungsbeitrag if (auftrag.Typ == AuftragTyp.Regelmäßig || (auftrag.Typ == AuftragTyp.Inventur & auftrag.Status == AuftragStatus.Herrichten)) { - foreach (OLVListItem item in this.oLVArtikel.Items) + foreach (var kvp in auftragDictionary) { - AuftragArtikel art = (AuftragArtikel)item.RowObject; - if (item.Checked) art.Erledigt = true; - else art.Erledigt = false; - - art.Save(); + AuftragArtikel aufart = AuftragArtikel.GetArtikel(kvp.Key); + aufart.Anzahl = (int)kvp.Value; + if (aufart.Anzahl == 0) aufart.Erledigt = true; + else aufart.Erledigt = false; + aufart.Save(); } + + //foreach (OLVListItem item in this.oLVArtikel.Items) + //{ + // AuftragArtikel art = (AuftragArtikel)item.RowObject; + // if (item.Checked) art.Erledigt = true; + // else art.Erledigt = false; + + // art.Save(); + //} if (auftrag.Typ == AuftragTyp.Inventur) { + foreach (var kvp in dictionary) + { + KundeArtikel kndart = KundeArtikel.GetItem(kvp.Key); + + kndart.Reklamation = kvp.Value[0]; + kndart.Fehlmenge = kvp.Value[1]; + kndart.Stand = kvp.Value[2]; + kndart.Korrektur = kvp.Value[3]; + + kndart.Save(); + } WriteToCSV(dictionary); } } @@ -215,12 +236,12 @@ namespace Deckungsbeitrag //SCHMUTZWÄSCHESCHEIN DRUCKEN private void EtikettDrucken() { - //DONE: Bestand von allen Artikeln speichern und für Druck vorbereiten. - //TODO: Erstellen von SonderAuftrag und Drucken von Etikett testen. - if (MessageBox.Show("Möchtest du Etiketten für die Änderung drucken?", "FRAGE", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + if (MessageBox.Show("Möchtest du JETZT Etiketten für die erfolgten Änderung drucken?", "FRAGE", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { - Funktionen.SonderEtikett_Drucken(this.auftrag, dictionary); - etikettgedruckt = true; + if (Funktionen.SonderEtikett_Drucken(this.auftrag, dictionary) == DialogResult.OK) + { + etikettgedruckt = true; + } } } @@ -264,7 +285,7 @@ namespace Deckungsbeitrag } //WENN LISTVIEW NICHT FOCUSED (FORM.LOAD) TOSAVE BLEIBT FALSE - private void oLVArtikel_ItemCheck(object sender, ItemCheckEventArgs e) + private void OLVArtikel_ItemCheck(object sender, ItemCheckEventArgs e) { ObjectListView olv = (ObjectListView)sender; if (e.NewValue != e.CurrentValue) { Tosave = true; } @@ -298,7 +319,8 @@ namespace Deckungsbeitrag private void buttonFertig_Click(object sender, EventArgs e) { EtikettDrucken(); - if (Tosave) AuftragSpeichern(); + if (Tosave && etikettgedruckt) AuftragSpeichern(); + else Toclose = false; if (Toclose) { if (int.Parse(this.labelContainer.Text) == 0) @@ -386,10 +408,9 @@ namespace Deckungsbeitrag } } Toclose = Tosave = false; + this.DialogResult = DialogResult.OK; + this.Close(); } - - this.DialogResult = DialogResult.OK; - this.Close(); } @@ -415,7 +436,7 @@ namespace Deckungsbeitrag /// SonderAuftrag in CSV-Liste eintragen. Jede Änderung wird in eine Zeile eingetragen. Rek./NW/Rest /// /// - private void WriteToCSV(Dictionary dictionary) + private void WriteToCSV(Dictionary dictionary) { Kunde _knd = Kunde.GetKunde(null, auftrag.KundeID, null); Benutzer _user = this.benutzer; @@ -456,7 +477,9 @@ namespace Deckungsbeitrag foreach (var kvp in dictionary) { - string artikelKey = kvp.Key; // z.B. "ART1" + KundeArtikel kndart = KundeArtikel.GetItem(kvp.Key); + Artikel _artikel = Artikel.GetArtikel(null, kndart.ArtikelID); + string artikelKey = _artikel.Bezeichnung; // z.B. "ART1" int[] artbestand = kvp.Value; // z.B. [3, 0, 5] int artikelIndex = Array.IndexOf(artikelArray, artikelKey); @@ -534,9 +557,15 @@ namespace Deckungsbeitrag if (e.Column.Text == "Anzahl") diff = (int)e.Value - ((int)e.NewValue); if (diff > 0) Tosave = true; - auftragArtikel.Anzahl = (int)e.NewValue; - auftragArtikel.Save(); - if (auftragArtikel.Anzahl == 0) e.ListViewItem.Checked = true; + if (auftragDictionary.TryGetValue((int)auftragArtikel.AuftragArtikelID, out int val)) + { + val = (int)e.NewValue; + if ((int)e.NewValue == 0) e.ListViewItem.Checked = true; + } + else auftragDictionary.Add((int)auftragArtikel.AuftragArtikelID, (int)e.NewValue); + + //auftragArtikel.Anzahl = (int)e.NewValue; + //auftragArtikel.Save(); KundeArtikel kndart = KundeArtikel.GetKundeArtikelVonArtikelID(this.kunde.KundeID, auftragArtikel.ArtikelID); @@ -545,20 +574,20 @@ namespace Deckungsbeitrag int stand = kndart.Stand; int korrektur = kndart.Korrektur; KorrigiereBestand(diff, ref reklamation, ref fehlmenge, ref stand, ref korrektur); - kndart.Reklamation = reklamation; - kndart.Fehlmenge = fehlmenge; - kndart.Stand = stand; - kndart.Korrektur = korrektur; + //kndart.Reklamation = reklamation; + //kndart.Fehlmenge = fehlmenge; + //kndart.Stand = stand; + //kndart.Korrektur = korrektur; - kndart.Save(); - if (dictionary.TryGetValue(kndart.ArtikelName, out int[] value)) + //kndart.Save(); + if (dictionary.TryGetValue((int)kndart.KundeArtikelID, out int[] value)) { for (int i = 0; i < value.Length; i++) { value[i] += bestand[i]; } } - else dictionary.Add(kndart.ArtikelName, bestand); + else dictionary.Add((int)kndart.KundeArtikelID, bestand); //WriteToCSV(kndart); this.ResumeLayout(); this.Cursor = Cursors.Default; @@ -624,19 +653,17 @@ namespace Deckungsbeitrag { if (Tosave) { - if (MessageBox.Show("Möchtest du die Änderungen wirklich verwerfen?", "ÄNDERUNGEN VERWERFEN", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + if (MessageBox.Show("Möchtest du die Änderungen wirklich verwerfen?", "ÄNDERUNGEN VERWERFEN", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) { - this.DialogResult = DialogResult.Cancel; - this.Close(); + e.Cancel = true; + return; } - else { e.Cancel = true; return; } } - } } } -//DONE: Korrigiere Bestand: Wenn -Zahl dann Stand - Zahl. -//DONE: Speichern etc. durchgehen und adaptieren -//DONE: Feedback Button hinzufügen -//DONE: ComboBox Fahrer und Priorität implementieren -//DONE: Container schmutzig bearbeitbar machen \ No newline at end of file +//CHANGES: 1. Es wird ab sofort nur ein Button zum Speichern und Abschließen bereitgestellt. System entscheidet was getan wird. +//CHANGES: 2. Änderungen werden nur gespeichert wenn ein Etikett gedruckt wurde. +//CHANGES: 3. Abschließen nur möglich wenn alle Artikel auf 0 sind (Checked) und gespeichert wurde. +//CHANGES: Bei Druckabbruch wird die geänderte Zahl NICHT zurückgesetzt. (Das muss händisch erfolgen) +//CHANGES: Wenn die Zahlen zurückgesetzt werden sollen, muss AuftragDetail geschlossen werden. \ No newline at end of file diff --git a/AA-Forms/FormMain.cs b/AA-Forms/FormMain.cs index f3d320e..6de1282 100644 --- a/AA-Forms/FormMain.cs +++ b/AA-Forms/FormMain.cs @@ -600,7 +600,7 @@ namespace Deckungsbeitrag conn.Dispose(); } - if (alist.Count == 0) meldung.KeineAufträge(); + if (alist.Count == 0) { meldung.KeineAufträge(); this.groupBoxAuftrag.Visible = false; } else Load_OLV(alist); // Load_ListView(alist); this.objectListViewAuftrag.EndUpdate(); diff --git a/AA-Forms/FormNeuerAuftrag.Designer.cs b/AA-Forms/FormNeuerAuftrag.Designer.cs index 4bbc0f0..38f9f1c 100644 --- a/AA-Forms/FormNeuerAuftrag.Designer.cs +++ b/AA-Forms/FormNeuerAuftrag.Designer.cs @@ -364,13 +364,13 @@ namespace Deckungsbeitrag // // panelRegAuftrag // - this.panelRegAuftrag.Controls.Add(this.textBoxText); this.panelRegAuftrag.Controls.Add(this.pictureBoxAddArtikel); this.panelRegAuftrag.Controls.Add(this.label8); this.panelRegAuftrag.Controls.Add(this.comboBoxArtikel); this.panelRegAuftrag.Controls.Add(this.labelText); this.panelRegAuftrag.Controls.Add(this.comboBoxRhythmus); this.panelRegAuftrag.Controls.Add(this.fLPArtikel); + this.panelRegAuftrag.Controls.Add(this.textBoxText); this.panelRegAuftrag.Enabled = false; this.panelRegAuftrag.Location = new System.Drawing.Point(409, -2); this.panelRegAuftrag.Margin = new System.Windows.Forms.Padding(4); @@ -423,6 +423,7 @@ namespace Deckungsbeitrag this.comboBoxArtikel.FlatStyle = System.Windows.Forms.FlatStyle.System; this.comboBoxArtikel.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.comboBoxArtikel.FormattingEnabled = true; + this.comboBoxArtikel.IntegralHeight = false; this.comboBoxArtikel.Location = new System.Drawing.Point(25, 132); this.comboBoxArtikel.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.comboBoxArtikel.Name = "comboBoxArtikel"; diff --git a/AA-Forms/FormNeuerAuftrag.cs b/AA-Forms/FormNeuerAuftrag.cs index 7e523fb..034c661 100644 --- a/AA-Forms/FormNeuerAuftrag.cs +++ b/AA-Forms/FormNeuerAuftrag.cs @@ -1,4 +1,5 @@ -using DatenDB; +using BrightIdeasSoftware; +using DatenDB; using Deckungsbeitrag.AA_Forms; using Deckungsbeitrag.AA_Klassen; using Deckungsbeitrag.UserControls; @@ -84,9 +85,17 @@ namespace Deckungsbeitrag if (this.auftragtyp == AuftragTyp.Regelmäßig) {kndService = "Geschäft"; labelLiefertag.Text = "Erster Liefertag:"; } if (this.benutzer.Rolle == BenutzerRolle.Fahrer) kndService = "Geschäft"; - if (this.auftragtyp == null || this.auftragtyp == AuftragTyp.Geschäft) SonderDatenLaden(kndService); - else DatenLaden(kndService); + // Kunde laden + this.kunde = Funktionen.Open_List(kndService); + if (this.kunde == null) { CloseForm(DialogResult.Cancel); return; } + this.textBoxKndNr.Text = kunde.KundeNummer; + this.kundeName = this.textBoxKundeName.Text = this.kunde.Suchtext ?? this.kunde.KundeName; + this.textBoxKundeName.Enabled = false; + this.textBoxKndNr.Enabled = false; + + if (this.auftragtyp == null || this.auftragtyp == AuftragTyp.Geschäft) SonderDatenLaden(); + else DatenLaden(); } private async void FormNeuerAuftrag_HelpButtonClicked(object sender, CancelEventArgs e) { @@ -95,32 +104,15 @@ namespace Deckungsbeitrag ZeigeOnboarding(); } - private void SonderDatenLaden(string kndService) + private void SonderDatenLaden() { - // Kunde laden - this.kunde = Funktionen.Open_List(kndService); - if (this.kunde == null) { CloseForm(DialogResult.Cancel); return; } - - this.textBoxKndNr.Text = kunde.KundeNummer; - this.kundeName = this.textBoxKundeName.Text = this.kunde.Suchtext ?? this.kunde.KundeName; - this.textBoxKundeName.Enabled = false; - this.textBoxKndNr.Enabled = false; - // ComboBox Typ & Fahrer wird mit Items geladen ComboBoxTyp_Load(); ComboBoxFahrer_Load(); } - private void DatenLaden(string kndService) + private void DatenLaden() { this.SuspendLayout(); - // Kunde laden - this.kunde = Funktionen.Open_List(kndService); - if (this.kunde == null) { CloseForm(DialogResult.Cancel); return; } - - this.textBoxKndNr.Text = kunde.KundeNummer; - this.kundeName = this.textBoxKundeName.Text = this.kunde.Suchtext ?? this.kunde.KundeName; - this.textBoxKundeName.Enabled = false; - this.textBoxKndNr.Enabled = false; // Containeranzahl laden if (int.TryParse(Interaction.InputBox($"Wieviel Container hast du beim Kunde {kundeName} abgeholt?", "CONTAINERANZAHL", "1"), out int i)) this.textBoxCont.Text = i.ToString(); @@ -200,10 +192,6 @@ namespace Deckungsbeitrag } #region ComboBox-Events - /// - /// ComboBox wird mit AuftragTyp geladen. - /// SelectedItem wird gewählt. Wenn Kunde Service ist Geschäft dann Geschäft, sonst Prop. auftragtyp. - /// private void ComboBoxTyp_Load() { try @@ -212,6 +200,7 @@ namespace Deckungsbeitrag this.comboBoxTyp.SelectedValueChanged -= ComboBoxTyp_SelectedValueChanged; // Items werden von AuftragTyp geladen. this.comboBoxTyp.DataSource = Enum.GetValues(typeof(AuftragTyp)); + this.comboBoxTyp.DropDownWidth = GetDropDownWidth(this.comboBoxTyp); // Wenn der Kunde ein Geschäftskunde ist, wird AuftragTyp.Geschäft ausgewählt. Andernfalls wird der AuftragTyp aus dem Konstruktor gewählt. this.comboBoxTyp.SelectedValueChanged += ComboBoxTyp_SelectedValueChanged; @@ -230,11 +219,6 @@ namespace Deckungsbeitrag throw; } } - - /// - /// ComboBox wird mit Fahrerliste geladen. - /// Wenn Prop. tour ist leer wird Benutzername angezeigt, sonst Tourbezeichnung. - /// private void ComboBoxFahrer_Load() { Saison saison = Saison.GetAktivSaison(); @@ -242,7 +226,7 @@ namespace Deckungsbeitrag List tourliste = Tour.GetSaisonListe(saison); this.comboBoxFahrer.DataSource = tourliste; this.comboBoxFahrer.DisplayMember = "Bezeichnung"; - + this.comboBoxFahrer.DropDownWidth = GetDropDownWidth(this.comboBoxFahrer); // ComboBox-Auswahl vordefinieren. if (this.benutzer.Rolle == BenutzerRolle.Fahrer) { @@ -265,55 +249,66 @@ namespace Deckungsbeitrag if (comboBoxTyp.SelectedValue != null) { switch ((AuftragTyp)comboBoxTyp.SelectedValue) - { - case AuftragTyp.Geschäft: // Wird derzeit wenig verwendet da die Auswahl in DatenLaden nach KundenService erfolgt. - this.Width = textBoxKundeName.Right + 30; - this.Height = 470; - break; - case AuftragTyp.Standart: - this.Width = textBoxKundeName.Right + 30; - this.Height = 470; - break; - case AuftragTyp.Inventur: - this.DialogResult = DialogResult.Abort; - this.Close(); - break; - case AuftragTyp.SOLL_Erhoehung: - if (this.kunde == null) return; - - this.panelRegAuftrag.Enabled = this.panelRegAuftrag.Visible = true; - this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = false; - this.Width = this.panelRegAuftrag.Right + 25; - this.Height = 470; - break; - case AuftragTyp.SOLL_Verminderung: - if (this.kunde == null) return; - - this.panelRegAuftrag.Enabled = this.panelRegAuftrag.Visible = true; - this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = false; - this.Width = this.panelRegAuftrag.Right + 25; - this.Height = 470; - break; - case AuftragTyp.Regelmäßig: - this.panelRegAuftrag.Enabled = this.panelRegAuftrag.Visible = true; - this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = false; - this.Width = this.panelRegAuftrag.Right + 25; - this.Height = 470; - break; - case AuftragTyp.AufAbruf: - this.Width = textBoxKundeName.Right + 30; - this.Height = 470; - break; - case AuftragTyp.Laufzettel: - this.panelRegAuftrag.Enabled = this.panelRegAuftrag.Visible = true; - this.textBoxText.Visible = true; - this.labelText.Text = "Laufzetteltext:"; - this.Width = this.panelRegAuftrag.Right + 25; - this.Height = 470; - break; - default: - break; - } + { + case AuftragTyp.Geschäft: // Wird derzeit wenig verwendet da die Auswahl in DatenLaden nach KundenService erfolgt. + this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = true; + this.Width = textBoxKundeName.Right + 30; + this.Height = 470; + break; + case AuftragTyp.Standart: + this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = true; + this.Width = textBoxKundeName.Right + 30; + this.Height = 470; + break; + case AuftragTyp.Inventur: + this.textBoxText.Visible = false; + this.DialogResult = DialogResult.Abort; + this.Close(); + break; + case AuftragTyp.SOLL_Erhoehung: + if (this.kunde == null) return; + this.textBoxText.Visible = false; + this.panelRegAuftrag.Enabled = this.panelRegAuftrag.Visible = true; + this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = false; + this.labelText.Text = "Rhythmus:"; + this.Width = this.panelRegAuftrag.Right + 25; + this.Height = 470; + break; + case AuftragTyp.SOLL_Verminderung: + if (this.kunde == null) return; + this.textBoxText.Visible = false; + this.panelRegAuftrag.Enabled = this.panelRegAuftrag.Visible = true; + this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = false; + this.labelText.Text = "Rhythmus:"; + this.Width = this.panelRegAuftrag.Right + 25; + this.Height = 470; + break; + case AuftragTyp.Regelmäßig: + this.textBoxText.Visible = false; + this.panelRegAuftrag.Enabled = this.panelRegAuftrag.Visible = true; + this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = false; + this.labelText.Text = "Rhythmus:"; + this.Width = this.panelRegAuftrag.Right + 25; + this.Height = 470; + break; + case AuftragTyp.AufAbruf: + this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = true; + this.Width = textBoxKundeName.Right + 30; + this.Height = 470; + break; + case AuftragTyp.Laufzettel: + this.panelRegAuftrag.Enabled = this.panelRegAuftrag.Visible = true; + this.textBoxText.Visible = true; + this.pictureBoxPlus.Enabled = this.pictureBoxMinus.Enabled = this.textBoxCont.Enabled = false; + this.labelText.Text = "Laufzetteltext:"; + this.Width = this.panelRegAuftrag.Right + 25; + this.Height = 470; + this.textBoxText.BringToFront(); + break; + default: + break; + } + PanelRegAuftrag_EnabledChanged(this.panelRegAuftrag, null); } else { @@ -354,7 +349,6 @@ namespace Deckungsbeitrag if (string.IsNullOrWhiteSpace(eingabe)) e.Cancel = true; } } - #endregion /// /// ComboBox Artikel & Rhythmus wird geladen. @@ -375,31 +369,34 @@ namespace Deckungsbeitrag List artikelListe; if ((AuftragTyp)comboBoxTyp.SelectedValue == AuftragTyp.Regelmäßig) artikelListe = Artikel.GetRegArtikelList(); else artikelListe = Artikel.GetArtikelList("Alle"); + if (artikelListe.Count == 0) + { + MessageBox.Show("Auswahl für den gewählten Kunden nicht verfügbar.", "FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Error); + this.comboBoxTyp.SelectedIndex = -1; + return; + } comboBoxArtikel.DataSource = artikelListe; - comboBoxArtikel.DisplayMember = "Bezeichnung"; - foreach (Artikel art in artikelListe) - { - int bezWidth = TextRenderer.MeasureText(art.Bezeichnung, comboBoxArtikel.Font).Width; - if (dropdownWidth < bezWidth) dropdownWidth = bezWidth; - } - comboBoxArtikel.DropDownWidth = dropdownWidth; + comboBoxArtikel.DisplayMember = "ComboBoxAnzeige"; + comboBoxArtikel.DropDownWidth = GetDropDownWidth(comboBoxArtikel); comboBoxArtikel.SelectedIndex = -1; comboBoxRhythmus.DataSource = Enum.GetValues(typeof(RegRhythmen)); comboBoxRhythmus.SelectedIndex = -1; + comboBoxRhythmus.Enabled = true; } - if ((AuftragTyp)comboBoxTyp.SelectedValue == AuftragTyp.SOLL_Erhoehung || (AuftragTyp)comboBoxTyp.SelectedValue == AuftragTyp.SOLL_Verminderung) + if ((AuftragTyp)comboBoxTyp.SelectedValue == AuftragTyp.SOLL_Erhoehung || (AuftragTyp)comboBoxTyp.SelectedValue == AuftragTyp.SOLL_Verminderung || (AuftragTyp)comboBoxTyp.SelectedValue == AuftragTyp.IST_Erhoehung) { List kndartikel = KundeArtikel.GetList(this.kunde.KundeID.ToString()); - comboBoxArtikel.DataSource = kndartikel; - comboBoxArtikel.DisplayMember = "ArtikelName"; - foreach (KundeArtikel art in kndartikel) + if (kndartikel.Count == 0) { - int bezWidth = TextRenderer.MeasureText(art.ArtikelName, comboBoxArtikel.Font).Width; - if (dropdownWidth < bezWidth) dropdownWidth = bezWidth; + MessageBox.Show("Auswahl für den gewählten Kunden nicht verfügbar.", "FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Error); + this.comboBoxTyp.SelectedIndex = -1; + return; } - comboBoxArtikel.DropDownWidth = dropdownWidth; + comboBoxArtikel.DataSource = kndartikel; + comboBoxArtikel.DisplayMember = "ComboBoxAnzeige"; + comboBoxArtikel.DropDownWidth = GetDropDownWidth(comboBoxArtikel); comboBoxArtikel.SelectedIndex = -1; comboBoxRhythmus.Enabled = false; @@ -408,6 +405,18 @@ namespace Deckungsbeitrag comboBoxArtikel.SelectedIndexChanged += ComboBoxArtikel_SelectedIndexChanged; } + private int GetDropDownWidth(ComboBox cb) + { + int maxLenght = 0; + foreach (object item in cb.Items) + { + int bezWidth = TextRenderer.MeasureText(cb.GetItemText(item), cb.Font).Width; + if (maxLenght < bezWidth) maxLenght = bezWidth; + } + return maxLenght; + } + #endregion + #region Click Events private void ButtonAbbrechen_Click(object sender, EventArgs e) @@ -668,7 +677,7 @@ namespace Deckungsbeitrag if (this.benutzer.Rolle == BenutzerRolle.Fahrer) { this.Auftrag = null; - DatenLaden(string.Empty); + DatenLaden(); } } @@ -736,6 +745,7 @@ namespace Deckungsbeitrag { foreach (Control ctr in this.panelRegAuftrag.Controls) if (!ctr.Name.Contains("Text")) ctr.Enabled = false; } + else foreach (Control ctr in this.panelRegAuftrag.Controls) if (!ctr.Name.Contains("Text")) ctr.Enabled = true; } private void CloseForm(DialogResult result) { @@ -744,4 +754,7 @@ namespace Deckungsbeitrag } } } -//TODO: TourenListe Entwurf muss überarbeitet werden. \ No newline at end of file +//CHANGES: Es kann ab jetzt Morgen als Liefertag gewählt werden. +//CHANGES: Auftrag LAUFZETTEL (ehem. Einmalig) läuft als Sonderauftrag also Tab-Sonderaufträge. +//CHANGES: Der Text des LAUFZETTELS wird bei Expedit im InfoFeld angezeigt. +//CHANGES: DropDownWidth wird an das größte Item angepasst. \ No newline at end of file diff --git a/AA-Klassen/Artikel.cs b/AA-Klassen/Artikel.cs index 2a3e9c0..f35f85c 100644 --- a/AA-Klassen/Artikel.cs +++ b/AA-Klassen/Artikel.cs @@ -60,7 +60,11 @@ namespace DatenDB NpgsqlCommand command = new NpgsqlCommand(); command.Connection = DatenbankConnection.GetConnection(); if (artikelID != null) command.CommandText = $"select short from {TABLE} where artikel_id = {artikelID}"; - if (!string.IsNullOrWhiteSpace(artname)) command.CommandText = $"select short from {TABLE} where bezeichnung = '{artname}'"; + if (!string.IsNullOrWhiteSpace(artname)) + { + artname += "%"; + command.CommandText = $"select short from {TABLE} where bezeichnung ILIKE '{artname}'"; + } NpgsqlDataReader reader = command.ExecuteReader(); while (reader.Read()) result = reader.IsDBNull(0) ? string.Empty : reader.GetString(0); reader.Close(); @@ -237,7 +241,8 @@ namespace DatenDB } set { } } - + [OLVIgnore] + public string ComboBoxAnzeige => $"{Nummer} {Bezeichnung}"; #endregion } } diff --git a/AA-Klassen/Funktionen.cs b/AA-Klassen/Funktionen.cs index 384323c..586863d 100644 --- a/AA-Klassen/Funktionen.cs +++ b/AA-Klassen/Funktionen.cs @@ -45,7 +45,9 @@ namespace Deckungsbeitrag private static Benutzer _benutzer; private static PrintDocument printdoc; public static bool IsPhysicalPrint = false; // Globaler Schalter - static Dictionary _dictionary; + static Dictionary _dictionary; + private static bool printed = false; + private static bool inPreview = false; public Funktionen() { @@ -1081,7 +1083,7 @@ namespace Deckungsbeitrag } } } - public static Image SonderEtikett_Entwurf(Auftrag auftrag, Dictionary dictionary) + public static Image SonderEtikett_Entwurf(Auftrag auftrag, Dictionary dictionary) { Kunde kunde = Kunde.GetKunde(string.Empty, auftrag.KundeID, string.Empty); if (kunde.Suchtext.StartsWith("?") | kunde.KundeNummer == "2320000") kunde.Suchtext = auftrag.ZusatzInfo; @@ -1116,49 +1118,58 @@ namespace Deckungsbeitrag foreach (var kvp in dictionary) { - string artikelKey = kvp.Key; // z.B. "ART1" + KundeArtikel kndart = KundeArtikel.GetItem(kvp.Key); + Artikel _artikel = Artikel.GetArtikel(null, kndart.ArtikelID); + string artikelKey = _artikel.Bezeichnung; // z.B. "ART1" int[] artbestand = kvp.Value; // z.B. [3, 0, 5] - string shortName = Artikel.GetShort(null, artikelKey); + string shortName = _artikel.Short; + float bestandWidth = g.MeasureString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/({artbestand[2].ToString()})/{artbestand[3].ToString()}", font1).Width; g.DrawString($"{shortName}", font1, Brushes.Black, einzug, nextposition); - - if (artbestand[2] < 0) g.DrawString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/({artbestand[2].ToString()})/{artbestand[3].ToString()}", font1, Brushes.Black, einzug + g.MeasureString(shortName, font1).Width + 10, nextposition); - else g.DrawString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/{artbestand[2].ToString()}/{artbestand[3].ToString()}", font1, Brushes.Black, einzug + g.MeasureString(shortName, font1).Width + 10, nextposition); + if (artbestand[2] < 0) g.DrawString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/({artbestand[2].ToString()})/{artbestand[3].ToString()}", font1, Brushes.Black, bitmap.Width - bestandWidth - 10, nextposition); + else g.DrawString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/{artbestand[2].ToString()}/{artbestand[3].ToString()}", font1, Brushes.Black, bitmap.Width - bestandWidth - 10, nextposition); nextposition += (int)height_font1; } Image img = bitmap; return img; } - public static DialogResult SonderEtikett_Drucken(Auftrag auftrag, Dictionary dictionary) + public static DialogResult SonderEtikett_Drucken(Auftrag auftrag, Dictionary dictionary) { _auftrag = auftrag; _dictionary = dictionary; int x = auftrag.ContainerClean; + PrintDialog dialog = new PrintDialog(); PrintPreviewDialog preview = new PrintPreviewDialog(); PrintDocument printDocument = new PrintDocument(); - foreach (string printer in PrinterSettings.InstalledPrinters) if (printer.Contains(Properties.Settings.Default.Etikett_Drucker)) dialog.PrinterSettings.PrinterName = printer; + foreach (string printer in PrinterSettings.InstalledPrinters) + { + if (printer.Contains(Properties.Settings.Default.Etikett_Drucker)) + { + dialog.PrinterSettings.PrinterName = printer; + break; + } + } dialog.PrinterSettings.Copies = 2; if (dialog.ShowDialog() == DialogResult.OK) { printDocument.PrinterSettings = dialog.PrinterSettings; - printDocument.PrintPage += new PrintPageEventHandler(PrintDocument_PrintPage); + printDocument.PrintPage -= PrintDocument_PrintPage; + printDocument.PrintPage += PrintDocument_PrintPage; + + // Wenn Drucker ist NICHT Etikett_Drucker wird Papiergröße Custom gesetzt if (!printDocument.PrinterSettings.PrinterName.Contains(Properties.Settings.Default.Etikett_Drucker)) printDocument.DefaultPageSettings.PaperSize = new PaperSize("Etikett-Custom", 29, 90); - preview.StartPosition = FormStartPosition.CenterScreen; - preview.WindowState = FormWindowState.Normal; - preview.Document = printDocument; - preview.Document.DocumentName = "SonderEtikett"; - preview.ShowDialog(); - //dialog.Document = printDocument; - //dialog.Document.DocumentName = "Etikett"; - //printDocument.Print(); + + dialog.Document = printDocument; + dialog.Document.DocumentName = "SonderEtikett"; + + printDocument.Print(); return DialogResult.OK; } - - return DialogResult.Cancel; + else return DialogResult.Cancel; } private static void PrintDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { @@ -1188,7 +1199,11 @@ namespace Deckungsbeitrag e.HasMorePages = false; } if (sender.ToString().Contains("Etikett")) e.Graphics.DrawImage(Etikett_Entwurf(null, _auftrag, _nocont), e.PageBounds); - if (sender.ToString().Contains("Sonder")) e.Graphics.DrawImage(SonderEtikett_Entwurf(_auftrag, _dictionary), e.PageBounds); + if (sender.ToString().Contains("Sonder")) + { + if (!inPreview) printed = true; + e.Graphics.DrawImage(SonderEtikett_Entwurf(_auftrag, _dictionary), e.PageBounds); + } if (sender.ToString().Contains("TourenListe")) { if (pagesToPrint == currentPage) currentPage = 0; diff --git a/AA-Klassen/KundeArtikel.cs b/AA-Klassen/KundeArtikel.cs index 1b148ff..41146d7 100644 --- a/AA-Klassen/KundeArtikel.cs +++ b/AA-Klassen/KundeArtikel.cs @@ -259,6 +259,6 @@ namespace DatenDB public int? ArtikelID { get; set; } [OLVColumn("Reihung", IsVisible = false)] public int Reihung { get; set; } - + [OLVIgnore] public string ComboBoxAnzeige => $"{ArtikelNR} {ArtikelName}"; } } diff --git a/App.config b/App.config index 6484ec4..cd7ad7f 100644 --- a/App.config +++ b/App.config @@ -6,7 +6,7 @@ - + diff --git a/Program.cs b/Program.cs index ff38a2a..563525d 100644 --- a/Program.cs +++ b/Program.cs @@ -42,7 +42,7 @@ namespace Deckungsbeitrag public static Color Wirlblau = Settings.Default.Wirlblau; public static ImageList imagelist = new ImageList(); public static string userid; - public static Benutzer benutzer = new Benutzer(); + public static Benutzer benutzer; public static bool Artikelliste_Importiert = false; public static bool Kundenliste_Importiert = false; public static bool Software_Updated = false; @@ -124,7 +124,7 @@ namespace Deckungsbeitrag switch (userid) { case var s when s.Contains("wstrasse"): - benutzer = Benutzer.GetBenutzer(null, 4); + //benutzer = Benutzer.GetBenutzer(null, 4); Application.Run(new FormAufleger(userid)); break; case var s when s.Contains("frottee"): diff --git a/UpdateVerwaltungReadMe.ps1 b/UpdateVerwaltungReadMe.ps1 index 8f0d9c4..e9cb668 100644 --- a/UpdateVerwaltungReadMe.ps1 +++ b/UpdateVerwaltungReadMe.ps1 @@ -25,10 +25,6 @@ Build-Info: ##CHANGES## -##DONE_TODOS## - -##OPEN_TODOS## - Installation: ##BUILD_DATE## ===================================== "@ | Out-File $readmePath -Encoding UTF8 @@ -142,14 +138,9 @@ Build-Info: - Install-Reminders: $($installReminders.Count) - Changes: $($changes.Count) - -$installText - $changesText -`r`n$doneText - -`r`n$openText +$installText Installation: $buildDate ===================================== diff --git a/UserControls/UCInventur.cs b/UserControls/UCInventur.cs index 8a68390..2a6227a 100644 --- a/UserControls/UCInventur.cs +++ b/UserControls/UCInventur.cs @@ -400,7 +400,6 @@ namespace Deckungsbeitrag.UserControls if (groupBoxInventur.Visible) { - this.buttonFreigeben.Visible = false; this.labelInvText.Text = groupBoxInventur.Text; this.groupBoxInventur.Visible = false; this.labelInvText.Visible = true; @@ -467,7 +466,6 @@ namespace Deckungsbeitrag.UserControls uci_loc = this.Location; DataGridView_GetNewSize(this.dGArtikel); this.buttonFreigeben.Visible = true; - groupBoxInventur.Visible = true; this.labelInvText.Visible = false; } } @@ -569,6 +567,5 @@ namespace Deckungsbeitrag.UserControls } } } -//DONE: CLick auf Inventur freigeben Dateiname von "Warten" auf "Herrichten" ändern. -//DONE: Inventur freigeben nur für Admin oder Verwaltung. -//DONE: Inventur für Expedit zugänglich machen. +//CHANGES: Es wird jetzt nur ein Button "Speichern/Freigeben" bereitgestellt und dort dann gefragt ob speichern oder freigeben. Hier wird auch zwischen den Rollen unterschieden. +//CHANGES: Beim nachträglichen Ändern des Standes wird jetzt die Schwund-Spalte neu berechnet. Damit sollte die Berechnung wieder stimmen. \ No newline at end of file diff --git a/Verwaltung_ReadMe.txt b/Verwaltung_ReadMe.txt index 6351933..2a42ec0 100644 --- a/Verwaltung_ReadMe.txt +++ b/Verwaltung_ReadMe.txt @@ -4,20 +4,26 @@ NEUIGKEITEN - Version 1.0.9.6 Build-Info: - Build-Typ: Release Build -- Erledigte TODOs: 15 -- Offene TODOs: 26 +- Erledigte TODOs: 6 +- Offene TODOs: 24 - Install-Reminders: 1 -- Changes: 15 +- Changes: 26 - -=== ⚙️ INSTALL-REMINDER (1) === -- ⚙️ DB anpassen. (Priority in Auftrag etc.) [Auftrag.cs] - -=== ✨ CHANGES (15) === +=== ✨ CHANGES (26) === +- ✨ 1. Es wird ab sofort nur ein Button zum Speichern und Abschließen bereitgestellt. System entscheidet was getan wird. [FormAuftragDetail.cs] +- ✨ 2. Änderungen werden nur gespeichert wenn ein Etikett gedruckt wurde. [FormAuftragDetail.cs] +- ✨ 3. Abschließen nur möglich wenn alle Artikel auf 0 sind (Checked) und gespeichert wurde. [FormAuftragDetail.cs] - ✨ Artikelliste und Kundenliste werden automatisch importiert wenn vorhanden. [FormMain.cs] +- ✨ Auftrag LAUFZETTEL (ehem. Einmalig) läuft als Sonderauftrag also Tab-Sonderaufträge. [FormNeuerAuftrag.cs] +- ✨ Bei Druckabbruch wird die geänderte Zahl NICHT zurückgesetzt. (Das muss händisch erfolgen) [FormAuftragDetail.cs] +- ✨ Beim nachträglichen Ändern des Standes wird jetzt die Schwund-Spalte neu berechnet. Damit sollte die Berechnung wieder stimmen. [UCInventur.cs] +- ✨ Der Text des LAUFZETTELS wird bei Expedit im InfoFeld angezeigt. [FormNeuerAuftrag.cs] +- ✨ DropDownWidth wird an das größte Item angepasst. [FormNeuerAuftrag.cs] +- ✨ Es kann ab jetzt Morgen als Liefertag gewählt werden. [FormNeuerAuftrag.cs] - ✨ Es kann nach der Kontrolle der Lieferrhythmus geändert werden. Dazu muss auch die Anzahl der Liefertage gewählt werden. [FormTourenplanung.cs] - ✨ Es können nur so viele Clone erstellt werden wie Liefertag im Lieferrhythmus hinterlegt sind. [FormTourenplanung.cs] - ✨ Es wir kontrolliert ob der gewählte Liefertag zum hinterlegten Lieferrhythmus passt. [FormTourenplanung.cs] +- ✨ Es wird jetzt nur ein Button "Speichern/Freigeben" bereitgestellt und dort dann gefragt ob speichern oder freigeben. Hier wird auch zwischen den Rollen unterschieden. [UCInventur.cs] - ✨ Fahrer können abgeholte Aufträge erstellen und ausgelieferte Aufträge markieren. [FormMain.cs] - ✨ Im Tab Rampe wird bei DoppelClick der Auftrag als gewaschen markiert und im Tab Aufträge heute sichtbar. [FormExpedit.cs] - ✨ Im Tab Vorbereitet wird beim Ändern der sauberen Containeranzahl gefragt ob die Etiketten neu gedruckt werden sollen. [FormExpedit.cs] @@ -28,54 +34,11 @@ Build-Info: - ✨ Speichern und Laden wurde angepasst, JSON enthält jetzt pro Tag eine Kundenliste. [UCTabPageLKW.cs] - ✨ TabText wird mit Benutzerliste verglichen. Wenn ein passender gefunden wird Tag hinterlegt. [FormTourenplanung.cs] - ✨ Wenn der Lieferrhythmus geändert wird, werden KundenControls an falschen Tagen gelöscht. [UCTabPageLKW.cs] +- ✨ Wenn die Zahlen zurückgesetzt werden sollen, muss AuftragDetail geschlossen werden. [FormAuftragDetail.cs] - ✨ Wenn ein anderer Fahrer ausgewählt wird, wird auch die Priority laut dem Fahrer geändert. [FormExpedit.cs] +=== ⚙️ INSTALL-REMINDER (1) === +- ⚙️ DB anpassen. (Priority in Auftrag etc.) [Auftrag.cs] -=== ✅ ERLEDIGTE TODOs (15) === -- ✅ : Bei Transport wir ein Fach mit Aktuellem Auftrag erstellt. Das Alte wird bei Transport gespeichert. [FormAusschlager.cs] -- ✅ : Bestand von allen Artikeln speichern und für Druck vorbereiten. [FormAuftragDetail.cs] -- ✅ : CLick auf Inventur freigeben Dateiname von "Warten" auf "Herrichten" ändern. [UCInventur.cs] -- ✅ : ComboBox Fahrer und Priorität implementieren [FormAuftragDetail.cs] -- ✅ : Container schmutzig bearbeitbar machen [FormAuftragDetail.cs] -- ✅ : Feedback Button hinzufügen [FormAuftragDetail.cs] -- ✅ : Inventur freigeben nur für Admin oder Verwaltung. [UCInventur.cs] -- ✅ : Inventur für Expedit zugänglich machen. [UCInventur.cs] -- ✅ : JSON nach angemeldeten Fahrer durchsuchen und Kundenliste des aktuellen Wochentag anzeigen. [FormMain.cs] -- ✅ : Korrigiere Bestand: Wenn -Zahl dann Stand - Zahl. [FormAuftragDetail.cs] -- ✅ : Mit AddFehler können Fehler aus try/chatch in Obsidian eingefügt werden. (Timestamp, PC-Name, Ex-Message) [Program.cs] -- ✅ : Speichern etc. durchgehen und adaptieren [FormAuftragDetail.cs] -- ✅ : Wenn Frottee-Expedit auch Reklamation bearbeitet, muss BenutzerRolle abgefragt werden. siehe CHANGES. [FormFehlmengeCount.cs] -- ✅ : Wenn NeuerAuftrag gewählt Fach ändern nicht vergessen. [FormAusschlager.cs] -- ✅ : Wenn NeuerAuftrag gewählt wie gehts weiter? [FormAusschlager.cs] - - -=== 🔄 OFFENE TODOs (26) === -- 🔄 Alle Icons in einer Spalte anzeigen? I für Anmerkung und ! für Aufgabe?? [FormMain.cs] -- 🔄 Alle Icons in einer Spalte anzeigen? I für Anmerkung und ! für Aufgabe?? [UCAuftragListe.cs] -- 🔄 Auftrag richtig speichern... mit gedruckt bzw. erledigt bzw. [FormExpedit.cs] -- 🔄 Auftragauswahl aufrufen statt NeuerAuftrag. (Wenn Fahrer Aufträge erstellen) [FormWSVerfolgung.cs] -- 🔄 Aufträge zusammenführen wenn gleicher Kunde und Liefertag. [FormNeuerAuftrag.cs] -- 🔄 Ausprobieren ob die Ausrichtung jetzt richtig ist. Sowohl beim ersten wie auch zweiten Mal. [Funktionen.cs] -- 🔄 Dateinamen aus Tikos anschauen. Eventuell Datum von letztem Import über Dateiname wählen? [FormMain.cs] -- 🔄 Deaktivieren wenn SPS funktioniert. Transport wird simuliert. [FormWSVerfolgung.cs] -- 🔄 Design des Controls anpassen. Eventuell im Designer erstellen. [UCKunde.cs] -- 🔄 Einbinden der NachwaescheArtikelData... [FormArtikelVW.cs] -- 🔄 Erstellen von SonderAuftrag und Drucken von Etikett testen. [FormAuftragDetail.cs] -- 🔄 Funktioniert mehrere KundenControls auf einmal DragDrop? [FormTourenplanung.cs] -- 🔄 Gesamt soll immer 100% sein. [Funktionen.cs] -- 🔄 Hier Settings speichern mit UserSettingsManager Klasse. [FormEinstellung.cs] -- 🔄 Mit Tour statt Fahrer durchgehen. [FormExpedit.cs] -- 🔄 Nach Test und Rücksprache eventuell wieder umbauen. Benutzer.Rolle etc. [FormFehlmengeCount.cs] -- 🔄 nicht ganze Aufträge holen sondern nur die Zahlen? [FormMain.cs] -- 🔄 Non-Hard-Coded-Lösung für Priority finden. [Auftrag.cs] -- 🔄 Reg.Aufträge einbauen. Besonderheit: Die Artikel sollen ebenfalls erscheinen. [Funktionen.cs] -- 🔄 Richtige Liste holen, wahrscheinlich mit TourID von ShowTourenplan. [FormMain.cs] -- 🔄 Settings hier ändern auf UserSettingsManager Klasse. [FormEinstellung.cs] -- 🔄 TourenListe Entwurf muss überarbeitet werden. [FormNeuerAuftrag.cs] -- 🔄 UserSetting Properties eintragen und in EinstellungsScreen abrufen. [UserSettingsManager.cs] -- 🔄 Warum der falsche Path? Immer mit \\ [UCFeedback.cs] -- 🔄 Weitere Properties von oben hier zuweisen [UserSettingsManager.cs] -- 🔄 Zuweisung zu Fahrer muss geklärt werden. [Funktionen.cs] - -Installation: 22.04.2026 17:39 +Installation: 24.04.2026 13:46 =====================================