481 lines
19 KiB
C#
481 lines
19 KiB
C#
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
|
|
{
|
|
}
|
|
/// <summary>
|
|
/// OLV-Model für Nachwäscheliste. Zeigt Kunden des in der ComboBox gewählten Artikels.
|
|
/// </summary>
|
|
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; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// OLV-Model für Nachwäscheliste. Zeigt Alle "Miete (ArtNr. Start mit 6)"-Artikel und ermöglicht das erfassen von Müll und Sauber.
|
|
/// </summary>
|
|
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; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// KundenDaten für die Tourenplanung. Notwendig damit die UserControls geladen werden können.
|
|
/// </summary>
|
|
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<AuftragInfo> LadeInfos(Auftrag auftrag)
|
|
{
|
|
string _connectionString = ConfigurationManager.AppSettings["ConnectionString"];
|
|
var result = new List<AuftragInfo>();
|
|
|
|
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; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// DB-View für Nachwäsche, NW2Müll und NW2Sauber Statistik. Tageseinträge von nw_artikel werden addiert/subtrahiert.
|
|
/// </summary>
|
|
public class View_Artikel_Nachwaesche
|
|
{
|
|
public static List<View_Artikel_Nachwaesche> LadeNachwaesche()
|
|
{
|
|
string _connectionString = ConfigurationManager.AppSettings["ConnectionString"];
|
|
var result = new List<View_Artikel_Nachwaesche>();
|
|
|
|
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; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// DB-View für Expedit. Sollte schneller bearbeitet werden können. Filtern ist einfacher.
|
|
/// </summary>
|
|
public class View_Auftrag_Expedit
|
|
{
|
|
/// <summary>
|
|
/// Holt die Aufträge aus der DB-View.
|
|
/// </summary>
|
|
/// <param name="statusFilter">Kleiner als Status</param>
|
|
/// <param name="minStatusFilter">Größer/Gleich Status</param>
|
|
/// <param name="typFilter">Kleiner als Typ</param>
|
|
/// <param name="minTypFilter">Größer/Gleich Typ</param>
|
|
/// <param name="frottee">true wenn Frottee-Expedit</param>
|
|
/// <param name="datum">null wenn kein Max. Datum</param>
|
|
/// <param name="conn"></param>
|
|
/// <returns></returns>
|
|
public static async Task<List<View_Auftrag_Expedit>> 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<View_Auftrag_Expedit>();
|
|
|
|
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<string>();
|
|
var parameters = new List<NpgsqlParameter>();
|
|
|
|
// 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<int, string> StatusAnzeigen = new Dictionary<int, string>
|
|
{
|
|
[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);
|
|
}
|
|
}
|
|
|
|
}
|