395 lines
14 KiB
C#
395 lines
14 KiB
C#
using DatenDB;
|
||
using Deckungsbeitrag.AA_Forms;
|
||
using Deckungsbeitrag.AA_Klassen;
|
||
using Microsoft.VisualBasic;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Globalization;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using static System.Net.WebRequestMethods;
|
||
|
||
namespace Deckungsbeitrag.UserControls
|
||
{
|
||
public partial class UCTabPageLKW : UserControl
|
||
{
|
||
public UCTabPageLKW()
|
||
{
|
||
InitializeComponent();
|
||
}
|
||
private void FlowLayout_DragEnter(object sender, DragEventArgs e)
|
||
{
|
||
// Unterscheiden zwischen Clone und Move KundenControl
|
||
// Wenn KundenControl innerhalb eines Tages bewegt wird ist Move
|
||
// sonst ist Clone.
|
||
if (e.Data.GetDataPresent("KundeData")) // Custom Format
|
||
e.Effect = DragDropEffects.Copy;
|
||
if (e.Data.GetDataPresent(typeof(KundenControl)))
|
||
e.Effect = DragDropEffects.Move;
|
||
}
|
||
|
||
private void FlowLayout_DragOver(object sender, DragEventArgs e)
|
||
{
|
||
// Unterscheiden zwischen Clone und Move KundenControl
|
||
// Wenn KundenControl innerhalb eines Tages bewegt wird ist Move
|
||
// sonst ist Clone.
|
||
if (e.Data.GetDataPresent("KundeData")) // Custom Format
|
||
e.Effect = DragDropEffects.Copy;
|
||
if (e.Data.GetDataPresent(typeof(KundenControl)))
|
||
e.Effect = DragDropEffects.Move;
|
||
}
|
||
|
||
private void FlowLayout_DragDrop(object sender, DragEventArgs e)
|
||
{
|
||
bool toClone = true;
|
||
string saison = string.Empty;
|
||
int saisonrhythmus = 0;
|
||
FlowLayoutPanel dropTarget = sender as FlowLayoutPanel;
|
||
|
||
DayOfWeek dropDay = DayOfWeek.Sunday;
|
||
switch (dropTarget.Tag.ToString())
|
||
{
|
||
case "MO":
|
||
dropDay = DayOfWeek.Monday; break;
|
||
case "DI":
|
||
dropDay = DayOfWeek.Tuesday; break;
|
||
case "MI":
|
||
dropDay = DayOfWeek.Wednesday; break;
|
||
case "DO":
|
||
dropDay = DayOfWeek.Thursday; break;
|
||
case "FR":
|
||
dropDay = DayOfWeek.Friday; break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
FormTourenplanung tourenplanung = (FormTourenplanung)this.ParentForm;
|
||
foreach (RadioButton rb in tourenplanung.Controls.OfType<RadioButton>()) if (rb.Checked) saison = rb.Text;
|
||
|
||
if (e.Data.GetDataPresent("KundeData"))
|
||
{
|
||
KundenControl kundectr = e.Data.GetData("KundeData") as KundenControl;
|
||
Kunde kunde = (Kunde)kundectr.Tag;
|
||
if (saison == "Sommer") saisonrhythmus = kunde.SommerLieferRhythmus;
|
||
else saisonrhythmus = kunde.WinterLieferRhythmus;
|
||
if (kundectr != null)
|
||
{
|
||
|
||
Liefertage neuerRhythmus = GetKompatiblenRhythmus(dropDay, (Liefertage)saisonrhythmus);
|
||
if (neuerRhythmus != (Liefertage)saisonrhythmus)
|
||
{
|
||
Meldungen meldung = new Meldungen();
|
||
if (meldung.GetFrage(null, $"Rhythmus von {Lieferrhythmen.GetAnzeigeText((Liefertage)saisonrhythmus)} auf {Lieferrhythmen.GetAnzeigeText((Liefertage)neuerRhythmus)} ändern?", false) == DialogResult.No) return;
|
||
else
|
||
{
|
||
if (saison == "Sommer") kunde.SommerLieferRhythmus = (int)neuerRhythmus;
|
||
else kunde.WinterLieferRhythmus = (int)neuerRhythmus;
|
||
kunde.Save();
|
||
kundectr.Tag = kunde;
|
||
FormTourenplanung.KundenControlToDelete(tourenplanung, kundectr);
|
||
}
|
||
}
|
||
|
||
// Überprüfung ob KundenControl geclont werden kann
|
||
if (neuerRhythmus == Lieferrhythmen.Unbekannt || !FormTourenplanung.KundenControlToClone(tourenplanung, kundectr)) toClone = false;
|
||
|
||
if (toClone)
|
||
{
|
||
// Kunde klonen (nicht original bewegen)
|
||
KundenControl kundeKopie = (KundenControl)kundectr.Clone();
|
||
kundeKopie.Tag = kundectr.Tag;
|
||
kundeKopie.Parent = dropTarget;
|
||
dropTarget.Controls.Add(kundeKopie);
|
||
}
|
||
}
|
||
GetGesamtContainer(dropTarget);
|
||
}
|
||
|
||
// Move statt Clone KundenControl
|
||
if (e.Data.GetDataPresent(typeof(KundenControl)))
|
||
{
|
||
KundenControl draggedControl = e.Data.GetData(typeof(KundenControl)) as KundenControl;
|
||
|
||
if (draggedControl == null || dropTarget == null || draggedControl.Parent.Tag != dropTarget.Tag) return;
|
||
|
||
dropTarget.SuspendLayout();
|
||
try
|
||
{
|
||
// Drop-Position berechnen
|
||
Point dropPoint = dropTarget.PointToClient(new Point(e.X, e.Y));
|
||
int dropIndex = GetDropIndex(dropTarget, dropPoint);
|
||
|
||
// Reihenfolge ändern
|
||
dropTarget.Controls.SetChildIndex(draggedControl, dropIndex);
|
||
|
||
// Gesamt-Labels aktualisieren
|
||
GetGesamtContainer(dropTarget);
|
||
}
|
||
finally
|
||
{
|
||
dropTarget.ResumeLayout(true);
|
||
}
|
||
}
|
||
}
|
||
|
||
private int GetDropIndex(FlowLayoutPanel flp, Point dropPoint)
|
||
{
|
||
for (int i = 0; i < flp.Controls.Count; i++)
|
||
{
|
||
if (flp.Controls[i].Bounds.Contains(dropPoint))
|
||
return i;
|
||
}
|
||
return flp.Controls.Count; // Am Ende anhängen
|
||
}
|
||
|
||
private void GetGesamtContainer(FlowLayoutPanel dropTarget)
|
||
{
|
||
int[] gesamt = { 0, 0, 0 };
|
||
|
||
foreach (KundenControl kndctrl in dropTarget.Controls.OfType<KundenControl>())
|
||
{
|
||
for (int i = 0; i < Math.Min(kndctrl.ContAnzahl.Length, gesamt.Length); i++)
|
||
{
|
||
gesamt[i] += kndctrl.ContAnzahl[i];
|
||
}
|
||
}
|
||
foreach (Label ctr in tableLayoutPanelTage.Controls.OfType<Label>())
|
||
{
|
||
if (tableLayoutPanelTage.GetRow(ctr) == 2) // Zeile 3 (Index 2)
|
||
{
|
||
if (ctr.Tag.ToString() == dropTarget.Tag.ToString())
|
||
{
|
||
// ctr.Text aktualisieren
|
||
ctr.Text = $"{gesamt[0]}/{gesamt[1]}/{gesamt[2]}";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Wenn KundeControl gedropped wird, wird der Lieferrhythmus kontrolliert.
|
||
/// Stimmt Drop-Tag mit Liefertagen überein wenn NICHT kann Lieferrhythmus angepasst werden.
|
||
/// </summary>
|
||
/// <param name="dropDay"></param>
|
||
/// <param name="originalRhythmus"></param>
|
||
/// <returns>Liefertage von Lieferrhythmen</returns>
|
||
private static Liefertage GetKompatiblenRhythmus(DayOfWeek dropDay, Liefertage originalRhythmus)
|
||
{
|
||
Meldungen meldung = new Meldungen();
|
||
CancelEventArgs e = new CancelEventArgs();
|
||
string dropTag = CultureInfo.GetCultureInfo("de-DE").DateTimeFormat.GetDayName(dropDay);
|
||
|
||
// 1. Ist dropDay im Original enthalten? Wird originalRhythums zurück gegeben.
|
||
if (IstTagEnthalten(originalRhythmus, dropDay))
|
||
return originalRhythmus;
|
||
|
||
// 2. Anzahl Liefertag pro Woche von hinterlegtem Rhythmus finden
|
||
int originalAnzahl = Lieferrhythmen.GetMaxClonesNet48(originalRhythmus);
|
||
|
||
// 3. Fragen ob der Lieferrhythmus geändert werden soll.
|
||
// Wenn NEIN wird Lieferage.None zurückgegeben.
|
||
// Sonst wird Anzahl der gewünschten Lieferungen pro Woche abgefragt,
|
||
if (meldung.GetFrage(null, $"Der gewählte Liefertag {dropTag} passt nicht zum Lieferrhythmus: {originalRhythmus.GetAnzeigeText()}\n\nSoll der **Lieferrhythmus geändert** werden?", false) == DialogResult.Yes)
|
||
{
|
||
string input = Interaction.InputBox("Wie oft soll der Kunde pro Woche angefahren werden?\n\nAnzahl Lieferungen:", "Lieferungen pro Woche", originalAnzahl.ToString());
|
||
|
||
// Kontrolle ob Input ist eine Zahl.
|
||
// Bei Abbruch wird KEIN Lieferrhythmus zurück gegeben.
|
||
if (!string.IsNullOrWhiteSpace(input))
|
||
{
|
||
while (!int.TryParse(input, out int zahl) || zahl < 1)
|
||
{
|
||
MessageBox.Show("Bitte nur positive Ganzzahlen eingeben!", "Ungültig");
|
||
input = Interaction.InputBox("Wie oft soll der Kunde pro Woche angefahren werden?\n\nAnzahl Lieferungen:", "Lieferungen pro Woche", originalAnzahl.ToString());
|
||
if (string.IsNullOrWhiteSpace(input)) return Lieferrhythmen.Unbekannt;
|
||
}
|
||
}
|
||
else return Lieferrhythmen.Unbekannt;
|
||
|
||
// Wenn Input korrekt abgeschlossen, wird original Anzahl geändert.
|
||
originalAnzahl = int.Parse(input);
|
||
|
||
// Lieferrhythmus mit übereinstimmenden Liefertag und Liefertaganzahl wird gewählt und zurück gegeben.
|
||
switch (originalAnzahl)
|
||
{
|
||
case 1:
|
||
switch (dropDay)
|
||
{
|
||
case DayOfWeek.Monday: return Lieferrhythmen.WoechentlichMo;
|
||
case DayOfWeek.Tuesday: return Lieferrhythmen.WoechentlichDi;
|
||
case DayOfWeek.Wednesday: return Lieferrhythmen.WoechentlichMi;
|
||
case DayOfWeek.Thursday: return Lieferrhythmen.WoechentlichDo;
|
||
case DayOfWeek.Friday: return Lieferrhythmen.WoechentlichFr;
|
||
default: return Lieferrhythmen.WoechentlichMi;
|
||
}
|
||
case 2:
|
||
switch (dropDay)
|
||
{
|
||
case DayOfWeek.Monday: return Lieferrhythmen.ZweimalMoDo;
|
||
case DayOfWeek.Thursday: return Lieferrhythmen.ZweimalMoDo;
|
||
case DayOfWeek.Tuesday: return Lieferrhythmen.ZweimalDiFr;
|
||
case DayOfWeek.Friday: return Lieferrhythmen.ZweimalDiFr;
|
||
default:
|
||
return Lieferrhythmen.ZweimalMoDo;
|
||
}
|
||
case 3:
|
||
return Lieferrhythmen.DreimalMoMiFr;
|
||
case 4:
|
||
return Lieferrhythmen.ViermalMoDiDoFr;
|
||
case 5:
|
||
return Lieferrhythmen.TaeglichMoFr;
|
||
default:
|
||
return Lieferrhythmen.WoechentlichMo;
|
||
}
|
||
}
|
||
else return Lieferrhythmen.Unbekannt;
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// Überprüfung ob Liefertag in hinterlegtem Lieferrhythmus enthalten ist.
|
||
/// </summary>
|
||
/// <param name="rhythmus"></param>
|
||
/// <param name="tag"></param>
|
||
/// <returns>Wenn enthalten return true</returns>
|
||
public static bool IstTagEnthalten(Liefertage rhythmus, DayOfWeek tag)
|
||
{
|
||
Liefertage tagFlag;
|
||
switch (tag)
|
||
{
|
||
case DayOfWeek.Monday:
|
||
tagFlag = Liefertage.Monday;
|
||
break;
|
||
case DayOfWeek.Tuesday:
|
||
tagFlag = Liefertage.Tuesday;
|
||
break;
|
||
case DayOfWeek.Wednesday:
|
||
tagFlag = Liefertage.Wednesday;
|
||
break;
|
||
case DayOfWeek.Thursday:
|
||
tagFlag = Liefertage.Thursday;
|
||
break;
|
||
case DayOfWeek.Friday:
|
||
tagFlag = Liefertage.Friday;
|
||
break;
|
||
default:
|
||
tagFlag = Liefertage.None;
|
||
break;
|
||
}
|
||
|
||
return (rhythmus & tagFlag) == tagFlag;
|
||
}
|
||
|
||
// ★ SPEICHERN – nutzt TAG der FlowLayoutPanels ★
|
||
public TourenDaten SpeichereDaten()
|
||
{
|
||
var data = new TourenDaten
|
||
{
|
||
FahrzeugName = this.Parent?.Text ?? "Unbekannt",
|
||
KundenProTag = new List<KundeData>()
|
||
};
|
||
|
||
// Alle FlowLayoutPanels durchgehen
|
||
foreach (Control ctrl in tableLayoutPanelTage.Controls)
|
||
{
|
||
if (ctrl is FlowLayoutPanel flp && flp.Tag is string tag) // ← TAG!
|
||
{
|
||
// Kunden sammeln
|
||
foreach (Control kundeCtrl in flp.Controls)
|
||
{
|
||
if (kundeCtrl is KundenControl kc)
|
||
{
|
||
data.KundenProTag.Add(new KundeData
|
||
{
|
||
Name = kc.KundenName,
|
||
Region = kc.KundenRegion,
|
||
Tag = tag, // ← Wochentag mit speichern!
|
||
KundeID = (int)((Kunde)kundeCtrl.Tag).KundeID,
|
||
ContAnzahl = kc.ContAnzahl
|
||
});
|
||
}
|
||
}
|
||
|
||
// Counter finden (labelContMO -> MO, etc.)
|
||
if (data.Counter.TryGetValue(tag, out int[] counts))
|
||
{
|
||
// Bestehende Werte laden
|
||
string baseName = $"labelCont{tag}";
|
||
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
string lblName = $"{baseName}{i}"; // labelContMO0, labelContMO1, labelContMO2
|
||
var lbl = tableLayoutPanelTage.Controls.Find(lblName, true).FirstOrDefault() as Label;
|
||
|
||
if (lbl != null && int.TryParse(lbl.Text, out int value))
|
||
{
|
||
counts[i] = value;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
// ★ LADEN – TAG der FlowLayoutPanels nutzen ★
|
||
public void LadeDaten(TourenDaten data)
|
||
{
|
||
// Zuerst alle FlowLayoutPanels leeren
|
||
foreach (Control ctrl in tableLayoutPanelTage.Controls)
|
||
{
|
||
if (ctrl is FlowLayoutPanel flp)
|
||
flp.Controls.Clear();
|
||
}
|
||
|
||
// Kunden nach TAG verteilen
|
||
var kundenGruppiert = data.KundenProTag.GroupBy(k => k.Tag);
|
||
|
||
foreach (var gruppe in kundenGruppiert)
|
||
{
|
||
string tag = gruppe.Key;
|
||
FlowLayoutPanel zielFlp = tableLayoutPanelTage.Controls
|
||
.OfType<FlowLayoutPanel>()
|
||
.FirstOrDefault(flp => flp.Tag?.ToString() == tag);
|
||
|
||
if (zielFlp != null)
|
||
{
|
||
foreach (var kundeData in gruppe)
|
||
{
|
||
Kunde kunde = Kunde.GetKunde(null, kundeData.KundeID, null);
|
||
KundenControl kundectrl = new KundenControl(kunde);
|
||
kundectrl.Tag = kunde;
|
||
zielFlp.Controls.Add(kundectrl);
|
||
}
|
||
}
|
||
|
||
// Counter setzen
|
||
if (data.Counter.TryGetValue(tag, out int[] counts))
|
||
{
|
||
string counterName = $"labelCont{tag}";
|
||
var counterLabel = tableLayoutPanelTage.Controls
|
||
.Find(counterName, true)
|
||
.FirstOrDefault() as Label;
|
||
if (counterLabel != null)
|
||
{
|
||
// Beispiel: nur ersten Wert anzeigen
|
||
counterLabel.Text = $"{counts[0]}/{counts[1]}/{counts[2]}";
|
||
|
||
// oder alle drei, z.B. "max / avg / min"
|
||
// counterLabel.Text = $"{counts[0]} / {counts[1]} / {counts[2]}";
|
||
}
|
||
}
|
||
|
||
GetGesamtContainer(zielFlp);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//CHANGES: Innerhalb eines Tages kann die Reihenfolge angepasst werden.
|
||
//CHANGES: Wenn der Lieferrhythmus geändert wird, werden KundenControls an falschen Tagen gelöscht. |