Programm_Wirl/AA-Forms/FormExpedit.cs

960 lines
36 KiB
C#

using BrightIdeasSoftware;
using DatenDB;
using Deckungsbeitrag.Properties;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Xml.Resolvers;
namespace Deckungsbeitrag
{
public partial class FormExpedit : Form
{
#region Properties
private ToolTip cellTooltip = new ToolTip();
public Meldungen fehlermeldung = new Meldungen();
public Image etikett = null;
public Auftrag auftrag;
public Auftrag NeuerAuftrag; //NEU FÜR UPDATE
public AuftragArtikel auftragArtikel;
public Benutzer benutzer;
public Kunde kunde;
DateTime? letzterLiefertag = null;
bool nocont = false;
bool nocontclicked = false;
Meldungen meldung = new Meldungen();
public List<KundeArtikel> artikelListe;
public List<Auftrag> auftraglist;
public List<Auftrag> sonderlist;
int beforeedit = 0;
int? neuecontclean = null;
int? altecontclean = null;
Timer timer1 = new Timer();
private Screen[] screens;
private Point itemlocation;
private ImageList imagelist = new ImageList();
private volatile bool _isProcessing = false; // Thread-sicherer Flag gegen Überlappung
private int _consecutiveFailures = 0;
private const int MAX_FAILURES = 3;
private bool aufgabeDone = false;
#endregion
public FormExpedit(Benutzer benutzer)
{
InitializeComponent();
this.benutzer = benutzer;
this.StartPosition = FormStartPosition.CenterScreen;
this.tabControlAuftragList.Visible = true;
//Timer für Autorefresh
timer1.Interval = 10000; // 10 Sekunden
timer1.Tick += Timer1_Tick;
timer1.Start();
}
public FormExpedit(Benutzer benutzer, Screen[] screens) : this(benutzer)
{
this.screens = screens;
foreach (Screen screen in screens)
{
if (screen.Primary)
{
if (screen.WorkingArea.Width < 1500) { this.objectListViewAuftrag.Font = new Font(this.objectListViewAuftrag.Font.FontFamily, 10); }
}
}
}
private void FormExpedit_Load(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
this.SuspendLayout();
this.Visible = false;
imagelist.Images.Add(Resources.Exclamation_Red);
imagelist.Images.Add(Resources.InformationSymbol_16x);
imagelist.ImageSize = new Size(24, 24);
// Controls aktivieren und deaktivieren nach BenutzerRolle
switch (this.benutzer.Rolle)
{
case BenutzerRolle.Verwaltung:
this.buttonDrucken.Enabled = this.buttonNeuerAuftrag.Enabled = this.buttonSWS_Drucken.Enabled = false;
this.groupBoxEtikett.Enabled = false;
GetUnvisibleButtonColumn();
break;
case BenutzerRolle.Fahrer:
this.buttonDrucken.Enabled = this.buttonNeuerAuftrag.Enabled = this.buttonSWS_Drucken.Enabled = false;
this.groupBoxEtikett.Enabled = false;
GetUnvisibleButtonColumn();
break;
case BenutzerRolle.Admin:
break;
case BenutzerRolle.Waschstrasse:
this.buttonDrucken.Enabled = this.buttonNeuerAuftrag.Enabled = this.buttonSWS_Drucken.Enabled = false;
this.groupBoxEtikett.Enabled = false;
GetUnvisibleButtonColumn();
break;
case BenutzerRolle.Master:
break;
case BenutzerRolle.Expedit:
break;
case BenutzerRolle.Frottee:
this.buttonDrucken.Enabled = this.buttonNeuerAuftrag.Enabled = this.buttonSWS_Drucken.Enabled = false;
this.groupBoxEtikett.Enabled = false;
GetUnvisibleButtonColumn();
break;
case BenutzerRolle.Flach:
this.buttonDrucken.Enabled = this.buttonNeuerAuftrag.Enabled = this.buttonSWS_Drucken.Enabled = false;
this.groupBoxEtikett.Enabled = false;
// WENN Rolle Frottee (Expedit Frottee) dann ButtonClick deaktiviert. Nur Expedit kann abschließen
GetUnvisibleButtonColumn();
break;
default:
break;
}
//Auftragslisten erstellen und in ObjectListViews laden.
GetLists();
Load_Etikett_GroupBox();
if (letzterLiefertag != null) this.dTPLiefertag.Value = (DateTime)letzterLiefertag;
else this.dTPLiefertag.Value = DateTime.Today.AddDays(1);
if (this.kunde != null) Funktionen.Get_RadioButtons(this.groupBoxEtikett);
this.ResumeLayout();
this.Visible = true;
Cursor.Current = Cursors.Default;
WindowState = FormWindowState.Maximized;
}
/// <summary>
/// Auftragslisten erstellen und in ObjectListViews laden.
/// </summary>
private void GetLists()
{
// Lade die ListView für Aufträge vom aktuellen Tag.
auftraglist = Auftrag.GetAuftragListToday(DateTime.Today);
OLV_Load(this.objectListViewAuftrag, auftraglist);
// Lade die ListView für Sonderaufträge wie STV, STH, oder INVENTUR
sonderlist = Auftrag.GetExpeditLists((int)AuftragTyp.Inventur);
if (sonderlist.Count == 0) { this.tabControlAuftragList.TabPages.Remove(tabPageSonder); }
else { OLV_Load(this.objectListViewSonder, sonderlist); if(this.tabControlAuftragList.TabPages.Count < 2) this.tabControlAuftragList.TabPages.Insert(1, tabPageSonder); }
// Lade die Artikel eines Kunden.
//if (kunde!= null) this.artikelListe = KundeArtikel.GetList(kunde.KundeID.ToString());
}
/// <summary>
/// Wenn Timer abgelaufen Funktion für Autorefresh.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer1_Tick(object sender, EventArgs e)
{
// Vermeide Überlappung (wenn vorheriger Tick noch läuft)
if (_isProcessing) return;
Cursor.Current = Cursors.WaitCursor;
_isProcessing = true;
try
{
if (auftrag != null)
{
const int maxRetries = 3;
Auftrag _auftrag = null;
for (int retry = 0; retry < maxRetries; retry++)
{
try
{
_auftrag = Auftrag.GetAuftrag(auftrag.AuftragID);
if (dGArtikel.Visible) Load_Gridview(_auftrag);
_consecutiveFailures = 0; // Erfolg -> Zähler reset
break;
}
catch (NpgsqlException ex) when ((ex.InnerException is SocketException || ex.InnerException is System.IO.IOException) && retry < maxRetries - 1)
{
_consecutiveFailures++;
Debug.WriteLine($"Retry {retry + 1}/{maxRetries}: {ex.Message}"); // Logging
System.Threading.Thread.Sleep(1000 * (int)Math.Pow(2, retry)); // Backoff: 1s, 2s, 4s
}
catch (Exception ex)
{
Debug.WriteLine($"Unexpected error: {ex.Message}"); // Logging
break;
}
}
// Timer stoppen bei zu vielen aufeinanderfolgenden Fehlern
if (_consecutiveFailures >= MAX_FAILURES)
{
timer1.Enabled = false;
Debug.WriteLine("Timer gestoppt nach " + MAX_FAILURES + " Fehlern. Bitte manuell neu starten.");
// Optional: Status-Label setzen oder MessageBox
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"Timer1_Tick globaler Fehler: {ex}");
_consecutiveFailures++;
}
finally
{
_isProcessing = false;
Cursor.Current = Cursors.Default;
}
}
/// <summary>
/// Laden Events (GroupBox_Etikett und GridView)
/// </summary>
private void Load_Etikett_GroupBox()
{
if (this.auftrag == null)
{
this.buttonKundeNr.Text = "Auftrag in der Liste wählen";
this.pictureBoxEntwurf.Image = null;
this.textBoxCont.Text = "0";
this.pictureBoxMinus.Enabled = this.pictureBoxPlus.Enabled = this.buttonDrucken.Enabled = false;
this.buttonDrucken.BackColor = Color.Gray;
this.pictureBoxMinus.BackColor = Color.Gray;
this.pictureBoxPlus.BackColor = Color.Gray;
foreach (Control ctr in this.groupBoxEtikett.Controls)
{
if (ctr.GetType() == typeof(Label)) ctr.Enabled = true;
else if (ctr.Enabled == true) ctr.Enabled = false;
}
this.dTPLiefertag.Enabled = true;
}
else
{
//Kunde holen und Name anzeigen
this.kunde = Kunde.GetKunde(null, this.auftrag.KundeID, null);
this.buttonKundeNr.Text = kunde.Suchtext;
//Containeranzahl und Liefertag anzeigen
if (neuecontclean != null) this.textBoxCont.Text = neuecontclean.ToString();
else this.textBoxCont.Text = this.auftrag.ContainerClean.ToString();
this.dTPLiefertag.Value = this.auftrag.Liefertag;
this.dTPLiefertag.Enabled = false;
//Buttons Enablen und BackColor wechsel
this.buttonDrucken.BackColor = Color.FromArgb(0, 192, 0);
this.pictureBoxPlus.BackColor = Color.FromArgb(0, 192, 0);
this.buttonDrucken.Enabled = this.pictureBoxPlus.Enabled = true;
this.auftrag.ContainerClean = int.Parse(this.textBoxCont.Text);
etikett = Funktionen.Etikett_Entwurf(this, this.auftrag, nocont);
this.pictureBoxEntwurf.Image = etikett;
}
}
private void Load_Gridview(Auftrag auftrag)
{
//Alle Einträge der DataGridView entfernen. Davor muss die DataSource entfernt werden.
this.dGArtikel.DataSource = null;
this.dGArtikel.Rows.Clear();
if (auftrag != null)
{
Aufgabe auf;
if (auftrag.AufgabeID.HasValue) auf = Aufgabe.GetAufgabe(null, auftrag.AufgabeID);
else auf = new Aufgabe();
this.dGArtikel.AutoGenerateColumns = false;
foreach (DataGridViewColumn col in this.dGArtikel.Columns)
{
col.DataPropertyName = col.Name;
if (col.Name.Contains("Bearbeitet")) col.Visible = false;
if (col.Name == "Fehlmenge")
{
if (auf.Bezeichnung == null || auf.Bezeichnung == "STA") col.Visible = true;
else col.Visible = false;
}
if (col.Name == "Korrektur")
{
if (auf.Bezeichnung != null && auf.Bezeichnung != "STA") col.Visible = true;
else col.Visible = false;
}
}
// DataGridView mit ArtikelStand Liste verbinden und Columns automatisch generieren.
artikelListe = KundeArtikel.GetList(auftrag.KundeID.ToString());
this.dGArtikel.DataSource = artikelListe;
this.dGArtikel.ClearSelection();
//this.dGArtikel.CurrentCell = this.dGArtikel.Rows[0].Cells[3];
// Alle Spaltenbreiten an den Zellinhalt anpassen
this.dGArtikel.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
// Alle Zeilenhöhen an Zellinhalt anpassen
this.dGArtikel.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
this.dGArtikel = Funktionen.DGV_Size_Anpassen(this.dGArtikel);
this.dGArtikel.Width = this.Width - dGArtikel.Left;
// Rechter Rand von letzter Spalte berechnen.
int x = 0;
foreach (ColumnHeader col in objectListViewAuftrag.Columns) x += col.Width;// x ist jetzt die Position direkt rechts von der letzten Spalte (relativ zu client origin)
this.dGArtikel.Location = new Point(this.objectListViewAuftrag.Left + x, this.dGArtikel.Location.Y);
if (this.dGArtikel.Rows.Count > 0) this.dGArtikel.Visible = true;
else this.dGArtikel.Visible = false;
}
}
/// <summary>
/// Containeranzahl bearbeiten und Funktion wenn Text geändert wird.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Container_Click(object sender, EventArgs e)
{
PictureBox pb = (PictureBox)sender;
int cont = int.Parse(this.textBoxCont.Text);
if (pb.Name.ToString().Contains("Plus")) { cont++; }
if (pb.Name.ToString().Contains("Minus"))
{
if (cont > 0)
{
cont--;
}
//else { pb.BackColor = Color.Gray; pb.Enabled = false; }
}
this.textBoxCont.Text = cont.ToString();
//Load_Etikett_GroupBox();
}
private void textBoxCont_TextChanged(object sender, EventArgs e)
{
if(int.TryParse(this.textBoxCont.Text, out int result))
{
if (this.auftrag != null) { neuecontclean = result; altecontclean = this.auftrag.ContainerClean; }
if (result == 0) { this.pictureBoxMinus.Enabled = false; this.pictureBoxMinus.BackColor = Color.Gray; }
else { this.pictureBoxMinus.Enabled = true; this.pictureBoxMinus.BackColor = Color.Red; }
if (!nocontclicked)
{
if (result >= 10) { nocont = true; cBNoCont.Checked = true; }
else { nocont = false; cBNoCont.Checked = false; }
}
Load_Etikett_GroupBox();
}
else
{
meldung.Eingabefehler();
this.textBoxCont.Text = "0";
this.textBoxCont.Focus();
}
}
private void cBNoCont_CheckedChanged(object sender, EventArgs e)
{
if (cBNoCont.Checked) nocont = true;
else nocont = false;
if (kunde != null) Load_Etikett_GroupBox();
}
private void cBNoCont_Click(object sender, EventArgs e)
{
if (cBNoCont.Checked) nocont = nocontclicked = true;
else { nocont = false; nocontclicked = true; }
}
#region Button_Click-Events
private void buttonDrucken_Click(object sender, EventArgs e)
{
if (this.auftrag.AufgabeID != null)
{
if (meldung.GetAchtung(this, $"Bei dem ausgewählten Auftrag ist die Aufgabe {Aufgabe.GetAufgabe(null, auftrag.AufgabeID).Bezeichnung} zu erledigen. Hast du die Aufgabe erledigt? ", false) == DialogResult.No) return;
}
if (this.textBoxCont.Text != "0")
{
//AUFTRAG UPDATE
this.auftrag.ContainerClean = int.Parse(this.textBoxCont.Text);
letzterLiefertag = this.auftrag.Liefertag = this.dTPLiefertag.Value;
//ETIKETT DRUCKEN
DialogResult result = Funktionen.Etikett_Drucken(auftrag, nocont);
if (result == DialogResult.OK)
{
this.auftrag.Gedruckt = this.auftrag.Erstellt = DateTime.Now;
this.auftrag.GedrucktVon = this.auftrag.ErstelltVon = (int)this.benutzer.BenutzerID;
this.auftrag.Status = AuftragStatus.Vorbereitet;
this.auftrag.Save();
this.auftrag = null;
FormExpedit_Load(this, e);
this.dGArtikel.DataSource = null;
this.dGArtikel.Rows.Clear();
}
}
}
private void buttonNeuerAuftrag_Click(object sender, EventArgs e)
{
FormNeuerAuftrag neuerAuftrag = new FormNeuerAuftrag(benutzer, this.letzterLiefertag, AuftragTyp.Standart);
if (neuerAuftrag.ShowDialog() == DialogResult.OK)
{
this.letzterLiefertag = neuerAuftrag.letzterLiefertag;
List<Auftrag> auftraglist = Auftrag.GetAuftragListToday(DateTime.Today);
OLV_Load(this.objectListViewAuftrag, auftraglist);
}
}
private void buttonSWS_Drucken_Click(object sender, EventArgs e)
{
Kunde knd = Funktionen.KundenAuswahl();
if(knd != null) Funktionen.SWS_Drucken(null, knd, this);
}
private void buttonEinstellung_Click(object sender, EventArgs e)
{
FormEinstellung einstellung = new FormEinstellung(this);
einstellung.ShowDialog();
}
#endregion
#region ObjectListView-Events
private void objectListViewAuftrag_FormatCell(object sender, FormatCellEventArgs e)
{
if (e.ColumnIndex == 11)
{ // jede zweite Spalte
if(e.SubItem.BackColor != Color.LightBlue)
{
e.SubItem.BackColor = Color.AliceBlue;
e.SubItem.ForeColor = Color.Black;
}
else
{
e.SubItem.BackColor = Color.LightSteelBlue;
e.SubItem.ForeColor = Color.Black;
}
}
}
private void objectListViewAuftrag_CellClick(object sender, CellClickEventArgs e)
{
itemlocation = new Point(e.Location.X, e.Location.Y);
ObjectListView olv = (ObjectListView)sender;
Auftrag _auftrag = (Auftrag)e.Model;
if (e.Model == null) { dGArtikel.Visible = false; return; }
if (_auftrag.Status != AuftragStatus.Fertig)
{
this.auftrag = _auftrag;
this.neuecontclean = null;
Load_Etikett_GroupBox();
this.artikelListe = KundeArtikel.GetList(kunde.KundeID.ToString());
Load_Gridview(this.auftrag);
}
else
{
fehlermeldung.AuftragFertig();
}
foreach (Control ctr in this.groupBoxEtikett.Controls) if (ctr.Enabled == false) ctr.Enabled = true;
this.buttonKundeNr.Enabled = false;
olv.Focus();
}
private void objectListViewAuftrag_CellRightClick(object sender, CellRightClickEventArgs e)
{
ObjectListView olv = (ObjectListView)sender;
// Überprüfung ob Click auf einem Item war.
if (e.Model == null) return;
Auftrag _auftrag = (Auftrag)e.Model;
Kunde _kunde = Kunde.GetKunde(null, _auftrag.KundeID, null);
string name = string.Empty;
if (string.IsNullOrWhiteSpace(_kunde.Suchtext)) name = _kunde.KundeName;
else name = _kunde.Suchtext;
// Überprüfung welche Spalte geclickt wurde.
switch (e.Column.Text)
{
case "Abschließen":
// Wenn Click in Gruppe Vorbereitet dann ignorieren.
if (e.Item.Group.Header == "Vorbereitet") return;
if (meldung.GetFrage(this, $"Für den Auftrag wurden keine Etiketten gedruckt, ohne Etikettendruck als Vorbereitet markieren?", false) == DialogResult.Yes)
{
// Wenn Aufgabe hinterlegt ist wir nachgefragt ob diese erledigt wurde.
if (_auftrag.AufgabeID != null)
{
// Wenn NEIN wird der Click abgebrochen.
if (meldung.GetAchtung(this, $"Bei dem ausgewählten Auftrag ist die Aufgabe {Aufgabe.GetAufgabe(null, auftrag.AufgabeID).Bezeichnung} zu erledigen. Hast du die Aufgabe erledigt? ", false) == DialogResult.No) return;
else Aufgabe_erledigt(_auftrag, _kunde, name);
}
// Wenn TextBox für saubere Container 0 ist wird der Click abgebrochen.
if (this.textBoxCont.Text == "0") { meldung.GetFehler(this, "Du kannst den Auftrag nicht als vorbereitet markieren. Wähle zuerst die Anzahl der sauberen Container."); return; }
// Auftrag wird bearbeitet und gespeichert.
_auftrag.Status = AuftragStatus.Vorbereitet;
_auftrag.Save();
olv.RefreshObject(e);
GetLists();
if (olv.Name.Contains("Sonder")) OLV_Load(olv, this.sonderlist);
else OLV_Load(olv, this.auftraglist);
}
break;
case "Aufgabe":
if (_auftrag.AufgabeID == null) return;
Aufgabe _aufgabe = Aufgabe.GetAufgabe(null, ((Auftrag)e.Model).AufgabeID);
if (meldung.GetFrage(this, $"Hast du beim Kunden {name} die Aufgabe {_aufgabe.Bezeichnung} erledigt und möchtest sie als erledigt markieren?", false) == DialogResult.Yes)
{
Aufgabe_erledigt(_auftrag, _kunde, name);
}
break;
default:
break;
}
}
private void objectListViewAuftrag_ButtonClick(object sender, CellClickEventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
ObjectListView olv = (ObjectListView)sender;
Auftrag _auftrag = (Auftrag)e.Model;
if (this.auftrag != _auftrag) neuecontclean = null;
this.auftrag = _auftrag;
//Load_Etikett_GroupBox();
if (this.auftrag.ContainerClean == 0)
{
switch (this.auftrag.Typ)
{
case AuftragTyp.Geschäft:
break;
case AuftragTyp.Standart:
if (meldung.NoCleanContainer() == DialogResult.OK) return;
break;
case AuftragTyp.Inventur:
if (meldung.SonderNoCleanContainer() == DialogResult.Yes)
{
Auftrag_Fertig();
Load_Etikett_GroupBox();
}
else return;
break;
case AuftragTyp.Standverminderung:
if (meldung.SonderNoCleanContainer() == DialogResult.Yes)
{
Auftrag_Fertig();
Load_Etikett_GroupBox();
}
else return;
break;
case AuftragTyp.Standerhöhung:
if (meldung.SonderNoCleanContainer() == DialogResult.Yes)
{
Auftrag_Fertig();
Load_Etikett_GroupBox();
}
else return;
break;
default:
break;
}
}
else
{
if (neuecontclean != null && neuecontclean != altecontclean)
{
switch (meldung.DifferentCleanContainer())
{
case DialogResult.Cancel:
return;
case DialogResult.Yes:
{
this.auftrag.ContainerClean = (int)neuecontclean;
neuecontclean = null;
//this.auftrag.Liefertag = dTPLiefertag.Value;
//WENN BEARBEITET UND AUSGEDRUCKT WIRD GEDRUCKT VERÄNDERT UND ERSTELLT IST URSPRUNGSDATUM
this.auftrag.Gedruckt = DateTime.Now;
this.auftrag.GedrucktVon = benutzer.BenutzerID;
bool nocont = false;
if (MessageBox.Show("Möchtest du die Containeranzahl am Etikett anzeigen?", "FRAGE", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
nocont = true;
}
else nocont = false;
DialogResult result = Funktionen.Etikett_Drucken(auftrag, nocont);
if (result == DialogResult.OK)
{
Auftrag_Fertig();
}
}
break;
case DialogResult.No:
{
this.auftrag.ContainerClean = (int)neuecontclean;
neuecontclean = null;
//this.auftrag.Liefertag = dTPLiefertag.Value;
//WENN BEARBEITET UND NICHT GEDRUCKT WIRD ERSTELLT VERÄNDERT UND GEDRUCKT IST URSPRUNGSDATUM
this.auftrag.Erstellt = DateTime.Now;
this.auftrag.ErstelltVon = (int)benutzer.BenutzerID;
Auftrag_Fertig();
}
break;
default:
break;
}
}
else
{
Auftrag_Fertig();
Load_Etikett_GroupBox();
}
}
olv.RefreshObject(e);
GetLists();
if (olv.Name.Contains("Sonder")) OLV_Load(olv, this.sonderlist);
else OLV_Load(olv, this.auftraglist);
Load_Gridview(this.auftrag);
Cursor.Current = Cursors.Default;
}
private void OLV_Load(ObjectListView olv, List<Auftrag> auftraglist)
{
// Cursor auf Warte-Status setzen, um Benutzerfeedback zu geben
Cursor.Current = Cursors.WaitCursor;
// Layout- und Update-Änderungen pausieren, um Flackern zu verhindern
olv.SuspendLayout(); // Stoppt Layout-Berechnungen (Anchor/Dock)
olv.BeginUpdate(); // Stoppt Datenaktualisierungen/Redraws
// Automatisch alle Properties von Auftrag als Spalten generieren
Generator.GenerateColumns(olv, typeof(Auftrag), true);
foreach (OLVColumn col in olv.Columns)
{
if (col.Index == 0) col.IsVisible = false;
if (col.Index >= 7 && col.Index <= 9) col.IsVisible |= false;
}
// ========== SPALTE 11: BUTTON-COLUMNE ==========
// Spalte 11 (Index 11) als Button-Spalte konfigurieren
OLVColumn buttonColumn = (OLVColumn)olv.Columns[11];
buttonColumn.IsButton = true; // Als Button rendern
buttonColumn.ButtonSizing = OLVColumn.ButtonSizingMode.CellBounds; // Button füllt gesamte Zelle
// ========== IMAGE-LIST ZUWEISEN ==========
// SmallImageList für Icons in Detail-View (16x16 Pixel standard)
olv.SmallImageList = imagelist; // Voraussetzung: imagelist mit Icon Index 0 gefüllt
// ========== SPALTE 10 & 1: ICON-KOLUMNE ==========
// Spalte 10 als Icon-Spalte: zeigt Icon wenn AufgabeID vorhanden
OLVColumn iconColumn = (OLVColumn)olv.Columns[10];
iconColumn.ImageGetter = rowObject =>
{
var auftrag = rowObject as Auftrag;
if (auftrag.AufgabeID == null) return null; // null = kein Icon anzeigen
else return 0; // Index 0 aus SmallImageList
};
OLVColumn iColumn = (OLVColumn)olv.Columns[1];
iColumn.ImageGetter = rowObject =>
{
var _auftrag = rowObject as Auftrag;
if (string.IsNullOrWhiteSpace(Kunde.GetKunde(null, _auftrag.KundeID, null).Anmerkung)) return null; // null = kein Icon anzeigen
else return 1; // Index 0 aus SmallImageList
};
// ========== TOOLTIP FÜR ICON-SPALTE ==========
// Automatischer Cell-Tooltip bei Mouse-Hover über Spalte 10 und 1
olv.CellToolTipShowing += (s, e) =>
{
// Nur für Icon-Spalte (Index 10) und gültiges Model
if (e.ColumnIndex == 10 && e.Model is Auftrag auftrag)
{
// Lade Bezeichnung der Aufgabe als Tooltip-Text
e.Text = Aufgabe.GetAufgabe(null, auftrag.AufgabeID).Bezeichnung;
}
// Nur für Icon-Spalte (Index 1) und gültiges Model
if (e.ColumnIndex == 1 && e.Model is Auftrag _auftrag)
{
if (!string.IsNullOrWhiteSpace(Kunde.GetKunde(null, _auftrag.KundeID, null).Anmerkung))
{
// Lade Anmerkung als Tooltip-Text
e.Text = Kunde.GetKunde(null, _auftrag.KundeID, null).Anmerkung;
}
}
//TODO: Alle Icons in einer Spalte anzeigen? I für Anmerkung und ! für Aufgabe??
};
// ========== DATEN LADEN ==========
// WICHTIG: SetObjects NACH Column-Konfiguration aufrufen!
olv.SetObjects(auftraglist); // Bindet die Auftragsliste an die View
// ========== SORTIERUNG ==========
// Spalte 5 als primäre Sortier-Spalte festlegen (nach Datenbindung!)
OLVColumn sortcolumn = (OLVColumn)olv.Columns[5];
olv.Sort(sortcolumn); // Sortiert aufsteigend nach Spalte 5
// ========== CHECKBOX-FUNKTIONALITÄT ==========
// Aktiviert Checkboxen basierend auf "IsChecked" Property des Auftrag-Modells
olv.CheckedAspectName = "IsChecked";
// ========== SPALTEN ANPASSEN ==========
Funktionen.Columns_Resize(olv); // Externe Funktion für responsive Spaltenbreiten
// Unsichtbare Spalten (Width = 0 = versteckt)
olv.Columns[0].Width = 0; // Spalte 0 verstecken
olv.Columns[7].Width = 0; // Spalte 7 verstecken
olv.Columns[8].Width = 0; // Spalte 8 verstecken
olv.Columns[9].Width = 0; // Spalte 9 verstecken
// ========== AUFRÄUMEN & AKTIVIEREN ==========
olv.EndUpdate(); // Update-Pause beenden, Daten neu zeichnen
olv.ResumeLayout(); // Layout-Pause beenden, Positionen neu berechnen
olv.Focus(); // OLV fokussieren (Tastaturbedienung aktivieren)
// Cursor zurücksetzen
Cursor.Current = Cursors.Default;
}
private void GetUnvisibleButtonColumn()
{
foreach (OLVColumn col in this.objectListViewAuftrag.Columns) if (col.IsButton) col.IsVisible = false;
}
#endregion
private void Aufgabe_erledigt(Auftrag _auftrag,Kunde _kunde, string name)
{
if (_kunde.AufgabeCount <= 0) _kunde.Aufgabe = null;
else _kunde.AufgabeCount--;
_auftrag.AufgabeErledigt = true;
if (_auftrag.Save()[0] != 1) meldung.GetFehler(this, $"Der Auftrag konnte nicht gespeichert und die Aufgabe nicht als erledigt markiert werden. Melde das bitte deinem Vorgesetzten.");
if (_kunde.Save() != 1) meldung.GetFehler(this, $"Der Kunde {name} konnte nicht gespeichert und die Aufgabe nicht entfernt werden. Melde das bitte deinem Vorgesetzten.");
}
/// <summary>
/// Wird aufgerufen wenn ein Auftrag Fertig ist und so gespeichert werden soll.
/// </summary>
private void Auftrag_Fertig()
{
this.auftrag.Status = AuftragStatus.Fertig;
this.auftrag.Save();
this.auftrag = null;
}
/// <summary>
/// Liefertag wird ermittelt und in Day of Week umgerechnet. RadioButtons werden Checked oder Unchecked und Click wird registriert.
/// </summary>
private void dTPLiefertag_Leave(object sender, EventArgs e)
{
foreach (RadioButton liefertag in this.groupBoxEtikett.Controls.OfType<RadioButton>())
{
if (liefertag.Name.Contains(((Liefertag)dTPLiefertag.Value.DayOfWeek).ToString())) liefertag.Checked = true;
}
}
private void Liefertag_rB_Checked(object sender, EventArgs e)
{
foreach (RadioButton radioButton in this.groupBoxEtikett.Controls.OfType<RadioButton>())
{
if (radioButton.Checked) radioButton.BackColor = Color.Yellow;
else { radioButton.BackColor = Color.Gray; }
}
}
private void Liefertag_rB_Click(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
foreach (Liefertag tag in Enum.GetValues(typeof(Liefertag)))
{
if (radioButton.Name.Contains(tag.ToString())) this.dTPLiefertag.Value = Berechnungen.GetNextWeekday((int)tag);
}
this.dTPLiefertag.Enabled = false;
}
private void dTPLiefertag_ValueChanged(object sender, EventArgs e)
{
dTPLiefertag_Leave(sender, e);
if (this.auftrag != null)
{
this.auftrag.Liefertag = this.dTPLiefertag.Value;
this.auftrag.Save();
Load_Etikett_GroupBox();
this.objectListViewAuftrag.RefreshObject(this.auftrag);
}
}
/// <summary>
/// Wenn das dritte Tab gewählt ist, wird die GroupBox Etikett ausgeblendet. 3.Tab wäre für vergangene Aufträge - weshalb kein Etikett mehr notwendig.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tabControlAuftragList_Selected(object sender, TabControlEventArgs e)
{
TabControl tabControl = (TabControl)sender;
if(tabControl.SelectedIndex < 3) { this.groupBoxEtikett.Visible = true; }
if(tabControl.SelectedIndex == 3) { this.groupBoxEtikett.Visible = false; }
}
/// <summary>
/// Beim Wechsel der Tabs wird die DataGridView geleert.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tabControlAuftragList_SelectedIndexChanged(object sender, EventArgs e)
{
this.dGArtikel.DataSource = null;
this.dGArtikel.Rows.Clear();
this.dGArtikel.Visible = false;
}
/// <summary>
/// Vor Beginn der Editierung wird Wert gespeichert um nach der Editierung vergleichen und eventuell speichern zu können.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dGArtikel_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
DataGridView dataGrid = sender as DataGridView;
beforeedit = int.Parse(dataGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString());
}
private void dGArtikel_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
DataGridView dgV = (DataGridView)sender;
// Aktuelle Zeile holen
var row = dgV.Rows[e.RowIndex];
var cell = row.Cells[e.ColumnIndex];
// Werte aus der Zeile auslesen
KundeArtikel stand = KundeArtikel.GetItem((int)row.Cells[0].Value);
if (cell.ColumnIndex == 4) { stand.Stand = int.Parse(row.Cells[4].Value.ToString()); stand.StandBearbeitet = this.benutzer.BenutzerName + " am " + DateTime.Now.ToString(); }
if (cell.ColumnIndex == 5) { stand.Fehlmenge = int.Parse(row.Cells[5].Value.ToString()); stand.FehlmengeBearbeitet = this.benutzer.BenutzerName + " am " + DateTime.Now.ToString(); }
if (cell.ColumnIndex == 6)
{
if (int.Parse(row.Cells[6].Value.ToString()) == 0)
{
stand.Stand = stand.Stand + beforeedit;
stand.Korrektur = int.Parse(row.Cells[6].Value.ToString());
stand.StandBearbeitet = stand.KorrekturBearbeitet = this.benutzer.BenutzerName + " am " + DateTime.Now.ToString();
}
}
// Hier kannst du die Werte speichern, z.B. in Datenbank oder Liste
if (stand.Save() != 1) meldung.Speicherfehler();
else Load_Gridview(this.auftrag);
}
private void dGArtikel_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.ColumnIndex >= 5)
{
DataGridView dgv = (DataGridView)sender;
DataGridViewCell dgc = dgv.CurrentCell;
if (!int.TryParse(dgc.EditedFormattedValue.ToString(), out int i))
{
meldung.Eingabefehler();
e.Cancel = true;
}
}
}
#region Statistik
private void buttonStats_Click(object sender, EventArgs e)
{
if (this.groupBoxStatistik.Visible) this.groupBoxStatistik.Visible = false;
else this.groupBoxStatistik.Visible = true;
}
private void GetStatistik()
{
string[] statistik = { "Container gewaschen:", "Container hergerichtet:", "Container fertig:", "Kunden gewaschen:", "Kunden hergerichtet:", "Kunden abgeschlossen:" };
List<Auftrag> auftraglist = Auftrag.GetAuftragStatsListToday(this.dateTimePicker1.Value.Date);
for (int i = 1; i <= statistik.Length; i++)
{
foreach (Control ctr in this.tableLayoutPanelStatistik.Controls)
{
Label lbl;
if (ctr.GetType() == typeof(Label))
{
lbl = (Label)ctr;
if (lbl.Text.Contains("Statistik") && lbl.Text.Contains($"{i.ToString()}")) lbl.Text = statistik[i - 1].ToString();
if (lbl.Name.Contains("Zahl"))
{
int j = 0;
switch (lbl.Name)
{
case var s when s.Contains($"1"):
foreach (Auftrag a in auftraglist) if (a.Status == AuftragStatus.Aufgelegt) j += a.Container;
lbl.Text = j.ToString();
break;
case var s when s.Contains($"2"):
foreach (Auftrag a in auftraglist) if (a.Status == AuftragStatus.Vorbereitet) j += a.ContainerClean;
lbl.Text = j.ToString();
break;
case var s when s.Contains($"3"):
foreach (Auftrag a in auftraglist) if (a.Status == AuftragStatus.Fertig) j += a.ContainerClean;
lbl.Text = j.ToString();
break;
case var s when s.Contains($"4"):
foreach (Auftrag a in auftraglist) if (a.Status == AuftragStatus.Aufgelegt) j++;
lbl.Text = j.ToString();
break;
case var s when s.Contains($"5"):
foreach (Auftrag a in auftraglist) if (a.Status == AuftragStatus.Vorbereitet) j++;
lbl.Text = j.ToString();
break;
case var s when s.Contains($"{i}"):
foreach (Auftrag a in auftraglist) if (a.Status == AuftragStatus.Fertig) j++;
lbl.Text = j.ToString();
break;
default:
break;
}
}
}
}
}
//this.groupBoxStatistik.Width = this.tableLayoutPanelStatistik.Right;
}
private void dateTimePicker1_CloseUp(object sender, EventArgs e)
{
GetStatistik();
}
#endregion
}
}
//CHANGES: Wenn Auftrag als Vorbereitet markiert wird, wird nachgefragt ob die Aufgabe erledigt wurde.
//CHANGES: Wenn saubere Container sind 0 kann Auftrag nicht als Vorbereitet markiert werden. (Damit die Statistik stimmt)
//CHANGES: Es werden jetzt Meldungen gezeigt damit Aufgaben erledigt und Containeranzahl zuverlässig stimmt.
//DONE: Spalten besser erkennbar gestalten damit Mirka die Spalte trifft wenn RechtsClick.
//DONE: Aufgabe wird bei "Vorbereiten ohne Etikett" verarbeitet.
//DONE: Auftrag als Vorbereitet markieren geht nur wenn saubere Container nicht 0 sind.