using BrightIdeasSoftware; using DatenDB; using Npgsql; using System; using System.CodeDom; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Data; using System.Drawing; using System.Drawing.Printing; using System.Linq; using System.Reflection; using System.Runtime.ConstrainedExecution; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Input; namespace Deckungsbeitrag { public partial class FormAufleger : Form { private Dictionary> auftragliste; private System.Windows.Forms.Timer timer; private Auftrag auftrag; private Meldungen meldung = new Meldungen(); private bool iswechsel = false; private string userid; public FormAufleger() { InitializeComponent(); // Timer für Wartezeit bis TextChanged eintritt. timer = new System.Windows.Forms.Timer(); timer.Interval = 700; // 0,7 Sekunden timer.Tick += Timer_Tick; } public FormAufleger(string userid) : this() { this.userid = userid; } private async void FormAufleger_Load(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; this.SuspendLayout(); this.labelVersion.Text += Assembly.GetExecutingAssembly().GetName().Version.ToString(); try { await GetAuftraege(); this.Invoke(new Action(() => { LoadPanel(); })); } finally { this.ResumeLayout(true); this.Cursor = Cursors.Default; this.textBoxScan.Focus(); } } private void LoadPanel() { this.Cursor = Cursors.WaitCursor; this.SuspendLayout(); for (int i = 0; i < this.tLPAuftrag.RowCount; i++) { if(i == 0) { int index = 0; foreach (var key in auftragliste.Keys.OrderBy(k => k)) { Control ctr = this.tLPAuftrag.GetControlFromPosition(index, i); if (index == 4) ctr.Text = "Rest"; else { ctr.Text = Funktionen.GetWochentagDeutsch(key.DayOfWeek); ctr.Text += " (" + key.ToShortDateString() + ")"; } ctr.Font = Funktionen.GetFontSizeByWidth(ctr.Font, ctr.Text, ctr.Width); index++; } } if(i == 1) { float flpsize = 0; // 1. Dictionary: Column-Index → FlowLayoutPanel var flpDictionary = new Dictionary(); for (int column = 0; column < this.tLPAuftrag.ColumnCount; column++) { Control ctr = this.tLPAuftrag.GetControlFromPosition(column, i); if (ctr is FlowLayoutPanel flp) flpDictionary[column] = flp; flpsize = ctr.Width; } // 2. Dictionary: Column → Array aller UCAuftrag für diesen Tag var ucArrays = new Dictionary(); int col = 0; foreach (List liste in auftragliste.Values) { UCAuftrag[] alleUCA = new UCAuftrag[liste.Count]; int anzUCA = 0; foreach (Auftrag auftrag in liste) { UCAuftrag uca = new UCAuftrag(auftrag); uca.Tag = auftrag; if (auftrag.Status == AuftragStatus.Aufgelegt) { this.auftrag = auftrag; uca.BackColor = Color.YellowGreen; } else uca.BackColor = Color.Silver; uca.Size = new Size(flpDictionary[col].Width - 30, uca.Height); alleUCA[anzUCA] = uca; anzUCA++; } ucArrays[col] = alleUCA; col++; } var ucA = new Dictionary(); foreach (KeyValuePair auftraglist in ucArrays) { int key = auftraglist.Key; // Innerhalb jedes Arrays nach Fahrer sortieren UCAuftrag[] sortiert = auftraglist.Value .OrderBy(a => a.Fahrer) // oder a.FahrerName .ToArray(); ucA[key] = sortiert; } ucArrays = ucA; // 3. ATOMAR: Alle FLPs leeren + Arrays auf einmal hinzufügen foreach (var kvp in flpDictionary) { if (ucArrays.TryGetValue(kvp.Key, out UCAuftrag[] ucArray)) { kvp.Value.Controls.Clear(); kvp.Value.Controls.AddRange(ucArray); // EIN Paint-Event pro FLP! } } } if(i == 2) { foreach (FlowLayoutPanel flowpanel in this.tLPAuftrag.Controls.OfType()) { int column = this.tLPAuftrag.GetColumn(flowpanel); int container = 0; foreach (UCAuftrag uca in flowpanel.Controls) { container += int.Parse(uca.ContainerAnzahl); Label lblKunde = uca.Controls["labelKunde"] as Label; lblKunde.Font = Funktionen.GetFontSizeByWidth(lblKunde.Font, lblKunde.Text, uca.Width); uca.Refresh(); } Control ctr = this.tLPAuftrag.GetControlFromPosition(column, i); ctr.Text = container.ToString(); } } } this.ResumeLayout(true); this.Cursor = Cursors.Default; } private async Task GetAuftraege() { var conn = new NpgsqlConnection(ConfigurationManager.AppSettings["ConnectionString"]); // Pro Task! try { await conn.OpenAsync(); auftragliste = await Auftrag.GetAuftraegeProLiefertagAsync(conn, AuftragTyp.Standart, AuftragStatus.Aufgelegt); } finally { if (conn.State == ConnectionState.Open) conn.Close(); conn.Dispose(); } } private void FormAufleger_Shown(object sender, EventArgs e) { this.ResumeLayout(true); this.Cursor = Cursors.Default; this.textBoxScan.Focus(); } /// /// Erfassen von Tasten für Tastaturlose Steuerung. /// /// /// protected override bool ProcessDialogKey(Keys keyData) { //TODO: Umbau in Switch. // Escape [ESC] schließt den Screen. if (Form.ModifierKeys == Keys.None && keyData == Keys.Escape) { this.Close(); return true; } return base.ProcessDialogKey(keyData); } private void textBoxScan_TextChanged(object sender, EventArgs e) { // TextChanged tritt nur ein wenn x Sekunden keine Eingabe erfolgt. Logik befindet sich in Timer_Tick timer.Stop(); // Alten Timer beenden timer.Start(); // Neuen Timer starten } private void Timer_Tick(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; timer.Stop(); // Timer stoppen Kunde kunde; string zusatz = string.Empty; if (string.IsNullOrEmpty(textBoxScan.Text)) { this.Cursor = Cursors.Default; return; } if (int.TryParse(textBoxScan.Text, out _)) kunde = Kunde.GetKunde(textBoxScan.Text, null, null); else { if (textBoxScan.Text.Contains(",")) { kunde = Kunde.GetKunde(textBoxScan.Text.Substring(0, textBoxScan.Text.IndexOf(',')), null, null); zusatz = textBoxScan.Text.Substring(textBoxScan.Text.IndexOf(',') + 1); } else kunde = Kunde.GetKunde(null, null, textBoxScan.Text); } List auftList = Auftrag.FindeAuftragVonKunde(kunde, zusatz); if (auftList.Count == 0) { meldung.GetFehler(this, "Es konnte kein Auftrag zum eingescannten Kunden gefunden werden.\nBitte Informiere deinen Vorgesetzten."); return; } // Alten Auftrag Speichern (Status Gewaschen) wenn neuer Auftrag gefunden wurde. if(auftrag != null) { if (AuftragSpeichern() == false) return; iswechsel = true; } if (auftList.Count == 1) auftrag = auftList[0]; if (auftList.Count > 1) { if (meldung.GetFrage(this, $"Es konnten mehrere Aufträge für den gescannten Kunden gefunden werden.\nIst auf der Containerkarte Auftrag 2 vermerkt?", false) == DialogResult.Yes) { auftrag = auftList.Find(a => a.ZusatzInfo.Contains("Auftrag 2")); } else { auftrag = auftList.Find(a => !a.ZusatzInfo.Contains("Auftrag 2")); } } SucheAuftrag(); this.Cursor = Cursors.Default; } private void SucheAuftrag() { this.textBoxScan.TextChanged -= textBoxScan_TextChanged; foreach (FlowLayoutPanel flp in this.tLPAuftrag.Controls.OfType()) { foreach (UCAuftrag uca in flp.Controls) { if (((Auftrag)uca.Tag).AuftragID == this.auftrag.AuftragID) { // Wenn neuer Auftrag gefunden dann Status Aufgelegt und UserControl Grüner Hintergrund. this.auftrag.Status = AuftragStatus.Aufgelegt; this.auftrag.Save(); uca.Tag = this.auftrag; if (this.auftrag.Status == AuftragStatus.Aufgelegt) uca.BackColor = Color.YellowGreen; } } } if (iswechsel) { FormAufleger_Load(this, null); iswechsel = false; } this.textBoxScan.Clear(); this.textBoxScan.Focus(); this.textBoxScan.TextChanged += textBoxScan_TextChanged; } private bool AuftragSpeichern() { auftrag.Status = AuftragStatus.Gewaschen; if (auftrag.Save()[0] == 1) auftrag = null; else { meldung.Speicherfehler(); return false; } return true; } private void FormAufleger_FormClosing(object sender, FormClosingEventArgs e) { //if (auftrag == null) return; //if (AuftragSpeichern() == false) e.Cancel = true; } private void buttonCloseForm_Click(object sender, EventArgs e) { if (meldung.GetFrage(this, "Möchtest du das Programm wirklich schließen?", false) == DialogResult.No) return; Application.Exit(); } /// /// Waschzeitberechnung bei DoppelClick auf Container Label. /// /// /// private void labelCont_DoubleClick(object sender, EventArgs e) { Label lbl = sender as Label; double[] zeit = { 0, 0 }; for (int i = 1; i < 3; i++) { if (double.TryParse(lbl.Text, out double cont)) zeit[i-1] = (cont * 2.7 * 3.5) / 60 / i; } meldung.GetInfo(this, $"Die Waschzeiten für den gewünschten Tag lauten:\n\n[Eine Waschstraße] => {zeit[0].ToString("F1")} Stunden\n[Zwei Waschstraßen] => {zeit[1].ToString("F1")} Stunden", false); } } } //CHANGES: Programm wird mit Button geschlossen. (Sicherheitsabfrage ob wirklich gewollt wird gemacht.)