using BrightIdeasSoftware; using DatenDB; using Npgsql; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Deckungsbeitrag.AA_Klassen { internal class DataClass { } /// /// OLV-Model für Nachwäscheliste. Zeigt Kunden des in der ComboBox gewählten Artikels. /// public class NWData { [OLVColumn(IsVisible = false)] public int? KndArtID { get; set; } [OLVColumn(IsVisible = false)] public int? KundeID { get; set; } [OLVColumn("KndNr.", DisplayIndex = 0, IsEditable = false)] public string KndNummer { get; set; } [OLVColumn("Kunde", DisplayIndex = 1, IsEditable = false)] public string Kunde { get; set; } [OLVColumn("NW", DisplayIndex = 2, TextAlign = HorizontalAlignment.Center)] public int Nachwaesche { get; set; } [OLVColumn("Rekl", DisplayIndex = 3, TextAlign = HorizontalAlignment.Center)]public int Reklamation { get; set; } } /// /// OLV-Model für Nachwäscheliste. Zeigt Alle "Miete (ArtNr. Start mit 6)"-Artikel und ermöglicht das erfassen von Müll und Sauber. /// public class NachwaescheArtikelData { [OLVColumn(IsVisible = false)] public int? ArtikelID { get; set; } [OLVColumn("ArtNr.", IsEditable = false, DisplayIndex = 0)] public string ArtNummer { get; set; } [OLVColumn("ArtName", IsEditable = false, DisplayIndex = 1)] public string ArtName { get; set; } [OLVColumn("Abkürzung", IsEditable = false, DisplayIndex = 2)] public string Short { get; set; } [OLVColumn("Sauber", TextAlign = HorizontalAlignment.Center, DisplayIndex = 3)] public int Sauber { get; set; } [OLVColumn("Müll", TextAlign = HorizontalAlignment.Center, DisplayIndex = 4)] public int Muell { get; set; } [OLVColumn("Kategorie", IsVisible = false, IsEditable = false, DisplayIndex = 6)] public ArtikelKategorie Kategorie { get; set; } } /// /// KundenDaten für die Tourenplanung. Notwendig damit die UserControls geladen werden können. /// public class KData { public string Name { get; set; } public string Region { get; set; } public string Tag { get; set; } // ← MO, DI, MI, DO, FR public int KundeID { get; set; } public int[] ContAnzahl { get; set; } = new int[3]; } public class AuftragInfo { public static List LadeInfos(Auftrag auftrag) { string _connectionString = ConfigurationManager.AppSettings["ConnectionString"]; var result = new List(); using (var conn = new NpgsqlConnection(_connectionString)) using (var cmd = new NpgsqlCommand($"SELECT auftrag_status_id, auftrag_id, benutzer_id, auftrag_status, status_changed FROM kundenverwaltung.auftrag_status WHERE auftrag_id = {auftrag.AuftragID} ORDER BY auftrag_id, status_changed ASC", conn)) { conn.Open(); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { result.Add(new AuftragInfo { StatusID = reader.GetInt32(0), AuftragID = reader.GetInt32(1), BenutzerID= reader.GetInt32(2), Status = (AuftragStatus)reader.GetInt16(3), Datum = reader.GetDateTime(4), }); } } } return result; } public int? StatusID { get; set; } public int? AuftragID { get; set; } public int? BenutzerID { get; set; } public AuftragStatus Status { get; set; } public DateTime Datum { get; set; } } /// /// DB-View für Nachwäsche, NW2Müll und NW2Sauber Statistik. Tageseinträge von nw_artikel werden addiert/subtrahiert. /// public class View_Artikel_Nachwaesche { public static List LadeNachwaesche() { string _connectionString = ConfigurationManager.AppSettings["ConnectionString"]; var result = new List(); using (var conn = new NpgsqlConnection(_connectionString)) using (var cmd = new NpgsqlCommand(@" SELECT artnr, abteilung, artname, nw, reklamation, muell, sauber FROM kundenverwaltung.vw_art_nachwaesche ORDER BY artnr ASC", conn)) { conn.Open(); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { result.Add(new View_Artikel_Nachwaesche { ArtNr = reader.GetInt32(0), Abteilung = (ArtikelKategorie)reader.GetInt16(1), ArtName = reader.GetString(2), Nachwaesche = reader.IsDBNull(3) ? 0 : reader.GetInt32(3), Reklamation = reader.IsDBNull(4) ? 0 : reader.GetInt32(4), Muell = reader.IsDBNull(5) ? 0 : reader.GetInt32(5), Sauber = reader.IsDBNull(6) ? 0 : reader.GetInt32(6) }); } } } return result; } [OLVColumn("ArtNr.", DisplayIndex = 0, IsEditable = false)] public int ArtNr { get; set; } [OLVColumn("Abteilung", DisplayIndex = 10, IsEditable = false)] public ArtikelKategorie Abteilung { get; set; } [OLVColumn("ArtName", DisplayIndex = 20, IsEditable = false)] public string ArtName { get; set; } [OLVColumn("NW", DisplayIndex = 30, TextAlign = HorizontalAlignment.Center)] public int Nachwaesche { get; set; } [OLVColumn("Rekl", DisplayIndex = 32, TextAlign = HorizontalAlignment.Center)] public int Reklamation { get; set; } [OLVColumn("Müll", DisplayIndex = 40, TextAlign = HorizontalAlignment.Center)] public int Muell { get; set; } [OLVColumn("Sauber", DisplayIndex = 50, TextAlign = HorizontalAlignment.Center)] public int Sauber { get; set; } } /// /// DB-View für Expedit. Sollte schneller bearbeitet werden können. Filtern ist einfacher. /// public class View_Auftrag_Expedit { /// /// Holt die Aufträge aus der DB-View. /// /// Kleiner als Status /// Größer/Gleich Status /// Kleiner als Typ /// Größer/Gleich Typ /// true wenn Frottee-Expedit /// null wenn kein Max. Datum /// /// public static async Task> GetAuftragExpeditAsync( AuftragStatus? statusFilter = null, AuftragStatus? minStatusFilter = null, AuftragTyp? typFilter = null, AuftragTyp? minTypFilter = null, ArtikelKategorie? kategorie = null, DateTime? datum = null, bool? undFertig = null, NpgsqlConnection conn = null) { string _connectionString = ConfigurationManager.AppSettings["ConnectionString"]; var resultList = new List(); NpgsqlConnection connection = conn ?? new NpgsqlConnection(_connectionString); try { await connection.OpenAsync(); NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM kundenverwaltung.vw_auftrag_expedit WHERE 1=1", connection); try { var conditions = new List(); var parameters = new List(); // Frottee-Filter if (kategorie.HasValue) { if (undFertig.HasValue && undFertig.Value) conditions.Add($"{kategorie.ToString().ToLower()}_status < 3"); else conditions.Add($"{kategorie.ToString().ToLower()}_status < 2"); } // Status-Filter if (statusFilter.HasValue) { if (minStatusFilter.HasValue) { conditions.Add("status < @status AND status >= @min_status"); parameters.Add(new NpgsqlParameter("@status", (int)statusFilter.Value)); parameters.Add(new NpgsqlParameter("@min_status", (int)minStatusFilter.Value)); } else { if (datum.HasValue) { if (kategorie.HasValue) { conditions.Add("(status = @status OR status = @status2"); parameters.Add(new NpgsqlParameter("@status", (int)statusFilter.Value)); parameters.Add(new NpgsqlParameter("@status2", (int)AuftragStatus.Herrichten)); } else { conditions.Add("status = @status OR status = @status2"); parameters.Add(new NpgsqlParameter("@status", (int)statusFilter.Value)); parameters.Add(new NpgsqlParameter("@status2", (int)AuftragStatus.Herrichten)); } } else { conditions.Add("status = @status"); parameters.Add(new NpgsqlParameter("@status", (int)statusFilter.Value)); } } } // Typ-Filter if (typFilter.HasValue) { if (minTypFilter.HasValue) { conditions.Add("typ < @typ AND typ >= @min_typ"); parameters.Add(new NpgsqlParameter("@typ", (int)typFilter.Value)); parameters.Add(new NpgsqlParameter("@min_typ", (int)minTypFilter.Value)); } else { conditions.Add("typ = @typ"); parameters.Add(new NpgsqlParameter("@typ", (int)typFilter.Value)); } } else { if (minTypFilter.HasValue) { conditions.Add("typ >= @typ"); parameters.Add(new NpgsqlParameter("@typ", (int)minTypFilter.Value)); } } // Datum-Filter if (datum.HasValue) { if (kategorie.HasValue) { conditions.Add($"liefertag <= @liefertag)"); parameters.Add(new NpgsqlParameter("@liefertag", datum.Value)); } else { conditions.Add($"liefertag <= @liefertag"); parameters.Add(new NpgsqlParameter("@liefertag", datum.Value)); } } if (conditions.Count > 0) command.CommandText += " AND " + string.Join(" AND ", conditions); command.CommandText += " ORDER BY liefertag ASC"; command.Parameters.AddRange(parameters.ToArray()); NpgsqlDataReader reader = await command.ExecuteReaderAsync(); try { while (await reader.ReadAsync()) { resultList.Add(new View_Auftrag_Expedit { AuftragID = SafeInt(reader, "auftrag_id"), BenutzerID = SafeInt(reader, "benutzer_id"), AufgabeID = SafeInt(reader, "aufgabe_id"), KundeID = SafeInt(reader, "kunde_id"), Zusatz = SafeString(reader, "zusatz"), Liefertag = SafeDateTime(reader, "liefertag"), Status = (AuftragStatus)SafeInt(reader, "status"), TourID = SafeIntNullable(reader, "tour_id"), ContainerDirt = SafeInt(reader, "container_dirt"), ContainerClean = SafeInt(reader, "container_clean"), Typ = (AuftragTyp)SafeInt(reader, "typ"), AufgabeErledigt = SafeBool(reader, "aufgabe_erledigt"), AbteilungenStatus = (AbteilungsStatus)SafeInt(reader, "abteilungen_status"), Rhythmus = (RegRhythmen)SafeInt(reader, "rhythmus"), Priority = (Priority)SafeInt(reader, "priority"), Gedruckt = SafeDateTime(reader, "gedruckt"), AufgabeBezeichnung = SafeString(reader, "aufgabe_bez"), KundeName = SafeString(reader, "suchtext"), Tour = SafeString(reader, "tour"), FrotteeStatus = SafeInt(reader, "frottee_status"), KleinteileStatus = SafeInt(reader, "kleinteile_status"), GrossteileStatus = SafeInt(reader, "grossteile_status") }); } } finally { reader.Dispose(); } } finally { command.Dispose(); } } finally { connection.Dispose(); } return resultList; } // Auftrag-Felder (ACOLUMNS) [OLVIgnore]public int AuftragID { get; set; } [OLVIgnore]public int BenutzerID { get; set; } [OLVIgnore]public int? AufgabeID { get; set; } [OLVIgnore]public int KundeID { get; set; } [OLVIgnore]public int? TourID { get; set; } [OLVIgnore]public bool AufgabeErledigt { get; set; } [OLVIgnore]public AbteilungsStatus AbteilungenStatus { get; set; } [OLVIgnore]public RegRhythmen Rhythmus { get; set; } [OLVIgnore]private DateTime? Gedruckt { get; set; } [OLVIgnore]public string Zusatz { get; set; } [OLVColumn("Liefertag", AspectToStringFormat = "{0:ddd dd.MM}", DisplayIndex = 10, IsEditable = false)]public DateTime? Liefertag { get; set; } [OLVColumn("Status", DisplayIndex = 40, IsEditable = false)]public AuftragStatus Status { get; set; } //DONE: STATUS NICHT EDITIERBAR! [OLVColumn("Schmutzig", DisplayIndex = 20, TextAlign = HorizontalAlignment.Center, IsEditable = false)]public int ContainerDirt { get; set; } [OLVColumn("Sauber", DisplayIndex = 30, TextAlign = HorizontalAlignment.Center, IsEditable = false)]public int ContainerClean { get; set; } [OLVColumn("Typ", DisplayIndex = 50, IsEditable = false)]public AuftragTyp Typ { get; set; } [OLVColumn("Priority", DisplayIndex = 15, IsEditable = false)]public Priority Priority { get; set; } // Join-Felder aus Table kunde & benutzer [OLVColumn("Aufgabe", DisplayIndex = 55, IsEditable = false)]public string AufgabeBezeichnung { get; set; } [OLVColumn("Kunde", DisplayIndex = 0, IsEditable = false)]public string KundeName { get; set; } [OLVColumn("Tour", DisplayIndex = 70, IsEditable = false)]public string Tour { get; set; } // **3 Status-Spalten statt 12 Flags** [OLVIgnore]public int FrotteeStatus { get; set; } [OLVIgnore]public int KleinteileStatus { get; set; } [OLVIgnore]public int GrossteileStatus { get; set; } // **Ein zentrales Dictionary für alle AbteilungStatus-Anzeigen** private static readonly Dictionary StatusAnzeigen = new Dictionary { [0] = "☒", [1] = "☐", [2] = "☑", [3] = string.Empty, }; // **String Anzeigen von Properties** [OLVColumn("FR", DisplayIndex = 60, TextAlign = HorizontalAlignment.Center, IsEditable = false)]public string FrotteeAnzeige { get { return StatusAnzeigen.TryGetValue(FrotteeStatus, out string text) ? text : "?"; } } [OLVColumn("KT", DisplayIndex = 61, TextAlign = HorizontalAlignment.Center, IsEditable = false)]public string KleinteileAnzeige { get { return StatusAnzeigen.TryGetValue(KleinteileStatus, out string text) ? text : "?"; } } [OLVColumn("GT", DisplayIndex = 62, TextAlign = HorizontalAlignment.Center, IsEditable = false)]public string GrossteileAnzeige { get { return StatusAnzeigen.TryGetValue(GrossteileStatus, out string text) ? text : "?"; } } //[OLVColumn("Etikett", DisplayIndex = 80, TextAlign = HorizontalAlignment.Center)]public string DruckenAnzeige //{ // get // { // // Wenn NICHT gedruckt (null oder MinValue) → Druck-Symbol // if (!Gedruckt.HasValue) // return "🖨"; // // Gedruckt → Datum oder leer // return string.Empty; // } //} [OLVColumn("Abschließen", DisplayIndex = 90, TextAlign = HorizontalAlignment.Center)]public string AbschliessenAnzeige { get { // Wenn NICHT gedruckt (null oder MinValue) → Druck-Symbol if (Gedruckt.HasValue) return "✅"; if (FrotteeStatus < 2) return "✅"; // Gedruckt → Datum oder leer return string.Empty; } } private static int SafeInt(NpgsqlDataReader reader, string columnName) { int ordinal; try { ordinal = reader.GetOrdinal(columnName); } catch { return 0; } // Spalte existiert nicht return reader.IsDBNull(ordinal) ? 0 : reader.GetInt32(ordinal); } private static int? SafeIntNullable(NpgsqlDataReader reader, string columnName) { int ordinal; try { ordinal = reader.GetOrdinal(columnName); } catch { return null; } return reader.IsDBNull(ordinal) ? (int?)null : reader.GetInt32(ordinal); } private static string SafeString(NpgsqlDataReader reader, string columnName) { int ordinal; string name; try { ordinal = reader.GetOrdinal(columnName); } catch { return null; } switch (columnName) { case var t when t == "suchtext": { if (reader.IsDBNull(ordinal)) { ordinal = reader.GetOrdinal("kunde_name"); } name = reader.IsDBNull(ordinal) ? null : reader.GetString(ordinal); if (name == "BAR DIVERSE") { ordinal = reader.GetOrdinal("zusatz"); string zusatz = reader.IsDBNull(ordinal) ? string.Empty : reader.GetString(ordinal); if (zusatz.Contains(";Kunde:")) { string text = ";Kunde: "; int index = zusatz.LastIndexOf(text) + text.Length; int lastindex = zusatz.IndexOf(';', index); name = zusatz.Substring(index, lastindex < 0 ? zusatz.Length - index : lastindex).Trim(); } } } break; case var t when t == "fahrer": { name = reader.IsDBNull(ordinal) ? null : reader.GetString(ordinal); name += reader.IsDBNull(ordinal + 1) ? string.Empty : " (" + reader.GetString(ordinal + 1) + ")"; } break; default: name = reader.IsDBNull(ordinal) ? null : reader.GetString(ordinal); break; } return name; } private static bool SafeBool(NpgsqlDataReader reader, string columnName) { int ordinal; try { ordinal = reader.GetOrdinal(columnName); } catch { return false; } return !reader.IsDBNull(ordinal) && reader.GetBoolean(ordinal); } private static DateTime? SafeDateTime(NpgsqlDataReader reader, string columnName) { int ordinal; try { ordinal = reader.GetOrdinal(columnName); } catch { return null; // Spalte existiert nicht } if (reader.IsDBNull(ordinal)) return null; else return reader.GetDateTime(ordinal); } } }